我收到的帧从canvas
通过canvas.getDataURL()
不过,现在我有PNG图像的数组,但我想要的视频文件。
我该怎么做呢?
var canvas = document.getElementById("mycanvaselementforvideocapturing");
var pngimages = [];
...
setInterval(function(){pngimages.push(canvas.toDataURL())}, 1000);
我收到的帧从canvas
通过canvas.getDataURL()
不过,现在我有PNG图像的数组,但我想要的视频文件。
我该怎么做呢?
var canvas = document.getElementById("mycanvaselementforvideocapturing");
var pngimages = [];
...
setInterval(function(){pngimages.push(canvas.toDataURL())}, 1000);
对于一个完整的浏览器支持的方式,你有你的图片批量发送到服务器,然后使用一些服务器端程序做编码。
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
该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');