谷歌致力於推進種族平等的黑人社區。 怎麼看。
本頁面由 Cloud Translation API 翻譯而成。
Switch to English

入門媒體設備

當幅材顯影,所述的WebRTC標準提供用於訪問連接到計算機或智能電話攝像機和麥克風的API。這些裝置通常被稱為媒體設備和可以用JavaScript通過訪問navigator.mediaDevices對象,它實現了MediaDevices接口。從這個對象,我們可以枚舉所有連接的設備,監聽設備的變化(當設備連接或斷開),並打開設備來獲取媒體流(見下文)。

這是最常用的方法是通過函數getUserMedia()它返回將解析為一個承諾MediaStream用於匹配的媒體設備。這個函數有一個MediaStreamConstraints對象,它指定的要求,我們有。例如,簡單地打開默認的麥克風和攝像頭,我們可以做到以下幾點。

使用承諾

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

使用異步/ 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()將觸發權限請求。如果用戶接受許可,承諾與解決MediaStream包含一個視頻和一個音頻軌道。如果權限被拒絕,一個PermissionDeniedError被拋出。如果沒有匹配的設備連接時, NotFoundError將被拋出。

對於完整的API參考MediaDevices接口可在MDN網頁文檔

查詢媒體設備

在更複雜的應用程序,我們將最有可能要全部檢查連接的攝像機和麥克風,並提供給用戶適當的反饋。這可以通過調用函數來完成enumerateDevices()這將返回一個承諾解析為陣列MediaDevicesInfo描述每個已知的媒體設備。我們可以用它來呈現用戶界面,這讓他們選擇他們喜歡的一個用戶。每個MediaDevicesInfo包含一個名為屬性kind與價值audioinputaudiooutputvideoinput ,說明它是什麼類型的媒體設備。

使用承諾

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

使用異步/ 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,藍牙耳機或一組外部揚聲器連接一個攝像頭。為了正確地支持這一點,一個Web應用程序應該監聽的媒體設備的變化。這可以通過添加一個監聽器,來完成navigator.mediaDevicesdevicechange事件。

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

需要與所使用的典型的視頻元素的HTML getUserMedia()通常具有的屬性autoplayplaysinline 。該autoplay屬性將導致分配給該元素為自動播放的新流。該playsinline屬性允許視頻在線播放,而不是只能在全屏,某些移動瀏覽器。此外,還建議在使用controls="false"的直播流,除非用戶應該能夠暫停。

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