diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
commit | 33058f2b292b3a581333bdfb21b8f671898c5060 (patch) | |
tree | 51c3e392513ec574331b2d3f85c394445ea803c6 /files/ja/web/api/mediadevices | |
parent | 8b66d724f7caf0157093fb09cfec8fbd0c6ad50a (diff) | |
download | translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.gz translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.bz2 translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.zip |
initial commit
Diffstat (limited to 'files/ja/web/api/mediadevices')
-rw-r--r-- | files/ja/web/api/mediadevices/enumeratedevices/index.html | 174 | ||||
-rw-r--r-- | files/ja/web/api/mediadevices/getsupportedconstraints/index.html | 128 | ||||
-rw-r--r-- | files/ja/web/api/mediadevices/getusermedia/index.html | 353 | ||||
-rw-r--r-- | files/ja/web/api/mediadevices/index.html | 134 | ||||
-rw-r--r-- | files/ja/web/api/mediadevices/ondevicechange/index.html | 254 |
5 files changed, 1043 insertions, 0 deletions
diff --git a/files/ja/web/api/mediadevices/enumeratedevices/index.html b/files/ja/web/api/mediadevices/enumeratedevices/index.html new file mode 100644 index 0000000000..8ff19d3396 --- /dev/null +++ b/files/ja/web/api/mediadevices/enumeratedevices/index.html @@ -0,0 +1,174 @@ +--- +title: MediaDevices.enumerateDevices() +slug: Web/API/MediaDevices/enumerateDevices +tags: + - API + - Experimental + - MediaDevices + - Method +translation_of: Web/API/MediaDevices/enumerateDevices +--- +<p>{{APIRef("WebRTC")}}{{SeeCompatTable}}</p> + +<p><strong><code>MediaDevices.enumeratedDevices()</code></strong> メソッドは、システム上で利用できる入出力メディアデバイスの情報を収集します。</p> + +<h2 id="構文">構文</h2> + +<pre class="syntaxbox">navigator.mediaDevices.enumerateDevices();</pre> + +<h3 id="戻り値">戻り値</h3> + +<p>列挙が成功した場合、使用できる入出力メディアデバイスの情報を持つ<font face="Courier New">MediaDeviceInfo</font>オブジェクトの配列で満たされた{{ domxref("Promise") }} が返されます。</p> + +<p>次の情報が返されます。プライバシーへの配慮のため、コールした時に現在のページにアクティブな{{domxref("MediaStream")}} オブジェクトがあるか、ユーザーがページのオリジンに対して認可に対して許可を出していない限り、<font face="Courier New">label</font>情報は空文字です。</p> + +<p><code>MediaDeviceInfoは以下の情報を含みます。</code></p> + +<dl> + <dt><code>deviceId</code></dt> + <dd>deviceIdはセッション間で一貫性のあるデバイスを表現するための識別子である{{domxref("DOMString")}} です。これはほかのアプリケーションから推測できず、呼び出されたアプリケーションのオリジンごとにユニークです。ユーザーがcookieをクリアしたときにリセットされます(プライベートブラウジングのためには、セッション間で一貫性のない異なる識別子が使われます)。</dd> + <dt><code>groupId</code></dt> + <dd>groupIdはグループ識別子である{{domxref("DOMString")}} です。同じ物理デバイスに所属する場合、2つのデバイスは同じグループ識別子を持ちます。たとえば、組み込みのカメラとマイクの両方があるモニターです。</dd> + <dt><code>kind</code></dt> + <dd>kindは "<font face="Courier New">videoinput</font>"、"<font face="Courier New">audioinput</font>" か "<font face="Courier New">audiooutput</font>"のいづれかが列挙された値です。</dd> + <dt><code>label</code></dt> + <dd>labelはこのデバイスを表すラベルである {{domxref("DOMString")}} です(たとえば、"External USB Webcam)。MediaStreamがアクティブな間か認可が許可されているときだけ使用できます。</dd> +</dl> + +<h2 id="例">例</h2> + +<p><code>mediaDevices.enumerateDevices()</code>の使用例を示します。</p> + +<pre class="brush: js">if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) { + console.log("enumerateDevices() not supported."); + return; +} + +// List cameras and microphones. + +navigator.mediaDevices.enumerateDevices() +.then(function(devices) { + devices.forEach(function(device) { + console.log(device.kind + ": " + device.label + + " id = " + device.deviceId); + }); +}) +.catch(function(err) { + console.log(err.name + ": " + err.message); +}); +</pre> + +<p>実行例:<br> + <br> + <code>videoinput: id = csO9c0YpAf274OuCPUA53CNE0YHlIr2yXCi+SqfBZZ8=<br> + audioinput: id = RKxXByjnabbADGQNNZqLVLdmXlS0YkETYCIbg+XxnvM=<br> + audioinput: id = r2/xw1xUPIyZunfV1lGrKOma5wTOvCkWfZ368XCndm0=</code><br> + <br> + つ以上のMediaStreamがアクティブか、認可に対する許可がある場合:</p> + +<p><code>videoinput: FaceTime HD Camera (Built-in) id=csO9c0YpAf274OuCPUA53CNE0YHlIr2yXCi+SqfBZZ8=<br> + audioinput: default (Built-in Microphone) id=RKxXByjnabbADGQNNZqLVLdmXlS0YkETYCIbg+XxnvM=<br> + audioinput: Built-in Microphone id=r2/xw1xUPIyZunfV1lGrKOma5wTOvCkWfZ368XCndm0=</code></p> + +<h2 id="認可">認可</h2> + +<p>インストールできるアプリケーション(たとえば、 <a href="/ja/Apps/Build/Building_apps_for_Firefox_OS/Firefox_OS_app_beginners_tutorial"><u><font color="#0066cc">Firefox OS app</font></u></a>)で<font face="Courier New">enumerateDevices()</font> を使用するには、マニフェストファイルに1つまたは両方の次のフィールドを設定する必要があります。</p> + +<pre class="brush: js">"permissions": { + "audio-capture": { + "description": "Required to capture audio using getUserMedia()" + }, + "video-capture": { + "description": "Required to capture video using getUserMedia()" + } +}</pre> + +<p>さらなる情報は<a href="/ja/Apps/Developing/App_permissions#audio-capture">permission: audio-capture</a>と<a href="/ja/Apps/Developing/App_permissions#video-capture">permission: video-capture</a>を見てください。</p> + +<h2 id="仕様">仕様</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + <tr> + <td>{{SpecName('Media Capture', '#mediadevices', 'mediaDevices.enumerateDevices')}}</td> + <td>{{Spec2('Media Capture')}}</td> + <td>Initial definition.</td> + </tr> + </tbody> +</table> + +<h2 id="ブラウザ実装状況">ブラウザ実装状況</h2> + +<div>{{CompatibilityTable}}</div> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari (WebKit)</th> + </tr> + <tr> + <td>Stream API </td> + <td>{{CompatChrome(45.0)}} [1]</td> + <td>39</td> + <td>{{CompatNo}} </td> + <td> + <p>{{CompatNo}}</p> + </td> + <td>{{CompatNo}} </td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>Firefox OS (Gecko)</th> + <th>IE Phone</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Stream API </td> + <td>{{CompatNo}} </td> + <td>39</td> + <td>39</td> + <td>{{CompatNo}} </td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}} </td> + </tr> + </tbody> +</table> +</div> + +<p>[1] Behind a flag.</p> + +<h3 id="ChromeとOperaの実装">ChromeとOperaの実装</h3> + +<ul> + <li><a href="https://github.com/webrtc/adapter"><u><font color="#0066cc">adapter.js</font></u></a>のポリフィルを通して、ChromeとOperaでこのインターフェイスを使用できます。</li> +</ul> + +<h2 id="関連項目">関連項目</h2> + +<ul> + <li><a href="https://developer.mozilla.org/ja/docs/Web/API/MediaDevices/getUserMedia" title="mediaDevices.getUserMedia">navigator.mediaDevices.getUserMedia</a></li> + <li><a href="/en-US/docs/WebRTC" title="WebRTC">WebRTC</a> - APIの導入ページ</li> + <li><a href="/en-US/docs/WebRTC/MediaStream_API" title="WebRTC/MediaStream_API">MediaStream API</a> - media streamオブジェクトの導入ページ</li> + <li><a href="/en-US/docs/WebRTC/taking_webcam_photos" title="WebRTC/taking_webcam_photos">Taking webcam photos</a> - videoよりも写真を撮るために<code>getUserMedia()を使用するためのチュートリアル</code></li> +</ul> diff --git a/files/ja/web/api/mediadevices/getsupportedconstraints/index.html b/files/ja/web/api/mediadevices/getsupportedconstraints/index.html new file mode 100644 index 0000000000..973a177674 --- /dev/null +++ b/files/ja/web/api/mediadevices/getsupportedconstraints/index.html @@ -0,0 +1,128 @@ +--- +title: MediaDevices.getSupportedConstraints() +slug: Web/API/MediaDevices/getSupportedConstraints +translation_of: Web/API/MediaDevices/getSupportedConstraints +--- +<p>{{APIRef("Media Capture and Streams")}}</p> + +<p>{{domxref("MediaDevices")}} インタフェースの<code><strong>getSupportedConstraints</strong></code><strong><code>()</code></strong> メソッドは、{{domxref("MediaTrackSupportedConstraints")}}ディクショナリをベースとするオブジェクトを戻り値として返します。このオブジェクトのメンバーフィールドは、{{Glossary("user agent")}}が扱えるメディア制約に関するプロパティを表しています。</p> + +<h2 id="文法">文法</h2> + +<pre class="syntaxbox">var <em>supportedConstraints</em> = navigator.mediaDevices.getSupportedConstraints();</pre> + +<h3 id="パラメータ">パラメータ</h3> + +<p>なし。</p> + +<h3 id="戻り値">戻り値</h3> + +<p>{{domxref("MediaTrackSupportedConstraints")}}ディクショナリをベースにした新しいオブジェクトです。このオブジェクトはユーザエージェントが扱えるメディア制約の一覧を含みます。この一覧に含まれているものはユーザエージェントが取り扱えるものだけなので、全てのBoolean型のプロパティは<code>true</code>の値になっています。</p> + +<h2 id="Example" name="Example">例</h2> + +<p>この例は、実行中のブラウザでサポートされている制約の一覧を出力するものです。</p> + +<div class="hidden"> +<h3 id="HTML">HTML</h3> + +<pre class="brush: html"><p>あなたのブラウザは、以下のメディア制約をサポートしています。</p> + +<ul id="constraintList"> +</ul></pre> + +<h3 id="CSS">CSS</h3> + +<pre class="brush: css">body { + font: 15px Arial, sans-serif; +}</pre> + +<h3 id="JavaScript">JavaScript</h3> +</div> + +<pre class="brush: js">let constraintList = document.getElementById("constraintList"); +let supportedConstraints = navigator.mediaDevices.getSupportedConstraints(); + +for (let constraint in supportedConstraints) { + if (supportedConstraints.hasOwnProperty(constraint)) { + let elem = document.createElement("li"); + + elem.innerHTML = "<code>" + constraint + "</code>"; + constraintList.appendChild(elem); + } +}</pre> + +<h3 id="実行結果">実行結果</h3> + +<p>{{ EmbedLiveSample('Example', 600, 350) }}</p> + +<h2 id="仕様">仕様</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">仕様</th> + <th scope="col">状態</th> + <th scope="col">コメント</th> + </tr> + <tr> + <td>{{SpecName('Media Capture', '#widl-MediaDevices-getSupportedConstraints-MediaTrackSupportedConstraints', 'getSupportedConstraints()')}}</td> + <td>{{Spec2('Media Capture')}}</td> + <td>初版</td> + </tr> + </tbody> +</table> + +<h2 id="ブラウザ互換性">ブラウザ互換性</h2> + +<p>{{ CompatibilityTable }}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Microsoft Edge</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatChrome(53)}}</td> + <td>{{CompatGeckoDesktop(44) }}</td> + <td>{{CompatUnknown}}</td> + <td>{{ CompatUnknown }}</td> + <td>{{CompatOpera(40)}}</td> + <td>{{CompatSafari(11)}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android Webview</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatChrome(53)}}</td> + <td>{{CompatChrome(52)}}</td> + <td>{{ CompatGeckoMobile(50) }}</td> + <td>{{ CompatUnknown }}</td> + <td>{{CompatOperaMobile(40)}}</td> + <td>{{CompatSafari(11)}}</td> + </tr> + </tbody> +</table> +</div> diff --git a/files/ja/web/api/mediadevices/getusermedia/index.html b/files/ja/web/api/mediadevices/getusermedia/index.html new file mode 100644 index 0000000000..3e8870c01f --- /dev/null +++ b/files/ja/web/api/mediadevices/getusermedia/index.html @@ -0,0 +1,353 @@ +--- +title: MediaDevices.getUserMedia() +slug: Web/API/MediaDevices/getUserMedia +tags: + - API + - Audio + - Capture + - Media Capture and Streams API + - Media Streams API + - MediaDevices + - Method + - Photos + - Reference + - Video + - WebRTC + - getusermedia + - メソッド +translation_of: Web/API/MediaDevices/getUserMedia +--- +<div>{{APIRef("Media Capture and Streams")}}</div> + +<p>{{domxref("MediaDevices")}}<code><strong>.getUserMedia()</strong></code> メソッドは、要求された種類のメディアを含むトラックを持つ {{domxref("MediaStream")}} を生成するメディア入力を使用する許可をユーザーに求めます。このストリームには、例えば、動画トラック (カメラ、ビデオ録画機器、スクリーン共有サービスなどのような、ハードウェアまたは仮想ビデオソースによって生み出される)、音声トラック (同様に、マイク、A/D 変換器などの物理的または仮想オーディオソースによって生み出される)、その他の可能な種別を含めることができます。</p> + +<p>これは {{domxref("MediaStream")}} オブジェクトに解決する {{jsxref("Promise")}} を返します。ユーザーが拒否した場合や、一致するメディアが利用できない場合、 Promise はそれぞれ <code>NotAllowedError</code> または <code>NotFoundError</code> で拒否されます。</p> + +<div class="note"> +<p><strong>メモ:</strong> ユーザーが選択する必要が全くなく、リクエストを単純に無視できる場合、返却された Promise が解決または拒絶の<em>どちらにもならない</em>可能性があります。</p> +</div> + +<p>一般的に、 {{domxref("MediaDevices")}} のシングルトンオブジェクトは以下のように、 {{domxref("navigator.mediaDevices")}} を使用してアクセスします。</p> + +<pre class="brush: js notranslate">async function getMedia(constraints) { + let stream = null; + + try { + stream = await navigator.mediaDevices.getUserMedia(constraints); + /* ストリームを使用 */ + } catch(err) { + /* エラーを処理 */ + } +} +</pre> + +<p>同様に、生の Promise を直接使用すると、コードは次のようになります。</p> + +<pre class="brush: js notranslate">navigator.mediaDevices.getUserMedia(constraints) +.then(function(stream) { + /* ストリームを使用 */ +}) +.catch(function(err) { + /* エラーを処理 */ +});</pre> + +<div class="blockIndicator note"> +<p><strong>メモ:</strong> 現在の文書が安全に読み込まれなかった場合は、 <code>navigator.mediaDevices</code> は <code>undefined</code> になり、 <code>getUserMedia()</code> を使用することはできません。{{anch("Security", "セキュリティ")}}の節に、この件やその他の <code>getUserMedia()</code> の使用に関するセキュリティ問題の詳細があります。</p> +</div> + +<h2 id="Syntax" name="Syntax">構文</h2> + +<pre class="syntaxbox notranslate">var <var>promise</var> = navigator.mediaDevices.getUserMedia(<var>constraints</var>); +</pre> + +<h3 id="Parameters" name="Parameters">引数</h3> + +<dl> + <dt><code><var>constraints</var></code></dt> + <dd> + <p>{{domxref("MediaStreamConstraints")}} オブジェクトで、それぞれの種類のために何らかの要件に沿って要求するメディアの種類を指定します。</p> + + <p><code><var>constraints</var></code> 引数は <code>MediaStreamConstraints</code> であり、二つのメンバー <code>video</code> および <code>audio</code> を持ち、要求されたメディアの種類を記述します。どちらか、または両方を指定する必要があります。ブラウザーが指定された条件に合う指定されたタイプを持つすべてのメディアトラックを発見できない場合、返却された Promise は <code>NotFoundError</code> で拒否されます。</p> + + <p>次の例は特定の要件なしに audio と video の両方を要求します。</p> + + <pre class="brush: js notranslate">{ audio: true, video: true }</pre> + + <p>メディアの種類に <code>true</code> が指定された場合、結果のストリームはそのタイプのトラックが中にある<em>必要</em>があります。何らかの理由で含めることができない場合、 <code>getUserMedia()</code> の呼び出しはエラーが返ります。</p> + + <p>ユーザーのカメラやマイクについての情報は、プライバシー上の理由からアクセスできませんが、アプリケーションは追加の制約を使用することで、カメラやマイクの能力を必要に応じて要求することができます。次の例は、 1280x720 のカメラ解像度の設定を表しています。</p> + + <pre class="brush: js notranslate">{ + audio: true, + video: { width: 1280, height: 720 } +}</pre> + + <p id="successCallback">ブラウザーはこれに忠実であろうとしますが、正確に一致するものが使用できない場合や、ユーザーがこれをオーバーライドした場合は、異なる解像度を返すことがあります。</p> + + <p>機能を<em>必要</em>とするには、 <code>min</code>, <code>max</code>, <code>exact</code> (つまり <code>min == max</code>) の各キーワードが使用してください。次の例は 1280x720 の最小解像度を要求します。</p> + + <pre class="brush: js notranslate">{ + audio: true, + video: { + width: { min: 1280 }, + height: { min: 720 } + } +}</pre> + + <p>この解像度以上のカメラがない場合、返却された Promise は <code>OverconstrainedError</code> として拒否され、ユーザーには通知されません。</p> + + <p>動作に違いが発生する理由は、 <code>min</code>, <code>max</code>, <code>exact</code> の各キーワードが本質的に必須であるためです。それに対して <code>ideal</code> と呼ばれるプレーンな値とキーワードはそうではありません。より充実したサンプルを示します。</p> + + <pre class="brush: js notranslate">{ + audio: true, + video: { + width: { min: 1024, ideal: 1280, max: 1920 }, + height: { min: 776, ideal: 720, max: 1080 } + } +}</pre> + + <p><code>ideal</code> の値は、使用された場合は重みをもち、つまりブラウザーは ideal の値からみた<a href="https://w3c.github.io/mediacapture-main/#dfn-fitness-distance">最適距離</a>が最小になるような設定 (および、複数ある場合はカメラ) を見つけようとすることを意味します。</p> + + <p>プレインの値は本質的に ideal ですので、これは上記の解像度の例を以下のように書くこともできることを意味します。</p> + + <pre class="brush: js notranslate">{ + audio: true, + video: { + width: { ideal: 1280 }, + height: { ideal: 720 } + } +}</pre> + + <p>すべての constraint が数字とは限りません。例えば、次の例はリアカメラよりもフロントカメラを (利用できるなら) を選好します。</p> + + <pre class="brush: js notranslate">{ audio: true, video: { facingMode: "user" } }</pre> + + <p>リアカメラが<em>必要</em>であれば、次のようにします。</p> + + <pre class="brush: js notranslate">{ audio: true, video: { facingMode: { exact: "environment" } } }</pre> + + <p>他の数値以外の制約として、 <code>deviceId</code> の制約があります。 <code>deviceId</code> が {{domxref("mediaDevices.enumerateDevices()")}} から分かっているのであれば、これを使用して特定の機器を要求することができます。</p> + + <pre class="brush: js notranslate">{ video: { deviceId: myPreferredCameraDeviceId } }</pre> + + <p>上記のものは要求されたカメラを返しますが、特定したカメラが利用できない場合は別なカメラを返します。また、特定のカメラが<em>必要</em>なのであれば、以下のようにすることができます。</p> + + <pre class="brush: js notranslate">{ video: { deviceId: { exact: myExactCameraOrBustDeviceId } } }</pre> + </dd> +</dl> + +<h3 id="Return_value" name="Return_value">返値</h3> + +<p>要求されたメディアが正しく取得できたときに {{domxref("MediaStream")}} を受け取るハンドラーを示す {{jsxref("Promise")}} を返します。</p> + +<h3 id="Exceptions" name="Exceptions">例外</h3> + +<p>返却されたpromiseの拒否は {{ domxref("DOMException") }}に構成された{{ domxref("MediaStreamError") }}として生成されます。関連するエラーは以下の通りです。</p> + +<dl> + <dt><code>AbortError</code></dt> + <dd>デバイスへのアクセスはユーザとOSから許可され、かつ<code>NotReadableError</code>が生じるような問題も起きなかったが、デバイスを利用できない何らかの問題が発生した。</dd> + <dt><code>NotAllowedError</code></dt> + <dd>One or more of the requested source devices cannot be used at this time. This will happen if the browsing context is insecure (that is, the page was loaded using HTTP rather than HTTPS). It also happens if the user has specified that the current browsing instance is not permitted access to the device, the user has denied access for the current session, or the user has denied all access to user media devices globally. On browsers that support managing media permissions with <a href="/en-US/docs/Web/HTTP/Feature_Policy">Feature Policy</a>, this error is returned if Feature Policy is not configured to allow access to the input source(s). + <div class="note">Older versions of the specification used <code>SecurityError</code> for this instead; <code>SecurityError</code> has taken on a new meaning.</div> + </dd> + <dt><code>NotFoundError</code></dt> + <dd>constraint で指定された機能を満たすメディアトラックの種類が見つからない。</dd> + <dt><code>NotReadableError</code></dt> + <dd>Although the user granted permission to use the matching devices, a hardware error occurred at the operating system, browser, or Web page level which prevented access to the device.</dd> + <dt><code>OverconstrainedError</code></dt> + <dd>The specified constraints resulted in no candidate devices which met the criteria requested. The error is an object of type <code>OverconstrainedError</code>, and has a <code>constraint</code> property whose string value is the name of a constraint which was impossible to meet, and a <code>message</code> property containing a human-readable string explaining the problem. + <div class="note">Because this error can occur even when the user has not yet granted permission to use the underlying device, it can potentially be used as a fingerprinting surface.</div> + </dd> + <dt><code>SecurityError</code></dt> + <dd>User media support is disabled on the {{domxref("Document")}} on which <code>getUserMedia()</code> was called. The mechanism by which user media support is enabled and disabled is left up to the individual user agent.</dd> + <dt><code>TypeError</code></dt> + <dd>The list of constraints specified is empty, or has all constraints set to <code>false</code>. This can also happen if you try to call <code>getUserMedia()</code> in an insecure context, since {{domxref("navigator.mediaDevices")}} is <code>undefined</code> in an insecure context.</dd> +</dl> + +<h2 id="Privacy_and_security" name="Privacy_and_security">プライバシーとセキュリティ</h2> + +<p>As an API that may involve significant privacy concerns, <code>getUserMedia()</code>'s specification lays out a wide array of privacy and security requirements that browsers are obligated to meet.</p> + +<p><code>getUserMedia()</code> is a powerful feature which can only be used in <a href="/en-US/docs/Web/Security/Secure_Contexts">secure contexts</a>; in insecure contexts, <code>navigator.mediaDevices</code> is <code>undefined</code>, preventing access to <code>getUserMedia()</code>. A secure context is, in short, a page loaded using HTTPS or the <code>file:///</code> URL scheme, or a page loaded from <code>localhost</code>.</p> + +<p>In addition, user permission is always required to access the user's audio and video inputs. Only a window's top-level document context for a valid origin can even request permission to use <code>getUserMedia()</code>, unless the top-level context expressly grants permission for a given {{HTMLElement("iframe")}} to do so using <a href="/en-US/docs/Web/HTTP/Feature_Policy">Feature Policy</a>. Otherwise, the user will never even be asked for permission to use the input devices.</p> + +<p>For additional details on these requirements and rules, how they are reflected in the context in which your code is running, and about how browsers manage user privacy and security issues, read on.</p> + +<h3 id="User_privacy" name="User_privacy">ユーザーのプライバシー</h3> + +<p>As an API that may involve significant privacy concerns, <code>getUserMedia()</code> is held by the specification to very specific requirements for user notification and permission management. First, <code>getUserMedia()</code> must always get user permission before opening any media gathering input such as a webcam or microphone. Browsers may offer a once-per-domain permission feature, but they must ask at least the first time, and the user must specifically grant ongoing permission if they choose to do so.</p> + +<p>Of equal importance are the rules around notification. Browsers are required to display an indicator that shows that a camera or microphone is in use, above and beyond any hardware indicator that may exist. They must also show an indicator that permission has been granted to use a device for input, even if the device is not actively recording at the moment.</p> + +<p>For example in Firefox,<strong> </strong>the URL bar displays a pulsing red icon to indicate that recording is underway. The icon is gray if the permission is in place but recording is not currently underway. The device's physical light is used to indicate whether or not recording is currently active. If you've muted your camera (so-called "facemuting"), your camera's activity light goes out to indicate that the camera is not actively recording you, without discarding the permission to resume using the camera once muting is over.</p> + +<h3 id="Security">Security</h3> + +<p>There are a number of ways security management and controls in a {{Glossary("user agent")}} can cause <code>getUserMedia()</code> to return a security-related error.</p> + +<div class="blockIndicator note"> +<p><strong>Note:</strong> The security model for <code>getUserMedia()</code> is still somewhat in flux. The originally-designed security mechanism is in the process of being replaced with Feature Policy, so various browsers have different levels of security support, using different mechanisms. You should test your code carefully on a variety of devices and browsers to be sure it is as broadly compatible as possible</p> +</div> + +<h4 id="Feature_Policy">Feature Policy</h4> + +<p>The <a href="/en-US/docs/Web/HTTP/Feature_Policy">Feature Policy</a> security management feature of {{Glossary("HTTP")}} is in the process of being introduced into browsers, with support available to some extent in many browsers (though not always enabled by default, as in Firefox). <code>getUserMedia()</code> is one method which will require the use of Feature Policy, and your code needs to be prepared to deal with this. For example, you may need to use the {{htmlattrxref("allow", "iframe")}} attribute on any {{HTMLElement("iframe")}} that uses <code>getUserMedia()</code>, and pages that use <code>getUserMedia()</code> will eventually need to supply the {{HTTPHeader("Feature-Policy")}} header.</p> + +<p>The two permissions that apply to <code>getUserMedia()</code> are <code>camera</code> and <code>microphone</code>.</p> + +<p>For example, this line in the HTTP headers will enable use of a camera for the document and any embedded {{HTMLElement("iframe")}} elements that are loaded from the same origin:</p> + +<pre class="notranslate">Feature-Policy: camera 'self'</pre> + +<p>This will request access to the microphone for the current origin and the specific origin https://developer.mozilla.org:</p> + +<pre class="notranslate">Feature-Policy: microphone 'self' https://developer.mozilla.org</pre> + +<p>If you're using <code>getUserMedia()</code> within an <code><iframe></code>, you can request permission just for that frame, which is clearly more secure than requesting a more general permission. Here, indicate we need the ability to use both camera and microphone:</p> + +<pre class="brush: html notranslate"><iframe src="https://mycode.example.net/etc" allow="camera;microphone"> +</iframe></pre> + +<p>Read our guide, <a href="/en-US/docs/Web/HTTP/Feature_Policy/Using_Feature_Policy">Using Feature Policy</a>, to learn more about how it works.</p> + +<h4 id="Encryption_based_security">Encryption based security</h4> + +<p>The <code>getUserMedia()</code> method is only available in <a href="/en-US/docs/Web/Security/Secure_Contexts">secure contexts</a>. A secure context is one the browser is reasonably confident contains a document which was loaded securely, using HTTPS/TLS, and has limited exposure to insecure contexts. If a document isn't loaded in a secure context, the {{domxref("navigator.mediaDevices")}} property is <code>undefined</code>, making access to <code>getUserMedia()</code> impossible.</p> + +<p>Attempting to access <code>getUserMedia()</code> in this situation will result in a <code>TypeError</code>.</p> + +<h4 id="Document_source_security">Document source security</h4> + +<p>Because of the obvious security concern associated with <code>getUserMedia()</code> if used unexpectedly or without security being carefully managed, it can only be used in secure contexts. There are a number of insecure ways to load a document that might, in turn, attempt to call <code>getUserMedia()</code>. The following are examples of situations in which <code>getUserMedia()</code> is not permitted to be called:</p> + +<ul> + <li>A document loaded into a sandboxed {{HTMLElement("iframe")}} element cannot call <code>getUserMedia()</code> unless the <code><iframe></code> has its {{htmlattrxref("sandbox", "iframe")}} attribute set to <code>allow-same-origin</code>.</li> + <li>A document loaded using a <code>data://</code> or <code>blob://</code> URL which has no origin (such as when one of these URLs is typed by the user into the address bar) cannot call <code>getUserMedia()</code>. These kinds of URLs loaded from JavaScript code inherit the script's permissions.</li> + <li>Any other situation in which there is no origin, such as when the {{htmlattrxref("srcdoc", "iframe")}} attribute is used to specify the contents of a frame.</li> +</ul> + +<h2 id="Examples" name="Examples">例</h2> + +<h3 id="Width_and_height" name="Width_and_height">幅と高さ</h3> + +<p>この例ではカメラの解像度の設定を与えて、結果の {{domxref("MediaStream")}} オブジェクトを vide 要素に割り当てます。</p> + +<pre class="brush: js notranslate">// Prefer camera resolution nearest to 1280x720. +var constraints = { audio: true, video: { width: 1280, height: 720 } }; + +navigator.mediaDevices.getUserMedia(constraints) +.then(function(mediaStream) { + var video = document.querySelector('video'); + video.srcObject = mediaStream; + video.onloadedmetadata = function(e) { + video.play(); + }; +}) +.catch(function(err) { console.log(err.name + ": " + err.message); }); // always check for errors at the end. +</pre> + +<h3 id="Using_the_new_API_in_older_browsers" name="Using_the_new_API_in_older_browsers">古いブラウザーでの新しい API の使用</h3> + +<p>Here's an example of using <code>navigator.mediaDevices.getUserMedia()</code>, with a polyfill to cope with older browsers. Note that this polyfill does not correct for legacy differences in constraints syntax, which means constraints won't work well across browsers. It is recommended to use the <a href="https://github.com/webrtc/adapter">adapter.js</a> polyfill instead, which does handle constraints.</p> + +<pre class="brush: js notranslate">// Older browsers might not implement mediaDevices at all, so we set an empty object first +if (navigator.mediaDevices === undefined) { + navigator.mediaDevices = {}; +} + +// Some browsers partially implement mediaDevices. We can't just assign an object +// with getUserMedia as it would overwrite existing properties. +// Here, we will just add the getUserMedia property if it's missing. +if (navigator.mediaDevices.getUserMedia === undefined) { + navigator.mediaDevices.getUserMedia = function(constraints) { + + // First get ahold of the legacy getUserMedia, if present + var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia; + + // Some browsers just don't implement it - return a rejected promise with an error + // to keep a consistent interface + if (!getUserMedia) { + return Promise.reject(new Error('getUserMedia is not implemented in this browser')); + } + + // Otherwise, wrap the call to the old navigator.getUserMedia with a Promise + return new Promise(function(resolve, reject) { + getUserMedia.call(navigator, constraints, resolve, reject); + }); + } +} + +navigator.mediaDevices.getUserMedia({ audio: true, video: true }) +.then(function(stream) { + var video = document.querySelector('video'); + // Older browsers may not have srcObject + if ("srcObject" in video) { + video.srcObject = stream; + } else { + // Avoid using this in new browsers, as it is going away. + video.src = window.URL.createObjectURL(stream); + } + video.onloadedmetadata = function(e) { + video.play(); + }; +}) +.catch(function(err) { + console.log(err.name + ": " + err.message); +}); +</pre> + +<h3 id="Frame_rate" name="Frame_rate">フレームレート</h3> + +<p>帯域幅に制限のあるWebRTC通信のようなケースでは、低フレームレートが望ましいかもしれません。</p> + +<pre class="brush: js notranslate">var constraints = { video: { frameRate: { ideal: 10, max: 15 } } }; +</pre> + +<h3 id="Front_and_back_camera" name="Front_and_back_camera">フロントカメラとバックカメラ</h3> + +<p>携帯電話での例。</p> + +<pre class="brush: js notranslate">var front = false; +document.getElementById('flip-button').onclick = function() { front = !front; }; + +var constraints = { video: { facingMode: (front? "user" : "environment") } }; +</pre> + +<h2 id="Specifications" name="Specifications">仕様書</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">仕様書</th> + <th scope="col">状態</th> + <th scope="col">備考</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('Media Capture', '#dom-mediadevices-getusermedia', 'MediaDevices.getUserMedia()')}}</td> + <td>{{Spec2('Media Capture')}}</td> + <td>初回定義</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの互換性</h2> + +<div class="hidden">このページの互換性一覧表は構造化データから生成されています。データに協力していただけるのであれば、 <a class="external" href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> をチェックアウトしてプルリクエストを送信してください。</div> + +<p>{{Compat("api.MediaDevices.getUserMedia")}}</p> + +<h2 id="See_also" name="See_also">関連情報</h2> + +<ul> + <li>より古い {{domxref("navigator.getUserMedia()")}} API。</li> + <li>{{domxref("mediaDevices.enumerateDevices()")}}:利用可能なメディア機器を列挙</li> + <li><a href="/ja/docs/Web/API/WebRTC_API">WebRTC API</a></li> + <li><a href="/ja/docs/Web/API/Media_Streams_API">Media Capture and Streams API (メディアストリーム)</a></li> + <li><a href="/ja/docs/Web/API/Screen_Capture_API">Screen Capture API</a>: 画面の内容を {{domxref("MediaStream")}} としてキャプチャ</li> + <li>{{domxref("mediaDevices.getDisplayMedia()")}}: スクリーンの内容を含むストリームの取得</li> + <li><a href="/ja/docs/Web/API/WebRTC_API/Taking_still_photos">ウェブカメラでの写真撮影</a>: <code>getUserMedia()</code> を使用して動画ではなくスチル写真を撮る方法</li> +</ul> diff --git a/files/ja/web/api/mediadevices/index.html b/files/ja/web/api/mediadevices/index.html new file mode 100644 index 0000000000..60a9a07517 --- /dev/null +++ b/files/ja/web/api/mediadevices/index.html @@ -0,0 +1,134 @@ +--- +title: MediaDevices +slug: Web/API/MediaDevices +tags: + - API + - Audio + - Conference + - Devices + - Interface + - Media + - Media Capture and Streams API + - Media Streams API + - MediaDevices + - Reference + - Screen Capture + - Screen Capture API + - Sharing + - Video + - WebRTC + - インターフェイス + - メディアストリーム + - 画面キャプチャ +translation_of: Web/API/MediaDevices +--- +<div>{{APIRef("Media Capture and Streams")}}</div> + +<p><span class="seoSummary"><strong><code>MediaDevices</code></strong> インターフェイスは、カメラやマイク、さらに画面共有などの接続されたメディア入力デバイスへのアクセスを提供します。要するに、メディアデータのソースであるハードウェアにアクセスすることができるようになります。</span></p> + +<h2 id="Properties" name="Properties">プロパティ</h2> + +<p><em>親インターフェイスである {{domxref("EventTarget")}} のプロパティを継承しています。</em></p> + +<h2 id="Handlers" name="Handlers">イベント</h2> + +<dl> + <dt>{{domxref("MediaDevices/devicechange_event", "devicechange")}}</dt> + <dd>メディアの入力または出力機器がユーザーのコンピューターに接続されたり取り外されたりしたときに発生します。<br> + {{domxref("MediaDevices/ondevicechange", "ondevicechange")}} プロパティから利用することもできます。</dd> +</dl> + +<h2 id="Methods" name="Methods">メソッド</h2> + +<p><em>親インターフェイスである {{domxref("EventTarget")}} のメソッドを継承しています。</em></p> + +<dl> + <dt>{{ domxref("MediaDevices.enumerateDevices", "enumerateDevices()") }}</dt> + <dd>システム上で使用できる入出力メディアデバイスについての情報を持つ配列を取得します。</dd> + <dt>{{domxref("MediaDevices.getSupportedConstraints", "getSupportedConstraints()")}}</dt> + <dd>{{domxref("MediaTrackSupportedConstraints")}} に適合するオブジェクトを返します。このオブジェクトは {{domxref("MediaStreamTrack")}} インターフェイスで対応している制約可能なプロパティを表します。制約に関する詳細や使い方については、 {{SectionOnPage("/ja/docs/Web/API/Media_Streams_API", "Capabilities and constraints")}}を参照してください。</dd> + <dt>{{domxref("MediaDevices.getDisplayMedia", "getDisplayMedia()")}}</dt> + <dd>共有または録画の目的で {{domxref("MediaStream")}} としてキャプチャする、画面または画面の一部 (ウィンドウなど) をユーザーに選択させます。 <code>MediaStream</code> で解決する Promise を返します。</dd> + <dt>{{ domxref("MediaDevices.getUserMedia", "getUserMedia()") }}</dt> + <dd>ユーザーの許可に基づいて、システム上のカメラや画面共有機能、マイクを起動して、入力と共にビデオトラックやオーディオトラックを含む {{domxref("MediaStream")}} を提供します。</dd> +</dl> + +<h2 id="Example" name="Example">例</h2> + +<pre class="brush:js">'use strict'; + +// Put variables in global scope to make them available to the browser console. +var video = document.querySelector('video'); +var constraints = window.constraints = { + audio: false, + video: true +}; +var errorElement = document.querySelector('#errorMsg'); + +navigator.mediaDevices.getUserMedia(constraints) +.then(function(stream) { + var videoTracks = stream.getVideoTracks(); + console.log('Got stream with constraints:', constraints); + console.log('Using video device: ' + videoTracks[0].label); + stream.onremovetrack = function() { + console.log('Stream ended'); + }; + window.stream = stream; // make variable available to browser console + video.srcObject = stream; +}) +.catch(function(error) { + if (error.name === 'ConstraintNotSatisfiedError') { + errorMsg('The resolution ' + constraints.video.width.exact + 'x' + + constraints.video.width.exact + ' px is not supported by your device.'); + } else if (error.name === 'PermissionDeniedError') { + errorMsg('Permissions have not been granted to use your camera and ' + + 'microphone, you need to allow the page access to your devices in ' + + 'order for the demo to work.'); + } + errorMsg('getUserMedia error: ' + error.name, error); +}); + +function errorMsg(msg, error) { + errorElement.innerHTML += '<p>' + msg + '</p>'; + if (typeof error !== 'undefined') { + console.error(error); + } +}</pre> + +<h2 id="Specifications" name="Specifications">仕様書</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">仕様書</th> + <th scope="col">状態</th> + <th scope="col">備考</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('Media Capture', '#mediadevices', 'MediaDevices')}}</td> + <td>{{Spec2('Media Capture')}}</td> + <td>初回定義</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの互換性</h2> + +<div> +<div class="hidden">このページの互換性一覧表は構造化データから生成されています。データに協力していただけるのであれば、 <a class="external" href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> をチェックアウトしてプルリクエストを送信してください。</div> + +<p>{{Compat("api.MediaDevices")}}</p> +</div> + +<h2 id="See_also" name="See_also">関連情報</h2> + +<ul> + <li><a href="/ja/docs/Web/API/Media_Streams_API">Media Capture and Streams API</a>: このインターフェイスが所属する API。</li> + <li><a href="/ja/docs/Web/API/Screen_Capture_API">Screen Capture API</a>: {{domxref("MediaDevices.getDisplayMedia", "getDisplayMedia()")}} メソッドを定義している API。</li> + <li><a href="/ja/docs/Web/API/WebRTC_API">WebRTC API</a></li> + <li>{{domxref("Navigator.mediaDevices")}}: 機器にアクセスするために使用することができる <code>MediaDevices</code> への参照を返します。</li> + <li><a href="https://github.com/chrisjohndigital/CameraCaptureJS">CameraCaptureJS:</a> HTML5 による動画キャプチャおよび再生で、 <code>MediaDevices</code> および MediaStream Recording API を使用しています (<a href="https://github.com/chrisjohndigital/CameraCaptureJS">GitHub 上のソース</a>)</li> + <li><a href="https://github.com/chrisjohndigital/OpenLang">OpenLang</a>: HTML5 による動画言語研究ウェブアプリケーションで、 <code>MediaDevices</code> および MediaStream Recording API を録画に使用しています (<a href="https://github.com/chrisjohndigital/OpenLang">GitHub 上のソース</a>)。</li> +</ul> diff --git a/files/ja/web/api/mediadevices/ondevicechange/index.html b/files/ja/web/api/mediadevices/ondevicechange/index.html new file mode 100644 index 0000000000..73458872b0 --- /dev/null +++ b/files/ja/web/api/mediadevices/ondevicechange/index.html @@ -0,0 +1,254 @@ +--- +title: MediaDevices.ondevicechange +slug: Web/API/MediaDevices/ondevicechange +translation_of: Web/API/MediaDevices/ondevicechange +--- +<p>{{APIRef("Media Capture and Streams")}}</p> + +<p><span class="seoSummary"><strong><code>MediaDevices.ondevicechange</code></strong></span>プロパティは<span class="seoSummary">{{domxref("EventHandler")}}であり、{{domxref("MediaDevices")}}インスタンスで{{event("devicechange")}}が発生した時に呼び出される関数です。このイベントは、{{Glossary("user agent")}}、Webサイト、アプリケーションによって利用可能なメディアデバイスの一覧が変更された時に発生します。更新された利用可能デバイスの一覧は{{domxref("MediaDevices.enumerateDevices", "enumerateDevices()")}}によっていつでも取得することができます。</span></p> + +<h2 id="文法">文法</h2> + +<pre class="syntaxbox"><em>MediaDevices</em>.ondevicechange = <em>eventHandler</em>; +</pre> + +<h3 id="値">値</h3> + +<p>{{event("devicechange")}}イベントが発生したことを示す{{domxref("Event")}}オブジェクトを入力として受け付ける関数を指定してください。このイベントオブジェクトには、変更に関する情報が含まれていませんので、更新されたデバイスの一覧を取得したい場合は、{{domxref("MediaDevices.enumerateDevices", "enumerateDevices()")}}を呼び出してください。</p> + +<h2 id="Example" name="Example">例</h2> + +<p>この例では、<code>updateDeviceList()</code>という関数があり、この関数は{{domxref("MediaDevices.getUserMedia()")}}が成功して、ストリームを取得できた時に一度だけ呼び出され、その後デバイスの一覧に変更があった場合も複数回呼び出されます。この関数は、ブラウザウィンドウに2つの一覧を出力します。1つは、オーディオデバイスの一覧であり、もう1つはビデオデバイスの一覧です。これら2つのリストは、デバイスラベル (名前)とこのデバイスが入力か出力であるかを示すものです。この例では、{{event("devicechange")}}イベントのハンドラを設定しているので、実行中にデバイスが接続または接続を解除されるたびに一覧が更新されます。</p> + +<div class="hidden"> +<h3 id="HTML">HTML</h3> + +<pre class="brush: html"><p>Click the start button below to begin the demonstration.</p> +<div id="startButton" class="button"> + Start +</div> +<video id="video" width="160" height="120" autoplay></video><br> + +<div class="left"> + <h2>Audio devices:</h2> + <ul class="deviceList" id="audioList"></ul> +</div> +<div class="right"> + <h2>Video devices:</h2> + <ul class="deviceList" id="videoList"></ul> +</div> + +<div id="log"></div></pre> + +<h3 id="CSS">CSS</h3> + +<pre class="brush: css">body { + font: 14px "Open Sans", "Arial", sans-serif; +} + +video { + margin-top: 20px; + border: 1px solid black; +} + +.button { + cursor: pointer; + width: 160px; + border: 1px solid black; + font-size: 16px; + text-align: center; + padding-top: 2px; + padding-bottom: 4px; + color: white; + background-color: darkgreen; +} + +h2 { + margin-bottom: 4px; +} + +.left { + float:left; + width: 48%; + margin-right: 2% +} + +.right { + float:right; + width: 48%; + margin-left: 2% +} + +.deviceList { + border: 1px solid black; + list-style-type: none; + margin-top: 2px; + padding: 6px; +}</pre> + +<h3 id="JavaScript">JavaScript</h3> + +<h4 id="他のコード">他のコード</h4> + +<p>下のコードは、<code>ondevicechange</code>と直接関係がないため詳細を省きます。</p> + +<pre class="brush: js">let videoElement = document.getElementById("video"); +let logElement = document.getElementById("log"); + +function log(msg) { + logElement.innerHTML += msg + "<br>"; +} + +document.getElementById("startButton").addEventListener("click", function() { + navigator.mediaDevices.getUserMedia({ + video: { + width: 160, + height: 120, + frameRate: 30 + }, + audio: { + sampleRate: 44100, + sampleSize: 16, + volume: 0.25 + } + }).then(stream => { + videoElement.srcObject = stream; + updateDeviceList(); + }) + .catch(err => log(err.name + ": " + err.message)); +}, false);</pre> +</div> + +<p>オーディオとビデオデバイスの一覧に使用される{{HTMLElement("ul")}}要素への参照を保持するためのグローバル変数を用意します。</p> + +<pre class="brush: js">let audioList = document.getElementById("audioList"); +let videoList = document.getElementById("videoList");</pre> + +<h4 id="デバイス一覧_の取得と描画">デバイス一覧 の取得と描画</h4> + +<p><code>updateDeviceList()</code>メソッドでは、現在のメディアデバイスの一覧を取得した後、先ほど用意したグローバル変数を用いて、表示されているオーディオとビデオのデバイス一覧を更新します。</p> + +<pre class="brush: js">function updateDeviceList() { + navigator.mediaDevices.enumerateDevices() + .then(function(devices) { + audioList.innerHTML = ""; + videoList.innerHTML = ""; + + devices.forEach(function(device) { + let elem = document.createElement("li"); + let [kind, type, direction] = device.kind.match(/(\w+)(input|output)/i); + + elem.innerHTML = "<strong>" + device.label + "</strong> (" + direction + ")"; + if (type === "audio") { + audioList.appendChild(elem); + } else if (type === "video") { + videoList.appendChild(elem); + } + }); + }); +}</pre> + +<p><code>updateDeviceList()</code>は、{{domxref("navigator.mediaDevices")}}プロパティから参照できる{{domxref("MediaDevices")}}オブジェクトにある{{domxref("MediaDevices.enumerateDevices", "enumerateDevices()")}}関数の呼び出しから構成されます。コードが実行されるのは、<code>enumerateDevices()</code>によって返された{{jsxref("promise")}}が完了した時です。デバイス一覧の準備ができると、完了ハンドラが呼び出されます。このデバイス一覧は、完了ハンドラの引数として{{domxref("MediaDeviceInfo")}}オブジェクトの配列で渡されます。この配列のそれぞれの要素は、1つのメディア入力デバイスまたは出力デバイスについての情報を含みます。</p> + +<p>すべてのデバイスの情報を出力するために、{{jsxref("Array.forEach", "forEach()")}}ループを使用します。それぞれのデバイスで、ユーザへこのデバイス情報を見せるために新しい{{HTMLElement("li")}}オブジェクトを作成します。</p> + +<p><code>let [kind, type, direction] = device.kind.match(/(\w+)(input|output)/i);</code>の行について詳しく説明します。ここでは<a href="/ja/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">分割代入</a> (<a href="/en-US/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_6_support_in_Mozilla">ECMAScript 6</a>の新しい機能)を使用しており、{{jsxref("String.match()")}}によって返された配列の値を<code>kind</code>、<code>type</code>、<code>direction</code>の変数へ代入しています。なぜこのようなことをするのかというと、{{domxref("MediaDeviceInfo.kind")}}の文字列は、"audioinput"や"videooutput"のように、メディアタイプとメディアフローの向きの2つの情報を含んでいるためです。この行で、タイプ("audio"または"video")と方向("input"と"output")を取り出すことで、リストに表示する文字列を作成することができます。</p> + +<p>太字のデバイス名と括弧で囲まれた方向を含む文字列が作成されると、デバイスタイプに基づいて<code>audioList</code>または<code>videoList</code>対応する一覧へ{{domxref("Node.appendChild", "appendChild()")}}の呼び出しによって追加されます。</p> + +<h4 id="デバイス一覧の変更を扱う">デバイス一覧の変更を扱う</h4> + +<p><code>updateDeviceList()</code>は2箇所から呼び出されます。1箇所目は{{domxref("MediaDevices.getUserMedia", "getUserMedia()")}}のpromiseの完了ハンドラであり、ストリームが開かれた時に最初に一覧を埋めます。2箇所目は{{event("devicechange")}}のイベントハンドラからです。</p> + +<pre class="brush: js">navigator.mediaDevices.ondevicechange = function(event) { + updateDeviceList(); +}</pre> + +<p>このコードでは、ユーザがカメラ、マイク、他のメディアデバイスを接続したり、電源を入れたり、電源を切ったりする度に、<code>updateDeviceList()</code>を呼び出し接続されたデバイス一覧を再描画します。</p> + +<h3 id="結果">結果</h3> + +<p>{{ EmbedLiveSample('Example', 600, 460) }}</p> + +<h2 id="仕様">仕様</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">仕様</th> + <th scope="col">状況</th> + <th scope="col">コメント</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{ SpecName('Media Capture', '#dom-mediadevices-ondevicechange', 'ondevicechange') }}</td> + <td>{{ Spec2('Media Capture') }}</td> + <td>初版</td> + </tr> + </tbody> +</table> + +<h2 id="ブラウザ互換性">ブラウザ互換性</h2> + +<div>{{CompatibilityTable}}</div> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari (WebKit)</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatChrome(57)}}</td> + <td>{{CompatGeckoDesktop(51)}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatOpera(34)}}</td> + <td>{{CompatUnknown}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android Webview</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Phone</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatOperaMobile(34)}}</td> + <td>{{CompatUnknown}}</td> + </tr> + </tbody> +</table> +</div> + +<p>Support for this event was added for Linux and Windows—and it was enabled by default—starting in Firefox 52.</p> + +<p>[1] <code>devicechange</code>イベントと{{domxref("MediaDevices.ondevicechange")}}のサポートはFirefox 51からですが、ただしMacだけであり、デフォルトで無効になっています。有効にするには、<code>media.ondevicechange.enabled</code>を<code>true</code>に設定してください。Firefox 52から、LinuxとWindowsでサポートされており、デフォルトで有効になっています。</p> + +<h2 id="関連項目">関連項目</h2> + +<ul> + <li>The {{event("devicechange")}}イベントとその型である{{domxref("Event")}}</li> + <li>{{domxref("MediaDevices.enumerateDevices()")}}</li> + <li>{{domxref("MediaDeviceInfo")}}</li> +</ul> |