Google cam kết thúc đẩy công bằng chủng tộc cho Cộng đồng người da đen. Xem cách thực hiện.
Trang này được dịch bởi Cloud Translation API.
Switch to English

Bắt đầu với các thiết bị phương tiện

Khi phát triển cho web, tiêu chuẩn WebRTC cung cấp các API để truy cập máy ảnh và micrô được kết nối với máy tính hoặc điện thoại thông minh. Các thiết bị này thường được gọi là Thiết bị Phương tiện và có thể được truy cập bằng JavaScript thông qua đối tượng navigator.mediaDevices , đối tượng này triển khai giao diện MediaDevices . Từ đối tượng này, chúng ta có thể liệt kê tất cả các thiết bị được kết nối, lắng nghe các thay đổi của thiết bị (khi thiết bị được kết nối hoặc ngắt kết nối) và mở một thiết bị để truy xuất Media Stream (xem bên dưới).

Cách phổ biến nhất được sử dụng là thông qua hàm getUserMedia() , trả về một lời hứa sẽ phân giải thành MediaStream cho các thiết bị phương tiện phù hợp. Hàm này nhận một đối tượng MediaStreamConstraints xác định các yêu cầu mà chúng ta có. Ví dụ, để chỉ cần mở micrô và máy ảnh mặc định, chúng tôi sẽ làm như sau.

Sử dụng lời hứa

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

Sử dụng 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);
}

Lệnh gọi tới getUserMedia() sẽ kích hoạt một yêu cầu quyền. Nếu người dùng chấp nhận quyền, lời hứa sẽ được giải quyết bằng MediaStream chứa một video và một bản âm thanh. Nếu quyền bị từ chối, PermissionDeniedError sẽ được đưa ra. Trong trường hợp không có thiết bị phù hợp nào được kết nối, NotFoundError sẽ được đưa ra.

Tham chiếu API đầy đủ cho giao diện MediaDevices hiện có tại tài liệu web MDN .

Truy vấn thiết bị phương tiện

Trong một ứng dụng phức tạp hơn, rất có thể chúng tôi sẽ muốn kiểm tra tất cả các máy ảnh và micrô được kết nối và cung cấp phản hồi thích hợp cho người dùng. Điều này có thể được thực hiện bằng cách gọi hàm enumerateDevices() . Điều này sẽ trả về một lời hứa phân giải thành một mảng MediaDevicesInfo mô tả từng thiết bị phương tiện đã biết. Chúng tôi có thể sử dụng điều này để giới thiệu giao diện người dùng cho người dùng để họ chọn giao diện người dùng họ thích. Mỗi MediaDevicesInfo chứa một thuộc tính được đặt tên là kind với giá trị audioinput , audiooutput hoặc videoinput , cho biết đó là loại thiết bị media nào.

Sử dụng lời hứa

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

Sử dụng 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);

Lắng nghe các thay đổi của thiết bị

Hầu hết các máy tính đều hỗ trợ cắm nhiều thiết bị khác nhau trong thời gian chạy. Đó có thể là một webcam kết nối bằng USB, tai nghe Bluetooth hoặc một bộ loa ngoài. Để hỗ trợ đúng cách này, ứng dụng web phải lắng nghe những thay đổi của thiết bị phương tiện. Điều này có thể được thực hiện bằng cách thêm một người biết lắng nghe để navigator.mediaDevices cho devicechange sự kiện.

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

Ràng buộc về phương tiện

Đối tượng ràng buộc, phải triển khai giao diện MediaStreamConstraints , mà chúng ta truyền dưới dạng tham số cho getUserMedia() cho phép chúng ta mở một thiết bị phương tiện phù hợp với một yêu cầu nhất định. Yêu cầu này có thể được xác định rất lỏng lẻo (âm thanh và / hoặc video), hoặc rất cụ thể (độ phân giải máy ảnh tối thiểu hoặc ID thiết bị chính xác). Trước tiên, các ứng dụng sử dụng API getUserMedia() kiểm tra các thiết bị hiện có và sau đó chỉ định ràng buộc khớp với thiết bị chính xác bằng cách sử dụng ràng buộc deviceId . Các thiết bị cũng sẽ được cấu hình theo các ràng buộc nếu có thể. Chúng tôi có thể bật tính năng khử tiếng vọng trên micrô hoặc đặt chiều rộng và chiều cao cụ thể hoặc tối thiểu của video từ máy ảnh.

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

Tài liệu đầy đủ cho giao diện MediaStreamConstraints có thể tìm thấy trên tài liệu web MDN .

Phát lại cục bộ

Sau khi một thiết bị media đã được mở và chúng tôi có sẵn MediaStream , chúng tôi có thể gán nó cho một phần tử video hoặc âm thanh để phát trực tiếp cục bộ.

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 cần thiết cho phần tử video điển hình được sử dụng với getUserMedia() thường sẽ có các thuộc tính autoplayplaysinline . Thuộc tính autoplay sẽ khiến các luồng mới được gán cho phần tử tự động phát. Thuộc tính playsinline cho phép video phát nội tuyến, thay vì chỉ ở chế độ toàn màn hình, trên một số trình duyệt dành cho thiết bị di động. Bạn cũng nên sử dụng controls="false" cho các luồng trực tiếp, trừ khi người dùng có thể tạm dừng chúng.

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