Объединение двух видео MediaStream потоков в 1
Задача: Нужно на стороне клиента (в браузере) объединить поток с вебкамерой и поток с демонстрацией экрана в один общий поток, так, чтобы видео с вебкамеры закрыло небольшую часть видео с демонстрацией экрана (например видео с вебки в правом верхнем углу).
Я знаю что можно получить MediaStreamTrack объекты с помощью getTracks, а затем объединить их в один MediaStream объект. Но я подозреваю, что получу просто быструю смену вебки и демонстрации экрана (1 кадр вебка, 1 кадр экран). И этот способ никак не позволяет мне управлять местоположением вебкамеры
Можно ли провернуть такое на стороне клиента или придётся прибегать к рендерингу на стороне сервера? Очень бы не хотелось это делать на сервере, потому что это требует много ресурсов
Ответы (1 шт):
Можно отрисовать всё в один canvas, а потом захватить результат с него.
(async () => {
let webCam = streamToVideo(await getWebCam());
let desktop = streamToVideo(await getDesktop());
let canvas = document.createElement('canvas');
let context = canvas.getContext('2d');
// 1024x576 - 16:9
canvas.width = 1024;
canvas.height = 576;
(function draw() {
context.drawImage(desktop, 0, 0, canvas.width, canvas.height);
// 200x150 - 4:3
let w = 200;
let h = 150;
context.drawImage(webCam, canvas.width - w, canvas.height - h, w, h);
requestAnimationFrame(draw);
})();
// Вот тут вы получаете тот результат который хотели
let resultMediaStream = canvas.captureStream();
// Но для примера выводим на страницу
let video = streamToVideo(resultMediaStream);
document.body.appendChild(video);
})();
function streamToVideo(stream) {
let video = document.createElement('video');
video.srcObject = stream;
video.style.width = stream.width;
video.style.height = stream.height;
video.play();
return video;
}
async function getWebCam() {
return await navigator.mediaDevices.getUserMedia({video: true});
}
async function getDesktop() {
return await navigator.mediaDevices.getDisplayMedia({video: true});
}