Html 从 html5 动画创建视频的最佳方式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4618048/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 06:00:33  来源:igfitidea点击:

best way to create video from html5 animation

htmlanimationwebkitscreenshot

提问by Russell Leggett

I wanted to make a short intro for a video podcast. Being a geeky web developer and not already having access to or knowledge of animation tools, I thought I might take a stab at doing the intro using various html5 techniques. The problem is, how do I turn that into a video clip I can easily drop into iMovie?

我想为视频播客做一个简短的介绍。作为一个极客 Web 开发人员并且还没有访问或了解动画工具,我想我可能会尝试使用各种 html5 技术进行介绍。问题是,如何将其转换为可以轻松放入 iMovie 的视频剪辑?

If I have to, I think this can be accomplished if I only use canvas by exporting a png every frame using getImageData. The only drawback is that I'm limited to just canvas. I was hoping to use the whole range of new html5/css3/svg techniques. I don't need this functionality to work for general web use, just for myself, so I'd be happy for anything that requires installation etc. to make it work.

如果必须的话,我认为如果我只通过使用 getImageData 每帧导出一个 png 来使用画布,就可以实现这一点。唯一的缺点是我仅限于画布。我希望使用整个范围的新 html5/css3/svg 技术。我不需要这个功能来为一般的网络使用工作,只是为了我自己,所以我很高兴任何需要安装等才能让它工作的东西。

If I have to, I guess I can probably use a video screen capture tool, but I was hoping for a complete open source chain.

如果必须的话,我想我可能可以使用视频屏幕捕获工具,但我希望有一个完整的开源链。

In the end, I expect I'll be creating a series of pngs and using ffmpeg to put them together, I was just hoping to figure out a great way of doing this in an automated, open source way.

最后,我希望我将创建一系列 png 并使用 ffmpeg 将它们组合在一起,我只是希望找到一种以自动化、开源方式执行此操作的好方法。

UpdateI just wanted to clarify that what I'm basically trying to do is use HTML5 instead of something like flash, but I'm not trying to serve it to other people on the internet, I want to convert it to video, and it never needs to leave my computer, which is actually a mac, not a Linux server. If flash can do it, why not html, right? That seems to be what people are trying to claim. The problem is, I can take a SWF and convert it to standard video, but how do you do that with javascript or CSS3 animations? Obviously a screen capture tool can sort of do the job, but those are usually low frame rate, and can't be run programmatically to my knowledge.

更新我只是想澄清一下,我主要尝试做的是使用 HTML5 而不是 Flash 之类的东西,但我不想将其提供给互联网上的其他人,我想将其转换为视频,并且永远不需要离开我的电脑,它实际上是一台 mac,而不是 Linux 服务器。如果 flash 可以做到,为什么 html 不行,对吧?这似乎是人们试图声称的。问题是,我可以使用 SWF 并将其转换为标准视频,但是您如何使用 javascript 或 CSS3 动画来做到这一点?显然,屏幕捕获工具可以完成这项工作,但这些通常是低帧率,并且无法以我所知的方式以编程方式运行。

The closest sort of thing I can think of that isn't a screenshot tool would be something like webkit2png, only instead of a single png, it would take 60 pngs per second. At some point, I might actually try to implement exactly that, but I wanted to see if anyone else had something good.

我能想到的最接近的东西不是屏幕截图工具,而是类似于 webkit2png 之类的东西,它不是单个 png,而是每秒 60 个 png。在某些时候,我实际上可能会尝试完全实现它,但我想看看其他人是否有好的东西。

ExampleSo I actually just did an intro using the built in iMovie title cards. This is a good exampleof roughly the sort of thing I would like to do. Should actually be fairly straightforward with a little CSS3 animation work. What I have isn't bad, but I would like to use custom graphics, with better font/layout control.

示例所以我实际上只是使用内置的 iMovie 标题卡做了一个介绍。这是一个很好的例子,大致说明了我想做的事情。通过一些 CSS3 动画工作,实际上应该相当简单。我所拥有的还不错,但我想使用具有更好字体/布局控制的自定义图形。

采纳答案by Russell Leggett

So far the best thing I've found so far that won't require me to write c code is using Titanium for desktop. It features a takeScreenshot function available from javascript code. The takeScreenshot function gets a screenshot of the entire desktop, but it should be easy to automate cropping that down. With a plethora of javascript animation libraries out there, I should be able to hack in ways of getting a screenshot at every frame, even if it can't happen in real-time.

到目前为止,我发现的最好的不需要我编写 c 代码的东西是在桌面上使用 Titanium。它具有可从 javascript 代码获得的 takeScreenshot 功能。takeScreenshot 函数获取整个桌面的屏幕截图,但自动裁剪它应该很容易。有了大量的 javascript 动画库,我应该能够在每一帧获取屏幕截图,即使它不能实时发生。

While I won't be able to use CSS animations, this is probably the most flexible solution anyway, given that anything I can do with CSS animations I can do with javascript, and I'll have more control over frame rate, etc.

虽然我无法使用 CSS 动画,但这可能是最灵活的解决方案,因为我可以用 CSS 动画做任何事情,我可以用 javascript 做,并且我可以更好地控制帧速率等。

Additionally, this should allow me to use all things the browser is capable of, combining html/css/js/svg/canvas.

此外,这应该允许我使用浏览器的所有功能,结合 html/css/js/svg/canvas。

回答by karlcow

There is a tutorial with the code using both javascript and PHP to create a video from your canvas animation. The program save frame by frame of your canvas animation like in a movie, and then you can convert this stack of frames to a specific video format with the codec of your choice.

有一个使用 javascript 和 PHP从画布动画创建视频的代码教程。该程序像电影一样逐帧保存画布动画,然后您可以使用您选择的编解码器将此帧堆栈转换为特定的视频格式。

Code from the linked page.

来自链接页面的代码。

(function () {
    var canvas = document.getElementById('c'),
        c = canvas.getContext('2d'),
        w = canvas.width, h = canvas.height,
        p = [], clr, n = 200;

    clr = [ 'red', 'green', 'blue', 'yellow', 'purple' ];

    for (var i = 0; i < n; i++) {
        // generate particle with random initial velocity, radius, and color
        p.push({
            x: w/2,
            y: h/2,
            vx: Math.random()*12-6,
            vy: Math.random()*12-6,
            r: Math.random()*4+3,
            clr: Math.floor(Math.random()*clr.length)
        });
    }

    function frame() {
        // cover the canvas with 50% opacity (creates fading trails)
        c.fillStyle = 'rgba(0,0,0,0.5)';
        c.fillRect(0, 0, w, h);

        for (var i = 0; i < n; i++) {
            // reduce velocity to 99%
            p[i].vx *= 0.99;
            p[i].vy *= 0.99;

            // adjust position by the current velocity
            p[i].x += p[i].vx;
            p[i].y += p[i].vy;

            // detect collisions with the edges
            if (p[i].x < p[i].r || p[i].x > w-p[i].r) {
                // reverse velocity (direction)
                p[i].vx = -p[i].vx;
                // adjust position again (in case it already passed the edge)
                p[i].x += p[i].vx;
            }
            // see above
            if (p[i].y < p[i].r || p[i].y > h-p[i].r) {
                p[i].vy = -p[i].vy;
                p[i].y += p[i].vy;
            }

            // draw the circle at the new postion
            c.fillStyle = clr[p[i].clr]; // set color
            c.beginPath();
            c.arc(p[i].x, p[i].y, p[i].r, 0, Math.PI*2, false);
            c.fill();
        }
    }

    // execute frame() every 30 ms
    setInterval(frame, 30);
}());

回答by Hans

Well Techsmith Snagit captures in AVI, or their premium application camtasia ( generates a Flash video and a web page launcher) would work. Why not simply create a Powerpoint slide of the features you want to touch on and use a HTML set of pages of actual demos you want to illustrate in depth. This is the approach I am taking.

好吧,Techsmith Snagit 捕获 AVI,或者他们的高级应用程序 camtasia(生成 Flash 视频和网页启动器)都可以。为什么不简单地创建您想要触及的功能的 Powerpoint 幻灯片,并使用您想要深入说明的实际演示页面的 HTML 集。这是我正在采取的方法。

回答by rhanb

You are right in my opinion the best way to do it is to create images from the canvas's data and then compile all those images into a video via a module (fluent-ffmpegfor example, which is a node js package). It's pretty easy but be careful of the FPS (frame rate) if you create those images as fast as you can you may change the fps of your video, for example if you use recursively requestAnimationFrame()you will be at 60fps. So, instead of reading a html5 video you should set the time each 1/30s (for example if you want a 30fps video) and create a image from the currentTime until the end of the video. And if you have not only one canvas, if you apply animations on your video via multiple canvas you could create a new empty canvas and draw all canvas's data on it to create only one image instead of one image for each canvas.

您是对的,我认为最好的方法是从画布的数据创建图像,然后通过模块(fluent-ffmpeg例如,它是一个 node js 包)将所有这些图像编译成视频。这很简单,但是如果您尽可能快地创建这些图像,请注意 FPS(帧速率),您可能会更改视频的 fps,例如,如果您递归使用,requestAnimationFrame()您将达到 60fps。因此,不是阅读 html5 视频,您应该每 1/30 秒设置一次时间(例如,如果您想要一个 30fps 的视频)并从 currentTime 到视频结束创建一个图像。如果您不仅有一个画布,如果您通过多个画布在视频上应用动画,您可以创建一个新的空画布并在其上绘制所有画布数据,从而仅创建一张图像,而不是为每个画布创建一张图像。

回答by Sagar Chakravarthy

I had worked on a tool that does something similar to your requirements. It basically uses cutycapt (or any other tool to convert HTML with CSS into image) and takes series of screenshot depending on the frame rate required.

我曾开发过一种工具,它可以满足您的要求。它基本上使用 cutycapt(或任何其他工具将带有 CSS 的 HTML 转换为图像)并根据所需的帧速率拍摄一系列屏幕截图。

For that to work, the animations should be purely CSS animations and the tool interpolates the intermediate frame's CSS properties by parsing the CSS.

为此,动画应该是纯粹的 CSS 动画,并且该工具通过解析 CSS 来插入中间帧的 CSS 属性。

https://github.com/bpsagar/css2video

https://github.com/bpsagar/css2video

I'm not sure if the tool is complete, let me know if you are interested.

我不确定该工具是否完整,如果您有兴趣,请告诉我。