
Recherche avancée
Autres articles (74)
-
Websites made with MediaSPIP
2 mai 2011, parThis page lists some websites based on MediaSPIP.
-
Creating farms of unique websites
13 avril 2011, parMediaSPIP platforms can be installed as a farm, with a single "core" hosted on a dedicated server and used by multiple websites.
This allows (among other things) : implementation costs to be shared between several different projects / individuals rapid deployment of multiple unique sites creation of groups of like-minded sites, making it possible to browse media in a more controlled and selective environment than the major "open" (...) -
Ecrire une actualité
21 juin 2013, parPrésentez les changements dans votre MédiaSPIP ou les actualités de vos projets sur votre MédiaSPIP grâce à la rubrique actualités.
Dans le thème par défaut spipeo de MédiaSPIP, les actualités sont affichées en bas de la page principale sous les éditoriaux.
Vous pouvez personnaliser le formulaire de création d’une actualité.
Formulaire de création d’une actualité Dans le cas d’un document de type actualité, les champs proposés par défaut sont : Date de publication ( personnaliser la date de publication ) (...)
Sur d’autres sites (16699)
-
How to convert a javascript animation to video on the server-side using nodejs ?
13 mai 2019, par user9964622I have a app where a user can create animations , I want to be able to convert these animations to video on server side, so user can save and share them eg YouTube, etc
Here is what I have so far , animation created using create js and ffmpegserver.js.
ffmpegserver.js.
This is a simple node server and library that sends canvas frames to the server and uses FFmpeg to compress the video. It can be used standalone or with CCapture.js
Test3.html
<code class="echappe-js"><body onload="init();">Simple Tween Demo
<script src="http://localhost:8081/ffmpegserver/CCapture.js"></script>
<script src="http://localhost:8081/ffmpegserver/ffmpegserver.js"></script>
<script src="https://code.createjs.com/1.0.0/createjs.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/17.2.0/Tween.js"></script>
<script src='http://stackoverflow.com/feeds/tag/test3.js'></script>
Test3.js
/* eslint-disable eol-last */
/* eslint-disable no-undef */
/* eslint-disable quotes */
var canvas, stage;
function init() {
var framesPerSecond = 60;
var numFrames = framesPerSecond * 5; // a 5 second 60fps video
var frameNum = 0;
var progressElem = document.getElementById("progress");
var progressNode = document.createTextNode("");
progressElem.appendChild(progressNode);
function onProgress(progress) {
progressNode.nodeValue = (progress * 100).toFixed(1) + "%";
}
function showVideoLink(url, size) {
size = size ? (" [size: " + (size / 1024 / 1024).toFixed(1) + "meg]") : " [unknown size]";
var a = document.createElement("a");
a.href = url;
var filename = url;
var slashNdx = filename.lastIndexOf("/");
if (slashNdx >= 0) {
filename = filename.substr(slashNdx + 1);
}
a.download = filename;
a.appendChild(document.createTextNode("Download"));
var container = document.getElementById("container").insertBefore(a, progressElem);
}
var capturer = new CCapture( {
format: 'ffmpegserver',
//workersPath: "3rdparty/",
//format: 'gif',
//verbose: true,
framerate: framesPerSecond,
onProgress: onProgress,
//extension: ".mp4",
//codec: "libx264",
} );
capturer.start();
canvas = document.getElementById("testCanvas");
stage = new createjs.Stage(canvas);
var ball = new createjs.Shape();
ball.graphics.setStrokeStyle(5, 'round', 'round');
// eslint-disable-next-line quotes
ball.graphics.beginStroke('#000000');
ball.graphics.beginFill("#FF0000").drawCircle(0, 0, 50);
ball.graphics.setStrokeStyle(1, 'round', 'round');
ball.graphics.beginStroke('#000000');
ball.graphics.moveTo(0, 0);
ball.graphics.lineTo(0, 50);
ball.graphics.endStroke();
ball.x = 200;
ball.y = -50;
createjs.Tween.get(ball, {loop: -1})
.to({x: ball.x, y: canvas.height - 55, rotation: -360}, 1500, createjs.Ease.bounceOut)
.wait(1000)
.to({x: canvas.width - 55, rotation: 360}, 2500, createjs.Ease.bounceOut)
.wait(1000)
.to({scaleX: 2, scaleY: 2}, 2500, createjs.Ease.quadOut)
.wait(1000)
stage.addChild(ball);
createjs.Ticker.addEventListener("tick", stage);
function render() {
requestAnimationFrame(render);
capturer.capture( canvas );
++frameNum;
if (frameNum < numFrames) {
progressNode.nodeValue = "rendered frame# " + frameNum + " of " + numFrames;
} else if (frameNum === numFrames) {
capturer.stop();
capturer.save(showVideoLink);
}
}
render();
}Everything works fine, you can test it yourself if you want by cloning the repo.
Right now animation rendering happens in client side, I would like this animation rendering to happen in the backend side
What do I need to change to make this animation rendering in backend server side using Nodejs ? any help or suggestions will be appreciated.
-
Displaying gif VideoClips on a half circle path with moviepy
25 juin 2022, par stooicrealismI am trying to compose a collection of about 6 to 7 gif aniated clips on top of a base video. These animated icons are shown on along a half circle at the center of the video. I am figuring out the best way to write this logic, but stuck at this for a while. Any help is much appreciated.


positions = [
 [(200,200)], 
 [(200,300)],
 [(200,400)],
 [(200,500)],
 [(200,600)],
 [(200,700)],
 [(200,800)],
 [(200,900)],
 [(200,1000)]
 
 ]
 
clip = (VideoFileClip(f"{DIRECTORY+wd}.gif")
 .set_start(0)
 .set_duration(video_clip.duration)
 .set_position(positions[l]))
clips.append(clip)

 
final_clip = concatenate_videoclips([clips[i] for i in range(len(clips))])



-
Evolution #3361 : Tri par défaut des entrées des menus du bandeau de l’espace privé
6 décembre 2014, par tcharlss (*´_ゝ`)Voilà ma petite proposition de patch et mes explications (un peu verbeuses, mais ça m’aide à retenir).
Dans http://core.spip.org/projects/spip/repository/entry/spip/prive/squelettes/inclure/barre-nav.html#L46, c’est la boucle
, ligne 46, qui affiche les entrées.
Tel quel, on ne peut pas faire de tri au moyen de{par xxx}
, car la chaîne de langue n’est pas contenue dans#VALEUR{menu}
, juste le nom de l’entrée i18n associé :array (size=6) ’auteurs’ => object(Bouton)[301] public ’icone’ => string ’’ (length=0) public ’libelle’ => string ’icone_auteurs’ (length=13) public ’url’ => null public ’urlArg’ => null public ’url2’ => null public ’target’ => null public ’sousmenu’ => null ’rubriques’ => ...
(Note : dans la boucle DATA, l’objet « Bouton » est traité comme un tableau associatif).
Pour faire le tri alphabétique, il y a juste 2 points à traiter :- Rajouter la chaîne de langue dans les valeurs. Les premières lettres suffiront pour le tri.
- Faire en sorte que cette paire clé/valeur soit au début du tableau. Anéfé, dans une boucle DATA, quand les
#VALEUR
sont des tableaux associatifs,{par valeur/toto}
ne fonctionne pas. En revanche, on peut faire{par valeur}
tout court et ça va prendre en compte la valeur associée à la première clé du tableau.
Donc concrètement, en ajoutant
'tri' => 'chaine de langue'
au début du tableau de chaque entrée, on peut faire{par valeur}
dans la boucle et le tour est joué.
Je propose 2 patchs, au choix :Patch A¶
Dans le squelette
barre_nav.html
: juste avant la boucle DATA qui affiche les entrées, on fait une boucle qui modifie le tableau qui l’alimente (dans le patch, on fait gaffe au espaces blancs, mais là c’est pour la lisibilité).[(#REM) prépare les données des entrées ] #SETsousmenu,#ARRAY
#SETentree,#ARRAY#CLE,#ARRAY
tri,#VAL#VALEURlibelle|_T|replace’\s+’,’’|substr0,3|strtolower,
icone,#VALEURicone,
libelle,#VALEURlibelle,
url,#VALEURlibelle,url,
urlArg,#VALEURurlArg,
url2,#VALEURurl2,
target,#VALEURtarget,
sousmenu,#VALEURsousmenu
#SETsousmenu,#GETsousmenu|array_merge#GETentree[(#REM) Affiche les entrées ]
- ...
Patch B¶
Dans
boutons.php
, on ajoute$this->tri = strtolower(substr(preg_replace('/\s+/','',_T($libelle)),0,3));
à la classeBouton
et on fait en sorte que ce soit la première donnée renvoyée.
Du coup dans le squelettebarre_nav.html
il suffit de rajouter{par valeur}
.