web-dev-qa-db-ja.com

Navigator.mediaDevices.getUserMediaがiOS 12 Safariで機能しない

IOS 12現在、navigator.mediaDevices.getUserMedia()はSafariでエラーを返しています。

これを再作成するには、 iPhone Web Inspector を開き、コンソールで次のスニペットを実行します。

var constraints = { audio: true, video: { width: 1280, height: 720 } }; 

navigator.mediaDevices.getUserMedia(constraints)
  .then(function() {
    console.log('getUserMedia completed successfully.');
  })
  .catch(function(error) {
    console.log(error.name + ": " + error.message);
  });

これは、デスクトップブラウザーおよびiOS 11 Safariでは正常に実行されますが、iOS 12 Safariでは失敗することがわかります。

NotAllowedError:ユーザーが許可を拒否した可能性があるため、現在のコンテキストのユーザーエージェントまたはプラットフォームは要求を許可しません。

理由は何ですか?

注:これは、ユーザーがカメラにアクセスできるかどうかを尋ねる前に発生しており、ユーザーが許可を拒否したことが原因である可能性を排除しています。

10
Severisth

すぐにNotAllowedErrorになる理由は2つあります:

1. getUserMediaはhttpsを要求します

Safariは、iOSとOSXの両方で、カメラとマイクへのアクセスにhttpsを必要とするようです。

httpsリンク を使用すると、iOS Safari 12が機能します。 httpの同じリンクNotAllowedErrorを取得します。

Chromeにも同じ要件があります。これは、仕様のdirectionと一致します。これは、 最近getUserMediaをセキュリティで保護されたコンテキストに制限しています。まだ更新していないブラウザは、httpでnavigator.mediaDevicesを公開しますが、getUserMediaは常にNotAllowedErrorで拒否します。

将来的には、仕様に準拠するために、ブラウザがhttpでmediaDevicesを完全に削除することを期待しています。

2. getUserMediaには、クロスオリジンiframeの機能ポリシーが必要です。

これは、Safari 12で新しく表示されます。iframeでは、クロスオリジンコンテンツのgetUserMediaの機能ポリシーはデフォルトでオフになっています。

これは動作します 私にとって:

<iframe
  allow="camera;microphone"
  src="https://webrtc.github.io/samples/src/content/getusermedia/gum/">
</iframe>

これは機能しません

<iframe src="https://webrtc.github.io/samples/src/content/getusermedia/gum/">
</iframe>

...そしてNotAllowedErrorで失敗することに加えて、SafariはWebコンソールで警告します:

The top-level frame has prevented a document with a different security Origin to
call getUserMedia.

これは、 仕様 の最近の更新でもあります。

6
jib

getUserMediaを呼び出す前にこれらの3つの属性を設定すると、問題が解決しました。

    video.setAttribute('autoplay', '');
    video.setAttribute('muted', '');
    video.setAttribute('playsinline', '');

何らかの理由でvideo.setAttribute()は機能しますが、たとえばvideo.muted = ''のように値をビデオオブジェクトに直接割り当てようとするとしません。

また、video.play()を呼び出す必要はないようです。

video.srcObjectgetUserMediaによって返されたストリームに設定するだけでうまくいきました。

この 中程度の投稿 には、動作するデモとソースコードへのリンクがあります。

6
braitsch

私の特定の問題は12.01のバグでした。そのバージョンのすべてのデバイスに問題があり、それらを新しいバージョンに更新するとすぐに消えました。

0
Severisth