Я пытаюсь создать видео в браузере из другого фрагмента: Слайд: поток с холста Видео: трансляция с веб-камеры
Я просто хочу разрешить пользователю загружать редактирование видео с помощью слайд1 + видео1 + слайд2 + видео2 + слайд3 + видео3.
Вот мой код:
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
const webcam = document.getElementById('webcam');
const videoPlayer = document.createElement('video');
videoPlayer.controls = true;
document.body.appendChild(videoPlayer);
const videoWidth = 640;
const videoHeight = 480;
let keepAnimating = true;
const frameRate=30;
// Attempt to get webcam access
function setupWebcam() {
const constraints = {
video: {
frameRate: frameRate,
width: videoWidth,
height: videoHeight
}
};
navigator.mediaDevices.getUserMedia(constraints)
.then(stream => {
webcam.srcObject = stream;
webcam.addEventListener('loadedmetadata', () => {
recordSegments();
console.info('Webcam feed is now displayed');
});
})
.catch(err => {
console.error("Error accessing webcam:", err);
alert('Could not access the webcam. Please ensure permissions are granted and try again.');
});
}
// Function to continuously draw on the canvas
function animateCanvas(content) {
if (!keepAnimating) {
console.info("keepAnimating", keepAnimating);
return;
}; // Stop the animation when keepAnimating is false
ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear previous drawings
ctx.fillStyle = `rgba(${Math.floor(Math.random() * 255)}, ${Math.floor(Math.random() * 255)}, ${Math.floor(Math.random() * 255)}, 0.5)`;
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#000';
ctx.font = '48px serif';
ctx.fillText(content + ' ' + new Date().toLocaleTimeString(), 50, 100);
// Request the next frame
requestAnimationFrame(() => animateCanvas(content));
}
// Initialize recording segments array
const recordedSegments = [];
// Modified startRecording to manage animation
function startRecording(stream, duration = 5000, content) {
const recorder = new MediaRecorder(stream, { mimeType: 'video/webm' });
const data = [];
recorder.ondataavailable = e => data.push(e.data);
// Start animating the canvas
keepAnimating = true;
animateCanvas(content);
recorder.start();
return new Promise((resolve) => {
// Automatically stop recording after 'duration' milliseconds
setTimeout(() => {
recorder.stop();
// Stop the animation when recording stops
keepAnimating = false;
}, duration);
recorder.onstop = () => {
const blob = new Blob(data, { type: 'video/webm' });
recordedSegments.push(blob);
keepAnimating = true;
resolve(blob);
};
});
}
// Sequence to record segments
async function recordSegments() {
// Record canvas with dynamic content
await startRecording(canvas.captureStream(frameRate), 2000, 'Canvas Draw 1').then(() => console.info('Canvas 1 recorded'));
await startRecording(webcam.srcObject,3000).then(() => console.info('Webcam 1 recorded'));
await startRecording(webcam.srcObject).then(() => console.info('Webcam 1 recorded'));
mergeAndDownloadVideo();
}
function downLoadVideo(blob){
const url = URL.createObjectURL(blob);
// Create an anchor element and trigger a download
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = 'merged-video.webm';
document.body.appendChild(a);
a.click();
// Clean up by revoking the Blob URL and removing the anchor element after the download
setTimeout(() => {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 100);
}
function mergeAndDownloadVideo() {
console.info("recordedSegments length", recordedSegments.length);
// Create a new Blob from all recorded video segments
const superBlob = new Blob(recordedSegments, { type: 'video/webm' });
downLoadVideo(superBlob)
// Create a URL for the superBlob
}
// Start the process by setting up the webcam first
setupWebcam();
Найти его можно здесь: https://jsfiddle.net/Sulot/nmqf6wdj/25/
Я не могу создать один «слайд» + видео с веб-камеры + «слайд» + видео с веб-камеры.
Он объединяет только первые 2 сегмента, но не другой. Я попробовал со стороны браузера ffmpeg.
Да, вы, мол, правы на 100%. Однако я не могу понять, в чем проблема. Я удаляю часть «игры» при загрузке. И загрузка не работает. И нет, видеоклип не по отдельности правильный, только первые.
Хорошо, теперь я понимаю, что вы пытаетесь объединить видео из совершенно разных видео? Это не сработает. У вас разные данные трека с холста и веб-камеры, а что нет. Вы не можете просто объединить произвольные фрагменты видео таким образом. Кроме того, то, что выходит из MediaRecorder, не является отдельными частями. Это всего лишь части длинного видеопотока. Есть два способа сделать то, что, как мне кажется, вы хотите сделать... либо взять независимые видеопотоки и выполнить сращивание на стороне сервера, либо просто нарисовать все на холсте и записать холст как один поток.
Есть третий способ — отказаться от MediaRecorder и использовать API веб-кодеков, но он более сложен, чем вам нужно, и все равно не решает вашу первоначальную проблему переключения потоков. Вам все равно придется рисовать все на этом холсте.
Итак, я смог сделать то, что хотел, используя MultiStreamsMixer. https://github.com/muaz-kan/MultiStreamsMixer
Вам нужно сузить эту проблему. Если все ваши отдельные видеоклипы записываются нормально, то проблема здесь не в 95% кода, а связана только с вашим воспроизведением и переключением, да?