Given the code
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<video width="320" height="280"></video>
<script>
const video = document.querySelector("video");
const src = "https://mirrors.creativecommons.org/movingimages/webm/ScienceCommonsJesseDylan_240p.webm#t=0,10";
let recorder;
video.oncanplay = () => {
video.play();
const mediaStream = video.captureStream();
recorder = new MediaRecorder(mediaStream);
recorder.ondataavailable = event =>
console.log(URL.createObjectURL(event.data));
recorder.start();
}
video.onpause = () => recorder && recorder.stop();
video.src = src;
</script>
</body>
</html>
Chromium browser captures the playback of <video>
element using .captureStream()
, MediaRecorder()
and logs Blob URL
of resulting Blob
at dataavailable
event of MediaRecorder
instance.
At Firefox browser which currently implements .mozCaptureStream()
an error is thrown recorder.start()
call SecurityError: The operation is insecure.
and at recorder.stop()
call InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable
.
The errors are apparently due to Security Considerations of Media Capture from DOM Elements.
How can we avoid the errors described above and achieve same result which Chromium and Chrome browsers implement at Firefox browser?
You can use
XMLHttpRequest()
orfetch()
to getBlob
representation of media resource, create aBlob URL
fromBlob
usingURL.createObjectURL()
alternatively, we can record the media playback of
MediaSource()
set as.src
ofHTMLMediaElement
by appending anArrayBuffer
representation of media resource to theSourceBuffer
ofMediaSource
instanceWe could additionally use a helper function to use the same code at each Chromium, Chrome browser and Firefox browser, for example, see Answer at captureStream() on dynamically created video element.