如何PNG图像数据的阵列转换成视频文件如何PNG图像数据的阵列转换成视频文件(How to conv

2019-05-12 03:47发布

我收到的帧从canvas通过canvas.getDataURL()

不过,现在我有PNG图像的数组,但我想要的视频文件。

我该怎么做呢?

var canvas = document.getElementById("mycanvaselementforvideocapturing");
var pngimages = [];
...
setInterval(function(){pngimages.push(canvas.toDataURL())}, 1000);

Answer 1:

对于一个完整的浏览器支持的方式,你有你的图片批量发送到服务器,然后使用一些服务器端程序做编码。

FFmpeg的可能是能够做到这一点。

但在最新的浏览器canvas.captureStream方法,已落实。 它将你的画布图纸转换成WebM视频流,具有可记录MediaRecorder 。 所有这一切都还没有,虽然稳定,只会在浏览器的最新版本,可能与用户的喜好设置一些标志(如铬需要“实验网络平台”一节)。

 var cStream, recorder, chunks = []; rec.onclick = function() { this.textContent = 'stop recording'; // set the framerate to 30FPS var cStream = canvas.captureStream(30); // create a recorder fed with our canvas' stream recorder = new MediaRecorder(cStream); // start it recorder.start(); // save the chunks recorder.ondataavailable = saveChunks; recorder.onstop = exportStream; // change our button's function this.onclick = stopRecording; }; function saveChunks(e) { chunks.push(e.data); } function stopRecording() { recorder.stop(); } function exportStream(e) { // combine all our chunks in one blob var blob = new Blob(chunks) // do something with this blob var vidURL = URL.createObjectURL(blob); var vid = document.createElement('video'); vid.controls = true; vid.src = vidURL; vid.onended = function() { URL.revokeObjectURL(vidURL); } document.body.insertBefore(vid, canvas); } // make something move on the canvas var x = 0; var ctx = canvas.getContext('2d'); var anim = function() { x = (x + 2) % (canvas.width + 100); // there is no transparency in webm, // so we need to set a background otherwise every transparent pixel will become opaque black ctx.fillStyle = 'ivory'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = 'black'; ctx.fillRect(x - 50, 20, 50, 50) requestAnimationFrame(anim); }; anim(); 
 <canvas id="canvas" width="500" height="200"></canvas> <button id="rec">record</button> 

而且既然你问了一个方法来添加音频视频,请注意,您可以使用cStream.addTrack(anAudioStream.getAudioTracks()[0]); 致电前new MediaRecorder(cStream)但是这会在Chrome目前只工作,FF似乎有MediaRecorder一个错误,这使得它仅记录它被定义在轨道上的流...一个FF的解决方法是调用new MediaStream([videoTrack, audioTrack]);

[非常感谢@jib让我知道如何实际使用它...]

编辑: video.onend - > video.onended



Answer 2:

MediaRecorder + canvas.captureStream在Kaiido的回答方式是肯定要走的那一刻的方式-遗憾的是因为写它的Chrome和Firefox的唯一支持。

当浏览器采用WEBP编码的支持(仅适用于Chrome浏览器拥有它,目前),将工作的另一种方法是这样的:

let frames = []; // <-- frames must be *webp* dataURLs
let webmEncoder = new Whammy.Video(fps); 
frames.forEach(f => webmEncoder.add(f));
let blob = await new Promise(resolve => webmEncoder.compile(false, resolve));
let videoBlobUrl = URL.createObjectURL(blob);

它采用了夹击库加入了一堆WEBP图片成WebM视频。 在支持WEBP编码你可以写的浏览器canvas.toDataURL("image/webp")以获得从画布上WEBP dataURL。 这是对Firefox的支持WEBP相关的bug报告。

一个跨浏览器的方法,因为写作似乎是使用libwebp.js由输出PNG dataURLs转换canvas.toDataURL()成WEBP图像,然后喂那些进入夹击编码器,让您最终的WebM视频。 不幸的是,PNG - > WEBP编码过程非常缓慢 (几分钟的视频在我的笔记本电脑几秒钟)。

编辑:我发现,与MediaRecorder / captureStream方法,您可以用比夹击的办法低质量的输出视频结束。 所以,除非有一些方法来控制捕获流的质量, whammy的做法似乎是最好的方法,与其他两个作为秋季的挫折。 见这个问题的更多细节。 使用此代码段来检测浏览器是否支持webp编码(以及因此支持打击的方法):

let webPEncodingIsSupported = document.createElement('canvas').toDataURL('image/webp').startsWith('data:image/webp');


文章来源: How to convert array of png image data into video file