我想使用MediaStream.captureStream()
方法,但是由于规范和错误,它要么变得无用,要么我完全错误地使用它。
我知道captureStream
将最大帧速率作为参数,而不是恒定的,它甚至不能保证,但是可以更改 MediaStream currentTime(目前在 Chrome 中,在 Firefox 中它没有效果,但作为回报有 requestFrame,在 Chrome 中不可用),但手动框架请求或设置框架位置的想法MediaStream
应该覆盖此效果。它没有。
在 Firefox 中,它逐帧平滑地渲染视频,但视频结果与用于处理的挂钟时间一样长。
在 Chrome 中,有一些可疑的黑框或重新排序的框(目前我不关心它,直到 FPS 匹配),手动设置currentTime
没有给出任何结果,与 FF 中的结果相同。
我使用来自MediaStream Capture Canvas 和 Audio 同时回答的修改后的代码。
const FPS = 30;
var cStream, vid, recorder, chunks = [], go = true,
Q = 61, rec = document.getElementById('rec'),
canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d');
ctx.strokeStyle = 'rgb(255, 0, 0)';
function clickHandler() {
this.textContent = 'stop recording';
//it has no effect no matter if it is empty or set to 30
cStream = canvas.captureStream(FPS);
recorder = new MediaRecorder(cStream);
recorder.ondataavailable = saveChunks;
recorder.onstop = exportStream;
this.onclick = stopRecording;
recorder.start();
draw();
}
function exportStream(e) {
if (chunks.length) {
var blob = new Blob(chunks)
var vidURL = URL.createObjectURL(blob);
var vid2 = document.createElement('video');
vid2.controls = true;
vid2.src = vidURL;
vid2.onend = function() {
URL.revokeObjectURL(vidURL);
}
document.body.insertBefore(vid2, vid);
} else {
document.body.insertBefore(document.createTextNode('no data saved'), canvas);
}
}
function saveChunks(e) {
e.data.size && chunks.push(e.data);
}
function stopRecording() {
go = false;
this.parentNode.removeChild(this);
recorder.stop();
}
var loadVideo = function() {
vid = document.createElement('video');
document.body.insertBefore(vid, canvas);
vid.oncanplay = function() {
rec.onclick = clickHandler;
rec.disabled = false;
canvas.width = vid.videoWidth;
canvas.height = vid.videoHeight;
vid.oncanplay = null;
ctx.drawImage(vid, 0, 0);
}
vid.onseeked = function() {
ctx.drawImage(vid, 0, 0);
/*
Here I want to include additional drawing per each frame,
for sure taking more than 180ms
*/
if(cStream && cStream.requestFrame) cStream.requestFrame();
draw();
}
vid.crossOrigin = 'anonymous';
vid.src = 'https://dl.dropboxusercontent.com/s/bch2j17v6ny4ako/movie720p.mp4';
vid.currentTime = 0;
}
function draw() {
if(go && cStream) {
++Q;
cStream.currentTime = Q / FPS;
vid.currentTime = Q / FPS;
}
};
loadVideo();
<button id="rec" disabled>record</button><br>
<canvas id="canvas" width="500" height="500"></canvas>
有没有办法让它运行?
目标是加载视频,处理每一帧(在我的情况下这很耗时)并返回处理后的帧。
脚注:我不想使用 ffmpeg.js、外部服务器或其他技术。我可以通过经典的 ffmpeg 处理它,根本不使用 JavaScript,但这不是这个问题的重点,更多的是关于 MediaStream 的可用性/成熟度。这里的上下文是 Firefox/Chrome,但也可能是 node.js 或 nw.js。如果这完全可行或正在等待错误修复,那么下一个问题将是为其提供音频,但我认为这将是一个单独的问题。