给出代码
<!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浏览器使用<video>
,.captureStream()
捕获MediaRecorder()
元素的回放,并在Blob URL
Blob
事件dataavailable
处生成MediaRecorder
{1}}实例。
在当前实施.mozCaptureStream()
的Firefox浏览器中,recorder.start()
调用SecurityError: The operation is insecure.
和recorder.stop()
调用InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable
时会抛出错误。
错误显然是Security Considerations的Media Capture from DOM Elements造成的。
我们如何避免上述错误并获得Chromium和Chrome浏览器在Firefox浏览器中实现的相同结果?
答案 0 :(得分:0)
您可以使用XMLHttpRequest()
或fetch()
获取媒体资源的Blob
代表,使用Blob URL
从Blob
创建URL.createObjectURL()
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<video width="320" height="280"></video>
<script>
(async() => {
const video = document.querySelector("video");
const src = "https://mirrors.creativecommons.org/movingimages/webm/ScienceCommonsJesseDylan_240p.webm#t=0,10";
const url = new URL(src);
let recorder;
video.oncanplay = () => {
// note, audio is not output here
video.play();
const mediaStream = video.mozCaptureStream();
recorder = new MediaRecorder(mediaStream);
recorder.ondataavailable = event =>
// audio is output at resulting `Blob URL`
console.log(URL.createObjectURL(event.data));
recorder.start();
}
video.onpause = () => recorder && recorder.stop();
const blob = await fetch(url).then(response => response.blob());
video.src = URL.createObjectURL(blob) + url.hash;
})();
</script>
</body>
</html>
或者,我们可以通过将MediaSource()
媒体资源的.src
表示附加到HTMLMediaElement
,将ArrayBuffer
的媒体播放设置为SourceBuffer
MediaSource
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<video width="320" height="280"></video>
<script>
(async() => {
// SecurityError: The operation is insecure.
// InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable
const video = document.querySelector("video");
const src = "https://mirrors.creativecommons.org/movingimages/webm/ScienceCommonsJesseDylan_240p.webm#t=0,10";
const url = new URL(src);
const mediaSource = new MediaSource();
const mimeCodec = "video/webm;codecs=opus";
video.src = URL.createObjectURL(mediaSource);
mediaSource.onsourceopen = async() => {
const sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
const mediaBuffer = await fetch(url).then(response => response.arrayBuffer());
sourceBuffer.appendBuffer(mediaBuffer);
}
let recorder;
video.oncanplay = () => {
// note, audio is not output here
video.play();
const mediaStream = video.mozCaptureStream();
recorder = new MediaRecorder(mediaStream);
recorder.ondataavailable = event =>
// audio is output at resulting `Blob URL`
console.log(URL.createObjectURL(event.data));
recorder.start();
}
video.ontimeupdate = () => {
if (Math.floor(video.currentTime) === Number(url.hash.split(",").pop())) {
video.ontimeupdate = null;
video.pause();
mediaSource.endOfStream();
}
}
video.onpause = () => recorder && recorder.stop();
})();
</script>
</body>
</html>
实例
X Y
0.99 0.56 //line 1
0.32 -0.23 //line 2
我们还可以使用辅助函数在每个Chromium,Chrome浏览器和Firefox浏览器中使用相同的代码,例如,请参阅Answer上的captureStream() on dynamically created video element。