Google is committed to advancing racial equity for Black communities. See how.
Ta strona została przetłumaczona przez Cloud Translation API.
Switch to English

Pierwsze kroki z urządzeniami multimedialnymi

W przypadku tworzenia aplikacji internetowych standard WebRTC zapewnia interfejsy API umożliwiające dostęp do kamer i mikrofonów podłączonych do komputera lub smartfona. Urządzenia te są powszechnie nazywane urządzeniami multimedialnymi i można uzyskać do nich dostęp za pomocą JavaScript za pośrednictwem obiektu navigator.mediaDevices , który implementuje interfejs MediaDevices . Z tego obiektu możemy wyliczyć wszystkie podłączone urządzenia, nasłuchiwać zmian urządzenia (gdy urządzenie jest podłączone lub odłączone) i otworzyć urządzenie w celu pobrania strumienia multimediów (patrz poniżej).

Najczęstszym sposobem jest to użycie funkcji getUserMedia() , która zwraca obietnicę, która zostanie rozwiązana do MediaStream dla pasujących urządzeń multimedialnych. Ta funkcja przyjmuje pojedynczy obiekt MediaStreamConstraints który określa wymagania, które mamy. Na przykład, aby po prostu otworzyć domyślny mikrofon i kamerę, wykonalibyśmy następujące czynności.

Korzystanie z obietnic

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

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

Wywołanie getUserMedia() wyzwoli żądanie uprawnień. Jeśli użytkownik zaakceptuje pozwolenie, obietnica zostanie rozwiązana za pomocą MediaStream zawierającego jedną ścieżkę wideo i jedną ścieżkę dźwiękową. W przypadku odmowy PermissionDeniedError jest błąd PermissionDeniedError . W przypadku, gdy nie ma podłączonych pasujących urządzeń, zostanie wyrzucony NotFoundError .

Pełne informacje o API dla interfejsu MediaDevices są dostępne w dokumentacji sieci Web MDN .

Zapytanie o urządzenia multimedialne

W bardziej złożonej aplikacji najprawdopodobniej będziemy chcieli sprawdzić wszystkie podłączone kamery i mikrofony i przekazać użytkownikowi odpowiednią informację zwrotną. Można to zrobić, wywołując funkcję enumerateDevices() . To zwróci obietnicę, która zostanie rozwiązana w postaci tablicy MediaDevicesInfo która opisuje każde znane urządzenie multimedialne. Możemy to wykorzystać, aby przedstawić użytkownikowi interfejs użytkownika, który pozwoli mu wybrać ten, który preferuje. Każdy MediaDevicesInfo zawiera właściwość o nazwie kind z wartością audioinput , audiooutput lub videoinput , wskazując, jaki rodzaj urządzenia multimedialnego jest.

Korzystanie z obietnic

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

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

Nasłuchiwanie zmian urządzeń

Większość komputerów obsługuje podłączanie różnych urządzeń w czasie działania. Może to być kamera internetowa podłączona przez USB, zestaw słuchawkowy Bluetooth lub zestaw głośników zewnętrznych. Aby poprawnie to obsługiwać, aplikacja internetowa powinna nasłuchiwać zmian urządzeń multimedialnych. Można to zrobić, dodając detektor do navigator.mediaDevices dla zdarzenia 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);
});
 

Ograniczenia dotyczące mediów

Obiekt constraints, który musi implementować interfejs MediaStreamConstraints , który przekazujemy jako parametr do getUserMedia() pozwala nam otworzyć urządzenie multimedialne, które spełnia określone wymagania. To wymaganie może być bardzo luźno zdefiniowane (dźwięk i / lub wideo) lub bardzo specyficzne (minimalna rozdzielczość kamery lub dokładny identyfikator urządzenia). Zaleca się, aby aplikacje korzystające z funkcji API getUserMedia() najpierw sprawdzały istniejące urządzenia, a następnie określały ograniczenie, które będzie deviceId do konkretnego urządzenia przy użyciu ograniczenia deviceId . Jeśli to możliwe, urządzenia będą również konfigurowane zgodnie z ograniczeniami. Możemy włączyć eliminację echa na mikrofonach lub ustawić określoną lub minimalną szerokość i wysokość wideo z kamery.

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

Pełną dokumentację interfejsu MediaStreamConstraints można znaleźć w dokumentacji sieci Web MDN .

Lokalne odtwarzanie

Po otwarciu urządzenia multimedialnego i udostępnieniu MediaStream możemy przypisać go do elementu wideo lub audio, aby odtwarzać strumień lokalnie.

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

Kod HTML potrzebny do typowego elementu wideo używanego z funkcją getUserMedia() będzie miał zazwyczaj atrybuty autoplay i playsinline . Atrybut autoplay spowoduje automatyczne odtworzenie nowych strumieni przypisanych do elementu. Atrybut playsinline umożliwia odtwarzanie wideo w playsinline zamiast tylko na pełnym ekranie w niektórych przeglądarkach mobilnych. Zaleca się również, aby w przypadku transmisji na żywo używać controls="false" , chyba że użytkownik powinien mieć możliwość ich wstrzymania.

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