如何将png图像数据数组转换为视频文件
How to convert array of png image data into video file
我正在从 canvas
到 canvas.getDataURL()
获取帧。
但是,现在我有一组 png 图片,但我想要一个视频文件。
我该怎么做?
var canvas = document.getElementById("mycanvaselementforvideocapturing");
var pngimages = [];
...
setInterval(function(){pngimages.push(canvas.toDataURL())}, 1000);
对于完整的浏览器支持方式,您必须将图像批处理发送到服务器,然后使用一些服务器端程序进行编码。
FFmpeg might be able to do it.
但是在最新的浏览器中已经实现了 canvas.captureStream
方法。
它会将您的 canvas 绘图转换为 webm 视频流,可使用 MediaRecorder
录制。
尽管如此,所有这些仍然不稳定,并且只能在最新版本的浏览器中使用,可能在用户的首选项中设置了一些标志(例如 chrome 需要 "Experimental Web Platforms" 一个)。
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>
并且由于您询问了向该视频添加音频的方法,请注意您可以在调用 new MediaRecorder(cStream)
之前使用 cStream.addTrack(anAudioStream.getAudioTracks()[0]);
,但这目前仅适用于 chrome, FF 似乎在 MediaRecorder 中有一个错误,这使得它只记录带有它定义的轨道的流...... FF 的解决方法是调用 new MediaStream([videoTrack, audioTrack]);
[非常感谢@jib 让我知道如何实际使用它...]
编辑:video.onend
--> video.onended
Kaiido 的回答中的 MediaRecorder
+ canvas.captureStream
方法绝对是目前的方法 - 不幸的是,在撰写本文时它仅在 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);
它使用 whammy library to join a bunch of webp images into a webm video. In browsers that support webp encoding you can write canvas.toDataURL("image/webp")
to get a webp dataURL from a canvas. This 是 Firefox webp 支持的相关错误报告。
在撰写本文时,一种跨浏览器的方法似乎是使用 libwebp.js 将 canvas.toDataURL()
输出的 png 数据 URL 转换为 webp 图像,然后将这些输入 whammy 编码器以获得您的最后的 webm 视频。不幸的是,png-->webp 编码过程非常慢(我的笔记本电脑上几秒钟的视频需要几分钟)。
编辑: 我发现使用 MediaRecorder
/captureStream
方法,与糟糕的方法。因此,除非有某种方法可以控制捕获的流的质量,否则 whammy
方法似乎是最好的方法,其他两个作为后备方法。有关详细信息,请参阅 。使用此代码段来检测浏览器是否支持 webp
编码(因此支持 whammy 方法):
let webPEncodingIsSupported = document.createElement('canvas').toDataURL('image/webp').startsWith('data:image/webp');
我正在从 canvas
到 canvas.getDataURL()
获取帧。
但是,现在我有一组 png 图片,但我想要一个视频文件。
我该怎么做?
var canvas = document.getElementById("mycanvaselementforvideocapturing");
var pngimages = [];
...
setInterval(function(){pngimages.push(canvas.toDataURL())}, 1000);
对于完整的浏览器支持方式,您必须将图像批处理发送到服务器,然后使用一些服务器端程序进行编码。
FFmpeg might be able to do it.
但是在最新的浏览器中已经实现了 canvas.captureStream
方法。
它会将您的 canvas 绘图转换为 webm 视频流,可使用 MediaRecorder
录制。
尽管如此,所有这些仍然不稳定,并且只能在最新版本的浏览器中使用,可能在用户的首选项中设置了一些标志(例如 chrome 需要 "Experimental Web Platforms" 一个)。
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>
并且由于您询问了向该视频添加音频的方法,请注意您可以在调用 new MediaRecorder(cStream)
之前使用 cStream.addTrack(anAudioStream.getAudioTracks()[0]);
,但这目前仅适用于 chrome, FF 似乎在 MediaRecorder 中有一个错误,这使得它只记录带有它定义的轨道的流...... FF 的解决方法是调用 new MediaStream([videoTrack, audioTrack]);
[非常感谢@jib 让我知道如何实际使用它...]
编辑:video.onend
--> video.onended
Kaiido 的回答中的 MediaRecorder
+ canvas.captureStream
方法绝对是目前的方法 - 不幸的是,在撰写本文时它仅在 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);
它使用 whammy library to join a bunch of webp images into a webm video. In browsers that support webp encoding you can write canvas.toDataURL("image/webp")
to get a webp dataURL from a canvas. This 是 Firefox webp 支持的相关错误报告。
在撰写本文时,一种跨浏览器的方法似乎是使用 libwebp.js 将 canvas.toDataURL()
输出的 png 数据 URL 转换为 webp 图像,然后将这些输入 whammy 编码器以获得您的最后的 webm 视频。不幸的是,png-->webp 编码过程非常慢(我的笔记本电脑上几秒钟的视频需要几分钟)。
编辑: 我发现使用 MediaRecorder
/captureStream
方法,与糟糕的方法。因此,除非有某种方法可以控制捕获的流的质量,否则 whammy
方法似乎是最好的方法,其他两个作为后备方法。有关详细信息,请参阅 webp
编码(因此支持 whammy 方法):
let webPEncodingIsSupported = document.createElement('canvas').toDataURL('image/webp').startsWith('data:image/webp');