使用HTML5动画创建视频的最佳方法

40
我想为一个视频播客制作一个简短的介绍。作为一个迷恋网站开发的极客,我没有使用或了解动画工具,因此我想用各种HTML5技术尝试做出介绍。问题是,如何将其转换为我可以轻松放入iMovie的视频剪辑?
如果必须这样做,我认为只使用画布并使用getImageData导出每一帧的png图像就可以完成。唯一的缺点是我仅限于使用画布。我希望使用全新的HTML5/CSS3/SVG技术范围。我不需要这个功能在一般网站使用,只是为了自己,所以我乐意为使其工作而安装其他软件。
如果必须这样做,我想我可能可以使用视频屏幕捕获工具,但我希望使用完整的开源链。
最终,我预计将创建一系列PNG文件,并使用FFmpeg将它们组合在一起,我只是希望找到一种自动化、开源的好方法来完成这个任务。
更新:我想澄清的是,我基本上想使用HTML5而不是Flash,但我不想将其提供给其他人在互联网上使用。我想将其转换为视频,它永远不需要离开我的电脑,我的电脑实际上是一台Mac电脑,而不是Linux服务器。如果Flash可以做到这一点,为什么HTML就不能呢?这似乎是人们试图宣称的。问题是,我可以将SWF转换为标准视频,但如何使用JavaScript或CSS3动画进行转换呢?显然,屏幕捕捉工具可以勉强完成此任务,但这些通常是低帧率的,并且据我所知不能以编程方式运行。
我能想到的最接近的东西不是截图工具,而是像webkit2png这样的东西,只是它每秒会生成60个PNG文件。在某个时候,我可能会尝试实现完全一样的效果,但我想看看其他人是否有更好的解决方案。

示例 所以我实际上只是使用内置的 iMovie 标题卡片做了一个简短的介绍。 这是一个很好的例子,大致是我想要做的类型。只需要一点 CSS3 动画处理,实际上应该相当简单。我的现有内容还不错,但我想使用自定义图形,并获得更好的字体/布局控制。

5个回答

11

这里有一个教程,其中包含使用JavaScript和PHP代码 从你的画布动画中创建视频。该程序逐帧保存画布动画,就像电影一样,然后您可以将这些帧转换为您选择的特定视频格式,使用您选择的编解码器。

连接页面中的代码。

(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);
}());

3
我在问题中提到了这个可能性,但我真的想要包括所有选项的内容。例如,它不会捕获CSS3动画或SVG。 - Russell Leggett
然后,如果您想要窗口上下文的图像转储,这可能会更加复杂。 - karlcow
webkit2png 只能拍摄一次。多次使用 webkit2png 捕捉图像不太可能解决问题。我猜可以设置一个循环,在初始渲染和捕捉之间有延迟,但这样做会变得很麻烦,而且图像不会完全同步。我想知道是否可以通过黑客手段让 webkit2png 推出多张图片。 - karlcow
向浏览器实现者询问,似乎安全上下文会禁止它。但我仍在寻找信息。 - karlcow
我非常怀疑我能否在javascript中从实际的股票浏览器内得到任何有效的东西,但是为了不花费数小时去弄清楚,我想知道是否可以像webkit2png一样使某些本机输出达到30fps,或者这在css-transform进行时是不可能的。另一个可能非常有效的方法是将函数注入到浏览器对象模型takeScreenshot()中,在基于javascript的动画期间使用类似停止动画的功能。javascript动画不必实时工作。 - Russell Leggett
此评论中列出的代码仅显示示例动画。执行电影创建工作的代码涉及将画布图像数据序列化并将每个帧通过HTTP POST到存储它们为PNG的PHP服务。将这些PNG转换为电影的操作由读者自行完成。 - asciimo

3
到目前为止,我所发现的最好的不需要编写 c 代码的方案是使用 Titanium 来进行桌面应用程序开发。它提供了一个“takeScreenshot”函数,可从 JavaScript 代码中调用来获取整个桌面的截图,但很容易自动裁剪出所需的部分。利用众多 JavaScript 动画库,即使不能实时获取每个帧的截图,也应该能够找到方法。虽然无法使用 CSS 动画,但这可能是最灵活的解决方案,因为任何可以通过 CSS 动画实现的功能都可以通过 JavaScript 实现,并且可以更好地控制帧率等参数。此外,这还允许使用浏览器所能支持的所有功能,包括 html/css/js/svg/canvas。

1
嗨@russel,已经有一段时间了,我想知道你是否对你的问题有了更高级的看法。 - Abhinav
看到这个,我也在尝试做类似的事情。不过我的需要在服务器上运行。最近我一直在研究很多选项。我刚刚用JavaFX和imageJ实现了它,但是扩展这个过程很困难。所以如果你能分享任何有用的东西,我将非常感激。谢谢! - Abhinav
我已经进行了更新。如果您想尝试这种方法,我会建议您使用 phantomjs,最容易的方法应该是使用 render 方法 (http://phantomjs.org/api/webpage/method/render.html)。不确定这样创建完整动画的效率如何 :) - Russell Leggett

2
很好,Techsmith Snagit可以捕获AVI格式,或者使用他们的高级应用程序Camtasia(生成Flash视频和Web页面启动器)也可以。为什么不简单地创建一个PowerPoint幻灯片,列出您想要介绍的功能,并使用一组HTML页面来详细说明您想要演示的实际演示内容呢?这是我采取的方法。

我并不是在做一个关于HTML的播客,我只是试图使用HTML制作一个短动画,可以将其包含在视频中 - 但这个视频并不是HTML演示。我不想让它看起来像屏幕录制 - 我只想让它看起来像一个流畅的视频。 - Russell Leggett

2
我曾经开发过一个类似于你要求的工具。它基本上使用 cutycapt(或任何其他将带有 CSS 的 HTML 转换为图像的工具),并根据所需的帧速率拍摄一系列截图。
为了使其正常工作,动画应该是纯 CSS 动画,并且该工具通过解析 CSS 插值中间帧的 CSS 属性。

https://github.com/bpsagar/css2video

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接