J'ai un flux de toile en utilisant canvas.captureStream(). J'ai un autre flux vidéo de l'appel vidéo webrtc. Maintenant, je veux mélanger le flux de toile avec les pistes audio du flux vidéo. Comment puis-je faire cela?Comment pouvons-nous mélanger flux de toile avec flux audio en utilisant mediaRecorder
3
A
Répondre
1
Utilisez le MediaStream
constructor disponible dans Firefox et Chrome 56, de combiner des pistes dans un nouveau flux:
let stream = new MediaStream([videoTrack, audioTrack]);
Les œuvres suivantes pour moi dans Firefox (utilisation https fiddle dans Chrome, mais il des erreurs sur l'enregistrement):
navigator.mediaDevices.getUserMedia({audio: true})
.then(stream => record(new MediaStream([stream.getTracks()[0],
whiteNoise().getTracks()[0]]), 5000)
.then(recording => {
stop(stream);
video.src = link.href = URL.createObjectURL(new Blob(recording));
link.download = "recording.webm";
link.innerHTML = "Download recording";
log("Playing "+ recording[0].type +" recording:");
})
.catch(log))
.catch(log);
var whiteNoise =() => {
let ctx = canvas.getContext('2d');
ctx.fillRect(0, 0, canvas.width, canvas.height);
let p = ctx.getImageData(0, 0, canvas.width, canvas.height);
requestAnimationFrame(function draw(){
for (var i = 0; i < p.data.length; i++) {
p.data[i++] = p.data[i++] = p.data[i++] = Math.random() * 255;
}
ctx.putImageData(p, 0, 0);
requestAnimationFrame(draw);
});
return canvas.captureStream(60);
}
var record = (stream, ms) => {
var rec = new MediaRecorder(stream), data = [];
rec.ondataavailable = e => data.push(e.data);
rec.start();
log(rec.state + " for "+ (ms/1000) +" seconds...");
var stopped = new Promise((y, n) =>
(rec.onstop = y, rec.onerror = e => n(e.error || e.name)));
return Promise.all([stopped, wait(ms).then(_ => rec.stop())]).then(_ => data);
};
var stop = stream => stream.getTracks().forEach(track => track.stop());
var wait = ms => new Promise(resolve => setTimeout(resolve, ms));
var log = msg => div.innerHTML += "<br>" + msg;
<div id="div"></div><br>
<canvas id="canvas" width="160" height="120" hidden></canvas>
<video id="video" width="160" height="120" autoplay></video>
<a id="link"></a>
devrait-il pas être correctement en utilisant 'MediaStream.addTrack'? (Même si cela [ne fonctionne pas dans FF] (https://bugzilla.mozilla.org/show_bug.cgi?id=1296531).) De plus, Chrome préfixe toujours le constructeur 'MediaStream'. – Kaiido
@Kaiido Ils ont tous les deux raison. Le constructeur travaille pour moi dans Chrome Canary sans l'attribut chrome: // flags/# enable-experimental-web-platform-features, bien que quelque chose dans l'enregistrement échoue. Espérons que les deux navigateurs corrigent leurs bugs bientôt. – jib
Oui, il est non préfixé dans canary 56, mais dans stable 53, vous devez toujours appeler 'new webkitMediaStream()'. J'ai fait un worakround laide pour gérer les deux navigateurs à la fin de [cette dupe] (http://stackoverflow.com/questions/39302814/mediastream-capture-canvas-and-audio-simultaneously). Et oui, il y a encore beaucoup de bugs dans les deux UA ... – Kaiido