2017-09-18 5 views
-1

与えられたコードSecurityErrorを回避する方法:操作は安全ではありません。 Firefoxで.mozCaptureStreamとMediaRecorderを使用していますか?

<!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>

クロムブラウザはMediaRecorderインスタンスのdataavailableイベントでBlobを得られるの.captureStream()MediaRecorder()およびログBlob URLを用い<video>要素の再生を捕捉します。現在、エラーが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にされ.mozCaptureStream()を実装Firefoxブラウザで

エラーは、明らかにSecurity ConsiderationsMedia Capture from DOM Elementsに起因しています。

上記のエラーを回避し、ChromiumブラウザとChromeブラウザがFirefoxブラウザで実装するのと同じ結果を得るにはどうすればよいですか?

+0

実際はクロムバグのようですね!あなたのコードがスローされないようにするには、ビデオの 'crossOrigin'を' 'anonymous ''に設定する必要があります(FFは実際にはバグがあります)(https://bugzilla.mozilla.org/show_bug.cgi?id=1341016 )、しかし少なくとも、彼らは**安心です**)。また、 'mozCaptureStream'が' captureStream'と同じように動作することは期待できません。なぜなら、それはまだプレフィックスされているからです/ – Kaiido

+0

@Kaiido ChromiumまたはChromeではエラーはスローされません。 MediaRecorderを使用して作成された録音を連結するソリューションを探しながら、回避策を構成しました。 'crossOrigin'属性でもエラーなしにメディア再生を記録できる場合は、解答を投稿できますか? – guest271314

+0

FFにリンクされているFFのバグで述べたように、FFでは正しいCORSヘッダーを持つMediaElementが許可されないため、修正されていない限り回避策としては機能しません。しかし、私が言っているのは、これはクロムのセキュリティ上のバグだということです(私はすぐにそれを放棄しています)。彼らはCORSヘッダーなしで配信されるmediaElementでcaptureStreamを呼び出さないでください。これは他のCORSのセキュリティ対策(webAudioやcanvas APIなど)とは異なります。したがって、mediaElementに 'cross-origin'属性を設定する必要があります。 – Kaiido

答えて

0

あなたは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>

代わりに使用してBlobからBlob URLを作成し、メディアリソースのBlob表現を取得するためにXMLHttpRequest()またはfetch()を使用することができ、我々はMediaSource()セットのメディア再生などを記録することができますメディアリソースのArrayBuffer表現をに付加することによってHTMLMediaElementの我々はさらに、例えば、それぞれクロム、ChromeブラウザとFirefoxブラウザで同じコードを使用するヘルパー関数を使用することができる

<!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>

インスタンスMediaSourceと、captureStream() on dynamically created video elementAnswer参照。

関連する問題