是否可以使用“javascript”或任何“网络客户端”方法对来自gif(或图像序列)和某些声音文件的视频进行编码?是否可以使用javascript从gif(或一系列图像)创建视频?
具体而言,我想从一些源图像和声音文件在客户端动态创建一个视频文件。然后我想让用户下载最终的视频。
我知道我可以使用ffmpeg和PHP在服务器端创建来自图像和mp3的视频,但我不想使用此方法,因为这会导致巨大的服务器CPU使用率和数据传输。
是否可以使用“javascript”或任何“网络客户端”方法对来自gif(或图像序列)和某些声音文件的视频进行编码?是否可以使用javascript从gif(或一系列图像)创建视频?
具体而言,我想从一些源图像和声音文件在客户端动态创建一个视频文件。然后我想让用户下载最终的视频。
我知道我可以使用ffmpeg和PHP在服务器端创建来自图像和mp3的视频,但我不想使用此方法,因为这会导致巨大的服务器CPU使用率和数据传输。
你有几个问题需要解决,以实现这一点。
获取GIF的原始像素。
<canvas>
可能是做到这一点的最佳方式,但我认为它不会很好地与GIF动画一起玩。你当然可以读一系列的图像。
将帧转换为视频流。
虽然有JavaScript implementations of MPEG audio codecs,我不知道在纯JS的视频编解码器。你可以看看ffmpeg源码并尝试移植它。
除了实现视频压缩编解码器本身(如MPEG-1,-2,H.264等)之外,还必须写入某种容器格式(例如, a MPEG PS。)
处理二进制数据。
任何视频编解码器的输出都是二进制数据,而JavaScript本质上并不能很好地处理原始二进制数据。最近的浏览器已经加入了typed arrays,以便以高效的内存方式解决这个缺点。
将视频文件传送给用户。
我知道这听起来很愚蠢,因为所有的上述技术会在用户的计算机上发生,但他们在浏览器沙盒发生。您现在必须将数据从浏览器中取出并存储到用户可以保存到文件系统的文件中。
其他人建议使用URI(base64编码数据),但从内存的角度来看,这是一个糟糕的想法,尤其是因为您将要处理的视频数据相对较大。在这一点上,你将有一个类型的数组视频流。从键入的数组中创建一个新的Blob
,并将Blob
传递给window.URL.createObjectURL
。这样,数据不需要在内存中复制;相反,浏览器将从类型化数组中“下载”到文件系统。
当然,所有这些假定用户的机器将有足够的内存(RAM)。与普通的视频压缩实现不同,您不能将输出数据流式传输到磁盘;你必须将整个文件保存在内存中。你可能会比你想象的更快地耗尽内存。
所以虽然这可能是理论上可能的,这不是一个好主意。如果它工作,它会非常缓慢,并冻结浏览器,而它编码的视频(因为JS和浏览器用户界面共享相同的单线程)。不过,我想你可以将网络工作者带入混合中来解决这个问题。
在这个时候,你几乎不得不推出你自己的服务器端解决方案,或者使用某种类型的service,它会为你付出沉重的代价。
或者,您可以在Chrome中利用Google的NaCl (native client)实际进行视频编码。 NaCl允许您在浏览器中运行本地(C/C++)代码。
它看起来像有一个ffmpeg port,并且有APIs to do file I/O。
很明显,这只在Chrome中有效。 Firefox,Safari和IE不支持NaCl。
在很多浏览器中,数据URI的长度也非常有限 - 整个视频可能由他们持有的机会非常低。 – Oded
当然。
使用setInterval
按计划调用函数,将图像源依次更改为下一个。
您可能希望预加载图像,以便在图像源更改时不会等待。
更新:
您possibly can创建单独使用JavaScript的图像序列的视频文件,但是这不太可能是容易或工作。我建议您使用一些服务器端处理来制作这样的视频并将音频合并到其中(可能使用ffmpeg)。
您已经注意到,为此目的编写的C语言程序会占用大量的CPU周期名称。什么会让你认为一个为其他目的设计的脚本语言完全可以做到这一点?
不,Javascript 在浏览器上没有直接访问各个像素,当然也无法创建二进制文件。如果您将这些帧作为单独的图像,则可以将它们加载到canvas
标记,access the pixels这样的方式中,将MPEG版本计算为整数数组并将其发回到服务器(将该数组转换为二进制文件),但哇,会不会很慢。至少比ffmpeg慢1000倍。
编辑
的评论指出,我其实完全错误的。尽管如此,我坚持我原来的结论,这是一个可怕的想法。
公平地说,有[JS MP3编解码器实现](https://www.google.com/search?q=javascript+mpeg+codec),而且[你可以用一个键入的数组](https://developer.mozilla.org/en-US/docs/JavaScript/Typed_arrays),因此MPEG视频编解码器在技术上*是可能的。而且,为了将数据传递给用户,您甚至不必将其发送回服务器;从类型数组中创建一个['Blob'](https://developer.mozilla.org/en-US/docs/DOM/Blob),并将'Blob'传递给['window.URL.createObjectURL'](https ://developer.mozilla.org/en-US/docs/DOM/window.URL.createObjectURL)。 – josh3736
+1,但服务器根本不是技术上需要的;您可以简单地将页面重定向到base64编码的data:URI来执行二进制下载。也就是说,我同意100%,这不是一个好主意。 – apsillers
这是可能的,它是可行的(速度/资源消耗明智)。看到我的答案。 – CWSpear
这是2014年底了,我不知道在什么时候,它之所以成为可能,但它确实是现在可以把一个视频转换为GIF:由同一人 http://jnordberg.github.io/gif.js/tests/video.html
通过图书馆谁演示了这个演示:https://github.com/jnordberg/gif.js
在Chrome 38中很有效,我相信任何其他支持Web Workers,File API和Typed Arrays的浏览器。
一个文件只是一个位序列 - 你*可以*取某些图像文件的位(例如使用'canvas'),然后做很多复杂的位操作,最后创建一个序列可作为视频文件播放的位。如果没有视频处理库,这将非常困难,并且据我所知,没有这样的JavaScript库存在。你可以自己编写一个这样的库(经过对图像和视频文件的详细研究),或者雇佣一些人为你编写它。 – apsillers
关闭选民:'重复'是关于显示一系列图像以达到动画的效果;这个问题是关于实际编码视频客户端。 – josh3736