Google is committed to advancing racial equity for Black communities. See how.
Trang này được dịch bởi Cloud Translation API.
Switch to English

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

Khi phát triển cho web, tiêu chuẩn WebRTC cung cấp 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ị truyền thông và có thể được truy cập bằng JavaScript thông qua đối tượng navigator.mediaDevices , thực hiện 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ẽ giải quyết với MediaStream cho các thiết bị đa phương tiện phù hợp. Hàm này nhận một đối tượng MediaStreamConstraints chỉ đị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);
}
 

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

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

Truy vấn thiết bị đa 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 camera 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 giải quyết một mảng MediaDevicesInfo mô tả từng thiết bị đa phương tiện đã biết. Chúng ta có thể sử dụng điều này để trình bày một giao diện người dùng cho người dùng để họ chọn cái họ thích. Mỗi MediaDevicesInfo chứa một thuộc tính có tên kind với giá trị audioinput , đầu ra audiooutput hoặc videoinput , cho biết loại thiết bị đa phương tiện đó là gì.

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 thay đổi thiết bị

Hầu hết các máy tính đều hỗ trợ cắm vào các thiết bị khác nhau trong thời gian chạy. Đó có thể là webcam được kết nối bằng USB, tai nghe Bluetooth hoặc bộ loa ngoài. Để hỗ trợ chính xác điều này, một ứng dụng web nên lắng nghe những thay đổi của thiết bị đa phương tiện. Điều này có thể được thực hiện bằng cách thêm một trình lắng nghe vào navigator.mediaDevices cho sự kiện 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);
});
 

Hạn chế phương tiện truyền thông

Đối tượng ràng buộc, phải triển khai giao diện MediaStreamConstraints , mà chúng ta chuyển dưới dạng tham số cho getUserMedia() cho phép chúng ta mở một thiết bị đa 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 camera 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 một ràng buộc khớp với thiết bị chính xác bằng ràng buộc deviceId . Các thiết bị cũng sẽ, nếu có thể, được cấu hình theo các ràng buộc. Chúng tôi có thể cho phép loại bỏ tiếng vang 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ể được tìm thấy trên các tài liệu web MDN .

Phát lại cục bộ

Khi một thiết bị đa phương tiện đã được mở và chúng tôi có sẵn MediaStream , chúng tôi có thể gán thiết bị đó cho một thành phần video hoặc âm thanh để phát luồng 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 một thành phần 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ỉ ở toàn màn hình, trên một số trình duyệt di động nhất định. 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>