メディア デバイス スタートガイド

ウェブ向けに開発する場合、WebRTC 標準では、 パソコンやスマートフォンに接続されたカメラとマイクこれらのデバイスは 一般に「メディア デバイス」と呼ばれ、JavaScript でアクセスできます。 MediaDevices を実装する navigator.mediaDevices オブジェクトを使用 行うことができます。このオブジェクトから、接続されているすべてのデバイスを列挙し、 デバイスの変更(デバイスが接続または接続解除されている場合)、デバイスを開く を使用してメディア ストリームを取得できます(下記参照)。

最も一般的な使用方法は getUserMedia() 関数です。この関数は、 一致するメディアの MediaStream に解決される Promise を返します。 できます。この関数は、オブジェクトごとに MediaStreamConstraints の 要件を指定します。たとえば、 デフォルトのマイクとカメラの場合は、次のようにします。

Promise の使用

const constraints = {
    'video': true,
    'audio': true
}
navigator.mediaDevices.getUserMedia(constraints)
    .then(stream => {
        console.log('Got MediaStream:', stream);
    })
    .catch(error => {
        console.error('Error accessing media devices.', error);
    });

async/await の使用

const openMediaDevices = async (constraints) => {
    return await navigator.mediaDevices.getUserMedia(constraints);
}

try {
    const stream = openMediaDevices({'video':true,'audio':true});
    console.log('Got MediaStream:', stream);
} catch(error) {
    console.error('Error accessing media devices.', error);
}

getUserMedia() を呼び出すと、権限のリクエストがトリガーされます。ユーザーが 権限を受け入れると、Promise は次を含む MediaStream で解決されます。 1 つの動画と 1 つの音声トラックが必要です。権限が拒否されると、 PermissionDeniedError がスローされます。一致するデバイスがない場合 接続されると、NotFoundError がスローされます。

MediaDevices インターフェースの API リファレンスの全文は、MDN ウェブでご覧いただけます。 ドキュメントをご覧ください

メディア デバイスのクエリ

より複雑なアプリケーションでは、ほとんどの場合、すべての 適切にフィードバックできるように できます。これを行うには、enumerateDevices() 関数を呼び出します。これにより、 記述する MediaDevicesInfo の配列に解決される Promise を返します。 各既知のメディア デバイスが含まれます。これを使用してユーザーに UI を表示することで、 好みに合わせて選ぶとよいでしょう。各 MediaDevicesInfo には kind は、値 audioinputaudiooutput、または videoinput に置き換えます。 判断できるようにしました

Promise の使用

function getConnectedDevices(type, callback) {
    navigator.mediaDevices.enumerateDevices()
        .then(devices => {
            const filtered = devices.filter(device => device.kind === type);
            callback(filtered);
        });
}

getConnectedDevices('videoinput', cameras => console.log('Cameras found', cameras));

async/await の使用

async function getConnectedDevices(type) {
    const devices = await navigator.mediaDevices.enumerateDevices();
    return devices.filter(device => device.kind === type)
}

const videoCameras = getConnectedDevices('videoinput');
console.log('Cameras found:', videoCameras);

デバイスの変更をリッスンする

ほとんどのパソコンは、実行時にさまざまなデバイスの接続をサポートしています。たとえば USB で接続されたウェブカメラ、Bluetooth ヘッドセット、外部スピーカー セットのいずれか。イン これを適切にサポートするために、ウェブ アプリケーションで 提供しますそのためには、次のようにリスナーを追加します。 devicechange イベントの navigator.mediaDevices

// Updates the select element with the provided set of cameras
function updateCameraList(cameras) {
    const listElement = document.querySelector('select#availableCameras');
    listElement.innerHTML = '';
    cameras.map(camera => {
        const cameraOption = document.createElement('option');
        cameraOption.label = camera.label;
        cameraOption.value = camera.deviceId;
    }).forEach(cameraOption => listElement.add(cameraOption));
}

// Fetch an array of devices of a certain type
async function getConnectedDevices(type) {
    const devices = await navigator.mediaDevices.enumerateDevices();
    return devices.filter(device => device.kind === type)
}

// Get the initial set of cameras connected
const videoCameras = getConnectedDevices('videoinput');
updateCameraList(videoCameras);

// Listen for changes to media devices and update the list accordingly
navigator.mediaDevices.addEventListener('devicechange', event => {
    const newCameraList = getConnectedDevices('video');
    updateCameraList(newCameraList);
});

メディアの制約

MediaStreamConstraints を実装する必要がある制約オブジェクト このインターフェースを getUserMedia() にパラメータとして渡すことで、 特定の要件に適合するメディアデバイスですこの要件は非常に 漠然と定義されている(音声や動画)、または非常に具体的(カメラが最小限) 具体的なデバイス ID など)。使用するアプリケーションでは、 getUserMedia() API は、まず既存のデバイスを確認してから、 deviceId 制約を使用してデバイスと完全に一致する制約を作成します。 可能であれば、制約に従ってデバイスを設定します。水 マイクのエコー キャンセラを有効にしたり、特定または最小の幅を設定したりできます カメラで撮影した動画の高さなどです

async function getConnectedDevices(type) {
    const devices = await navigator.mediaDevices.enumerateDevices();
    return devices.filter(device => device.kind === type)
}

// Open camera with at least minWidth and minHeight capabilities
async function openCamera(cameraId, minWidth, minHeight) {
    const constraints = {
        'audio': {'echoCancellation': true},
        'video': {
            'deviceId': cameraId,
            'width': {'min': minWidth},
            'height': {'min': minHeight}
            }
        }

    return await navigator.mediaDevices.getUserMedia(constraints);
}

const cameras = getConnectedDevices('videoinput');
if (cameras && cameras.length > 0) {
    // Open first available video camera with a resolution of 1280x720 pixels
    const stream = openCamera(cameras[0].deviceId, 1280, 720);
}

MediaStreamConstraints インターフェースのドキュメントの全文については、こちらをご覧ください。 MDN ウェブ ドキュメントをご覧ください

ローカル再生

メディア デバイスを開いて MediaStream が使用可能になったら、 それを動画要素や音声要素に割り当てて、ストリームをローカルで再生できます。

async function playVideoFromCamera() {
    try {
        const constraints = {'video': true, 'audio': true};
        const stream = await navigator.mediaDevices.getUserMedia(constraints);
        const videoElement = document.querySelector('video#localVideo');
        videoElement.srcObject = stream;
    } catch(error) {
        console.error('Error opening video camera.', error);
    }
}

getUserMedia() で使用される一般的な動画要素に必要な HTML は、 通常は、属性 autoplayplaysinline があります。autoplay 属性を使用すると、その要素に割り当てられた新しいストリームが自動的に再生されます。 playsinline 属性を使用すると、動画をフルではなくインラインで再生できます。 画面に表示されます。また、kubectl の ライブ配信の場合は controls="false"(ユーザーが一時停止できる必要がある場合を除きます) できます。

<html>
<head><title>Local video playback</title></head>
<body>
    <video id="localVideo" autoplay playsinline controls="false"/>
</body>
</html>