HTMLMediaElement.play() trả về lời hứa hẹn

Tự động phát âm thanh và video trên web là một tính năng mạnh mẽ và phải tuân thủ các quy định hạn chế khác nhau trên nhiều nền tảng. Ngày nay, hầu hết các trình duyệt dành cho máy tính sẽ luôn cho phép trang web bắt đầu phát <video> hoặc <audio> qua JavaScript mà không cần người dùng tương tác. Tuy nhiên, hầu hết các trình duyệt dành cho thiết bị di động đều yêu cầu một cử chỉ rõ ràng của người dùng trước khi có thể phát nội dung do JavaScript khởi tạo. Điều này giúp đảm bảo rằng người dùng thiết bị di động (nhiều người phải trả tiền cho băng thông hoặc những người có thể đang ở trong môi trường công cộng) không vô tình bắt đầu tải xuống và phát nội dung đa phương tiện khi không tương tác rõ ràng với trang.

Trước đây, rất khó để xác định xem có cần phải tương tác của người dùng để bắt đầu phát hay không, cũng như việc phát hiện lỗi xảy ra khi người dùng cố gắng phát (tự động) nhưng không thành công. Chúng tôi có nhiều giải pháp khác nhau, nhưng không phải là giải pháp lý tưởng. Đã có một điểm cải tiến đối với phương thức play() cơ bản để giải quyết tình trạng không chắc chắn này từ lâu và điều này hiện đã được áp dụng cho nền tảng web, với cách triển khai ban đầu trong Chrome 50.

Lệnh gọi play() trên phần tử <video> hoặc <audio> hiện trả về một Promise. Nếu phát thành công, Promise sẽ được thực hiện. Nếu phát không thành công, Promise sẽ bị từ chối cùng với thông báo lỗi giải thích lỗi đó. Điều này cho phép bạn viết mã trực quan như sau:

var playPromise = document.querySelector('video').play();

// In browsers that don’t yet support this functionality,
// playPromise won’t be defined.
if (playPromise !== undefined) {
    playPromise.then(function() {
    // Automatic playback started!
    }).catch(function(error) {
    // Automatic playback failed.
    // Show a UI element to let the user manually start playback.
    });
}

Ngoài việc phát hiện xem phương thức play() có thành công hay không, giao diện mới dựa trên Lời hứa còn cho phép bạn xác định thời điểm phương thức play() thành công. Có những bối cảnh mà trình duyệt web có thể quyết định trì hoãn thời điểm bắt đầu phát (ví dụ: Chrome dành cho máy tính sẽ không bắt đầu phát <video> cho đến khi thẻ xuất hiện). Promise sẽ không thực hiện được cho đến khi quá trình phát thực sự bắt đầu, nghĩa là mã bên trong then() sẽ không thực thi cho đến khi nội dung nghe nhìn đang phát. Các phương pháp trước đây để xác định xem play() có thành công hay không, chẳng hạn như chờ một khoảng thời gian nhất định cho sự kiện playing và giả định lỗi nếu sự kiện không kích hoạt, rất dễ có kết quả âm tính giả trong trường hợp phát lại bị trễ.

Chúng tôi đã phát hành ví dụ trực tiếp về chức năng mới này. Xem bản dựng này trong một trình duyệt như Chrome 50 có hỗ trợ giao diện dựa trên Promise này. Cảnh báo trước: trang sẽ tự động phát nhạc khi bạn truy cập trang đó. (Dĩ nhiên là trừ trường hợp không làm vậy!)

Vùng nguy hiểm

<source> trong <video> tạo ra play() lời hứa không bao giờ bị từ chối

Đối với <video src="not-existing-video.mp4"\>, lời hứa play() sẽ từ chối như mong đợi vì video không tồn tại. Đối với <video><source src="not-existing-video.mp4" type='video/mp4'></video>, lời hứa play() sẽ không bao giờ từ chối. Điều này chỉ xảy ra nếu không có nguồn hợp lệ.

Lỗi Chromium