简体   繁体   English

在后端服务器端使用Node.js进行动画渲染

[英]Animation rendering using Nodejs on backend server side

I have simple animation created using create js and ffmpegserver.js. 我有使用create js和ffmpegserver.js创建的简单动画。

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. 这是一个简单的节点服务器和库,可将画布帧发送到服务器并使用FFmpeg压缩视频。 It can be used standalone or with CCapture.js. 它可以独立使用,也可以与CCapture.js一起使用。

Here is repo: video rendering demo . 这是回购: 视频渲染演示

on folder public, I have demos eg test3.html and test3.js 在公用文件夹上,我有演示,例如test3.html和test3.js

Test3.html Test3.html

<!DOCTYPE html>
<html>
<head>
    <title>TweenJS: Simple Tween Demo</title>
<style>

canvas {
          border: 1px solid #08bf31;
          justify-content: center;
          display: flex;
          align-items: center;
          margin: 0px auto;
          margin-bottom: 40px;
      }

      a {
        width: 150px;
        height: 45px;
        background: red;
        text-align: center;
        display: flex;
        justify-content: center;
        align-items: center;
        border-radius: 300px;
        color: white;
      }
      #container{
        flex-direction: column;
        justify-content: center;
        display: flex;
        align-items: center;
        margin: 0px auto;
      }
    #progress{
        margin: 30px;
    }
    #preview{
        margin: 40px;
        width: 150px;
        height: 45px;
        background: deepskyblue;
        color: white;
        border: none;
        border-radius: 300px;
    }


</style>

</head>
<body onload="init();">

<div>

<div id="container">
        <h1>Simple Tween Demo</h1>
    <canvas id="testCanvas" width="500" height="400"></canvas>
    <div id="progress"></div>
</div>
</div>
<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="test3.js"></script>
</body>
</html>

Test3.js 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? 为了使用Node.js在后端服务器端进行此动画渲染,我需要更改什么? any help or suggestions will be appreciated. 任何帮助或建议,将不胜感激。

Since you do all your animations in the canvas, you can use node-canvas to do the same in Node.js. 由于您在画布中制作了所有动画,因此可以在Node.js中使用节点画布进行相同的操作。 (You have to double check that create.js also work in Node.js, though. If not, find another library or write those routines yourself). (不过,您必须仔细检查create.js是否也可以在Node.js中使用。否则,请找到另一个库或自己编写这些例程)。

Spawn ffmpeg into it's own process accepting input through a pipe ( ffmpeg -i - -f rawvideo -pix_fmt rgba etc. The pipe will probably be different according to which server environment you use). 将ffmpeg生成自己的进程,以通过管道( ffmpeg -i - -f rawvideo -pix_fmt rgba等)接受输入。根据您使用的服务器环境,管道可能会有所不同。 After each frame is drawn, extract the image array using canvas.getContext('2d').getImageData(0, 0, width, height).data and pipe the result to to ffmpeg. 绘制完每一帧后,使用canvas.getContext('2d').getImageData(0, 0, width, height).data提取图像数组canvas.getContext('2d').getImageData(0, 0, width, height).data并将结果通过管道传递到ffmpeg。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM