是否可以以较低的帧速率提供MediaStream帧?

时间:2017-11-23 07:25:23

标签: javascript html5 video html5-canvas mediastream

我想使用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。如果这是可能的或等待修复错误,下一个问题就是向它提供音频,但我认为这将是一个单独的问题。

0 个答案:

没有答案