MediaStream同时捕获画布和音频

我正在一个项目中,我想要:

  1. 加载视频js并将其显示在画布上。
  2. 使用滤镜可更改画布(以及视频)的外观。
  3. 使用MediaStream captureStream()方法和MediaRecorder对象来记录画布的表面和原始视频的音频。
  4. 在HTML视频元素中播放画布和音频流。

就是说,我不知道如何在画布旁边录制视频的音频。是否可以从两个不同的源/元素创建一个包含MediaStreamTrack实例的MediaStream?

“ MediaStreamAPI的两个主要组件是MediaStreamTrack和MediaStream接口。MediaStreamTrack对象表示一种单一类型的媒体,该媒体源自用户代理中的一个媒体源,例如网络摄像头产生的视频。MediaStream用于分组将多个MediaStreamTrack对象合并为一个单元,可以将其记录或呈现在媒体元素中。”_

回答:

是否可以从两个不同的源/元素创建一个包含MediaStreamTrack实例的MediaStream?

是的,您可以使用MediaStream.addTrack()方法进行操作。


OP已经知道如何获取所有信息,但是在此提醒未来的读者:

  • 要从画布获取videoStream轨道,可以调用canvas.captureStream(framerate)method。

  • 要从视频元素获取音频streamTrack,可以使用WebAudio API及其createMediaStreamDestination方法。这将返回dest包含我们的audioStream 的MediaStreamDestination节点()。然后,您必须将根据您的视频元素创建[MediaElementSource连接到this dest。如果您需要向此流添加更多音轨,则应将所有这些源连接到dest

现在我们有了两个流,一个流用于画布视频,一个流用于音频,我们可以canvasStream.addTrack(audioStream.getAudioTracks()[0])在初始化之前使用newMediaRecorder(canvasStream)

这是一个完整的示例,该示例现在仅在chrome中有效,并且可能很快将在Firefox中运行,此时他们将修复该错误:

var cStream,

aStream,

vid,

recorder,

analyser,

dataArray,

bufferLength,

chunks = [];

function clickHandler() {

this.textContent = 'stop recording';

cStream = canvas.captureStream(30);

cStream.addTrack(aStream.getAudioTracks()[0]);

recorder = new MediaRecorder(cStream);

recorder.start();

recorder.ondataavailable = saveChunks;

recorder.onstop = exportStream;

this.onclick = stopRecording;

};

function exportStream(e) {

if (chunks.length) {

var blob = new Blob(chunks)

var vidURL = URL.createObjectURL(blob);

var vid = document.createElement('video');

vid.controls = true;

vid.src = vidURL;

vid.onend = function() {

URL.revokeObjectURL(vidURL);

}

document.body.insertBefore(vid, canvas);

} else {

document.body.insertBefore(document.createTextNode('no data saved'), canvas);

}

}

function saveChunks(e) {

e.data.size && chunks.push(e.data);

}

function stopRecording() {

vid.pause();

this.parentNode.removeChild(this);

recorder.stop();

}

function initAudioStream(evt) {

var audioCtx = new AudioContext();

// create a stream from our AudioContext

var dest = audioCtx.createMediaStreamDestination();

aStream = dest.stream;

// connect our video element's output to the stream

var sourceNode = audioCtx.createMediaElementSource(this);

sourceNode.connect(dest)

// start the video

this.play();

// just for the fancy canvas drawings

analyser = audioCtx.createAnalyser();

sourceNode.connect(analyser);

analyser.fftSize = 2048;

bufferLength = analyser.frequencyBinCount;

dataArray = new Uint8Array(bufferLength);

analyser.getByteTimeDomainData(dataArray);

// output to our headphones

sourceNode.connect(audioCtx.destination)

startCanvasAnim();

rec.onclick = clickHandler;

rec.disabled = false;

};

var loadVideo = function() {

vid = document.createElement('video');

vid.crossOrigin = 'anonymous';

vid.oncanplay = initAudioStream;

vid.src = 'https://dl.dropboxusercontent.com/s/bch2j17v6ny4ako/movie720p.mp4';

}

function startCanvasAnim() {

// from MDN https://developer.mozilla.org/en/docs/Web/API/AnalyserNode#Examples

var canvasCtx = canvas.getContext('2d');

canvasCtx.fillStyle = 'rgb(200, 200, 200)';

canvasCtx.lineWidth = 2;

canvasCtx.strokeStyle = 'rgb(0, 0, 0)';

var draw = function() {

var drawVisual = requestAnimationFrame(draw);

analyser.getByteTimeDomainData(dataArray);

canvasCtx.fillRect(0, 0, canvas.width, canvas.height);

canvasCtx.beginPath();

var sliceWidth = canvas.width * 1.0 / bufferLength;

var x = 0;

for (var i = 0; i < bufferLength; i++) {

var v = dataArray[i] / 128.0;

var y = v * canvas.height / 2;

if (i === 0) {

canvasCtx.moveTo(x, y);

} else {

canvasCtx.lineTo(x, y);

}

x += sliceWidth;

}

canvasCtx.lineTo(canvas.width, canvas.height / 2);

canvasCtx.stroke();

};

draw();

}

loadVideo();

<canvas id="canvas" width="500" height="200"></canvas>

<button id="rec" disabled>record</button>


:由于FF团队似乎需要花费一些时间来修复该错误,因此这里有一个快速修复使其也可以在FF上运行。

您也可以使用混合两个音轨newMediaStream([track1,track2])。但是,chrome当前为此构造函数添加了前缀,但由于它确实支持addTrack,因此并不需要它,因此我们可以提供类似

var mixedStream = 'MediaStream' in window ? 

new MediaStream([cStream.getVideoTracks()[0], aStream.getAudioTracks()[0]]) :

cStream;

recorder = new MediaRecorder(mixedStream);

以上是 MediaStream同时捕获画布和音频 的全部内容, 来源链接: utcz.com/qa/435552.html

回到顶部