MediaRecorder.stop()
является своего рода асинхронным методом.
В алгоритме stop существует вызов requestData , который сам поставит в очередь задачу для запуска события dataavailable с текущимдоступные данные с момента последнего такого события.
Это означает, что синхронно после того, как вы вызвали MediaRecorder # stop () , последние захваченные данные еще не будут частью вашего allChunks
массива.Они станут не такими длинными после этого (обычно в одном и том же цикле событий).
Поэтому, когда вы собираетесь сохранять записи, сделанные из MediaRecorder, обязательно всегда собирайте последний BLOB-объект из MediaRecorder.Событие onstop
, которое будет сигнализировать о том, что MediaRecorder действительно завершен, запустило свое последнее событие dataavailable и все хорошо.
И одна вещь, которую я пропустил приВо-первых, вы запрашиваете междоменное видео.В результате этого без правильного запроса перекрестного происхождения ваш холст (и MediaElement) будут испорчены, поэтому ваш MediaStream будет отключен.
Поскольку видео, которое вы пытаетесь запросить, получено из Викимедиа, вы можете просто запроситьон является ресурсом разных источников, но для других ресурсов вы должны быть уверены, что сервер настроен на разрешение этих запросов.
const canvas = document.querySelector("canvas")
const ctx = canvas.getContext("2d")
const video = document.querySelector("video")
// Start the video in the player
video.play()
// On play event - draw the video in the canvas
video.addEventListener('play', () => {
function step() {
ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
requestAnimationFrame(step)
}
requestAnimationFrame(step);
// Init stream and recorder
const stream = canvas.captureStream()
const recorder = new MediaRecorder(stream, {
mimeType: 'video/webm',
});
// Get the blob data when is available
let allChunks = [];
recorder.ondataavailable = function(e) {
allChunks.push(e.data);
}
recorder.onstop = (e) => {
const fullBlob = new Blob(allChunks, { 'type' : 'video/webm' });
const downloadUrl = window.URL.createObjectURL(fullBlob)
console.log({fullBlob})
console.log({downloadUrl})
}
// Start to record
recorder.start()
// Stop the recorder after 5s and check the result
setTimeout(() => {
recorder.stop()
}, 5000);
})
<!--add the 'crossorigin' attribute to your video -->
<video id="video" controls="true" src="https://upload.wikimedia.org/wikipedia/commons/7/79/Big_Buck_Bunny_small.ogv" crossorigin="anonymous"></video>
<canvas id="myCanvas" width="532" height="300"></canvas>
Кроме того, я не могу не отметить, что если вы не делаете никаких специальных рисунков со своего холста, вы можете сохранитьнепосредственно к источнику видео или, по крайней мере, напрямую записывать captureStream MediaStream.