我想使用MediaStream.captureStream()
方法,但由于规范和错误而导致它无法使用,或者我使用它完全错误。
我知道captureStream
得到最大帧率作为参数,而不是常数,甚至不能保证,但是可以更改MediaStream currentTime(目前在Chrome中,在Firefox中它没有效果,但作为回报,有请求框架,在Chrome上不可用),但手动框架请求或在MediaStream
中设置框架的位置的想法应该覆盖此效果。它没有。
在Firefox中,它可以逐帧平滑地呈现视频,但视频结果与用于处理的挂钟时间一样长。
在Chrome中有一些可疑的黑色帧或重新排序的帧(目前我不关心它直到FPS匹配),并且currentTime
的手动设置没有给出任何结果,与FF中的结果相同。
我使用来自MediaStream Capture Canvas and Audio Simultaneously answer的修改后的代码。
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,外部服务器或其他技术。我可以在不使用JavaScript的情况下通过经典的ffmpeg处理它,但这不是这个问题的重点,更多的是关于MediaStream的可用性/成熟度。这里的上下文是Firefox / Chrome,但也可能是node.js或nw.js。如果这是可能的或等待修复错误,下一个问题就是向它提供音频,但我认为这将是一个单独的问题。