То, что выводит ваш MediaRecorder ondataavailable
, это не видеоблок, это всего лишь фрагмент видеофайла. За исключением самого первого, он не может быть воспроизведен один, вам нужно объединить его со всеми предыдущими фрагментами, которые были записаны до этого момента.
const chunks = [];
recorder.ondatavailable = (evt) => {
chunks.push( evt.data ); // store all the chunks
play( new Blob( chunks ) ); // concatenate all the chunks to as single Blob
};
Затем для воспроизведения видео, используемого в качестве BLOB-объекта , вам нужно создать URL, указывающий на этот BLOB-объект, это делается с помощью метода URL.createObjectURL()
.
Теперь, чтобы нарисовать его на холсте, вы должны пройти через элемент , на котором вы установим src
для blob: URI, который мы создали до:
(async () => {
const source = document.createElement( 'video' );
source.crossOrigin = "anonymous";
source.muted = true;
source.src = "https://upload.wikimedia.org/wikipedia/commons/a/a4/BBH_gravitational_lensing_of_gw150914.webm";
console.log('loading, please wait');
await source.play();
const player = document.createElement( 'video' );
player.muted = true;
const output = document.getElementById( 'output' );
const ctx = output.getContext( '2d' );
const stream = (source.captureStream && source.captureStream()) || source.mozCaptureStream();
const recorder = new MediaRecorder( stream );
const chunks = [];
recorder.ondataavailable = (evt) => {
console.clear();
chunks.push( evt.data );
play( new Blob( chunks ) );
};
console.clear();
console.log('buffering, please wait 5s');
recorder.start( 5000 ); // 5s per chunk
source.addEventListener( 'ended', (evt) => recorder.stop() );
function play( blob ) {
if( player.paused ) {
drawing = true;
player.addEventListener( 'loadedmetadata', (evt) => {
output.width = player.videoWidth;
output.height = player.videoHeight;
requestAnimationFrame( loop );
}, { once: true } );
}
player.src = URL.createObjectURL( blob );
player.play();
}
function loop() {
ctx.drawImage( player, 0, 0 );
if( !player.paused ) {
requestAnimationFrame( loop );
}
}
})().catch( console.error );
<canvas id="output"></canvas>
Но учтите, что это на самом деле не обычное дело ...
Обычно мы ждем вся запись выполняется перед тем, как что-либо делать с полученным видеофайлом:
const chunks = [];
recorder.ondatavailable = (evt) => {
chunks.push( evt.data ); // store all the chunks
};
recorder.onstop = (evt) => { // only when the recording is entirely done
play( new Blob( chunks ) ); // concatenate all the chunks to as single Blob
};
Но если вы действительно хотите нарисовать это видео на холсте в режиме реального времени, просто сделайте это и не используйте MediaRecorder в все:
(async () => {
const source = document.createElement( 'video' );
source.crossOrigin = "anonymous";
source.muted = true;
source.src = "https://upload.wikimedia.org/wikipedia/commons/a/a4/BBH_gravitational_lensing_of_gw150914.webm";
console.log('loading, please wait');
await source.play();
console.clear();
const player = document.createElement( 'video' );
player.muted = true;
const output = document.getElementById( 'output' );
const ctx = output.getContext( '2d' );
const stream = (source.captureStream && source.captureStream()) || source.mozCaptureStream();
player.addEventListener( 'loadedmetadata', (evt) => {
output.width = player.videoWidth;
output.height = player.videoHeight;
requestAnimationFrame( loop );
}, { once: true } );
player.srcObject = stream;
player.play();
function loop() {
ctx.drawImage( player, 0, 0 );
if( !source.paused ) {
requestAnimationFrame( loop );
}
}
})().catch( console.error );
<canvas id="output"></canvas>