Erste Schritte mit Mediengeräten

Bei der Entwicklung für das Web bietet der WebRTC-Standard APIs für den Zugriff auf Kameras und Mikrofone, die mit dem Computer oder Smartphone verbunden sind. Auf diesen Geräten werden allgemein als Mediengeräte bezeichnet und können über JavaScript aufgerufen werden. über das navigator.mediaDevices-Objekt, das die MediaDevices . Mit diesem Objekt können wir alle verbundenen Geräte aufzählen, Geräteänderungen (wenn ein Gerät verbunden oder nicht verbunden ist) und ein Gerät öffnen um einen Media-Stream abzurufen (siehe unten).

Am häufigsten wird dies über die Funktion getUserMedia() verwendet, gibt ein Promise zurück, das für die übereinstimmenden Medien in ein MediaStream-Objekt aufgelöst wird. Geräte. Diese Funktion verwendet ein einzelnes MediaStreamConstraints-Objekt, die Anforderungen, die wir haben. Um beispielsweise einfach die Standardmikrofon und Kamera verwenden, gehen wir so vor:

Promise-Objekte verwenden

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 verwenden

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);
}

Der Aufruf von getUserMedia() löst eine Berechtigungsanfrage aus. Wenn der Nutzer die Genehmigung akzeptiert, wird das Promise aufgelöst mit einem MediaStream, das einen Video- und einen Audiotrack. Wird die Berechtigung verweigert, wird ein PermissionDeniedError wird geworfen. Falls es keine passenden Geräte gibt verbunden ist, wird NotFoundError ausgegeben.

Die vollständige API-Referenz für die MediaDevices-Schnittstelle ist unter MDN web verfügbar. Dokumentation.

Mediengeräte abfragen

Bei einer komplexeren Anwendung werden wahrscheinlich alle angeschlossenen Kameras und Mikrofonen und geben dem Nutzer. Dazu muss die Funktion enumerateDevices() aufgerufen werden. Dadurch wird ein Promise zurückgeben, das in ein Array von MediaDevicesInfo aufgelöst wird, das jedes bekannte Mediengerät. Damit können wir dem Nutzer eine Benutzeroberfläche präsentieren, wählen Sie die gewünschte Option aus. Jede MediaDevicesInfo enthält eine Property namens kind mit dem Wert audioinput, audiooutput oder videoinput, der angibt, welche Art von Mediengerät es ist.

Promise-Objekte verwenden

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 verwenden

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);

Auf Geräteänderungen warten

Die meisten Computer unterstützen das Anschließen verschiedener Geräte während der Laufzeit. Es könnte sich um einen eine über ein USB-Kabel angeschlossene Webcam, ein Bluetooth-Headset oder mehrere externe Lautsprecher. In Um dies richtig zu unterstützen, sollte eine Webanwendung die Änderungen überwachen, von Mediengeräten. Fügen Sie dazu einen Listener navigator.mediaDevices für das Ereignis devicechange.

// 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);
});

Medieneinschränkungen

Das Einschränkungsobjekt, das die MediaStreamConstraints implementieren muss Schnittstelle, die als Parameter an getUserMedia() übergeben wird, Mediengerät, das eine bestimmte Anforderung erfüllt, Diese Anforderung kann sehr nicht definiert (Audio und/oder Video) oder sehr spezifisch (Mindestanzahl an Auflösung oder eine genaue Geräte-ID). Es wird empfohlen, Anwendungen, die prüft die getUserMedia() API zuerst die vorhandenen Geräte und legt dann eine , die mit der Einschränkung deviceId genau mit dem Gerät übereinstimmt. Geräte werden, wenn möglich, auch entsprechend den Einschränkungen konfiguriert. Mi. Sie können die Echounterdrückung der Mikrofone aktivieren oder eine bestimmte oder Mindestbreite einstellen. und Höhe des Videos von der Kamera.

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);
}

Die vollständige Dokumentation für die MediaStreamConstraints-Schnittstelle finden Sie im MDN Web Dokumentation.

Lokale Wiedergabe

Sobald ein Mediengerät geöffnet wurde und ein MediaStream verfügbar ist, ihn einem Video- oder Audioelement zuweisen, um den Stream lokal abzuspielen.

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);
    }
}

Der HTML-Code, der für ein typisches Videoelement mit getUserMedia() benötigt wird, haben normalerweise die Attribute autoplay und playsinline. Das autoplay werden neue Streams, die dem Element zugewiesen sind, automatisch abgespielt. Mit dem Attribut playsinline kann das Video inline statt vollständig wiedergegeben werden. in bestimmten mobilen Browsern angezeigt. Es wird außerdem empfohlen, controls="false" für Livestreams, es sei denn, der Nutzer sollte die Möglichkeit haben, das Streaming zu pausieren .

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