Âm thanh web, chính sách tự động phát và trò chơi

Tom Greenaway
Hongchan Choi

Vào tháng 9 năm 2017, chúng tôi đã thông báo về một thay đổi sắp tới đối với cách xử lý âm thanh theo chính sách về hành vi tự động phát trong Chrome. Thay đổi về chính sách này được phát hành cùng với Chrome 66 phiên bản ổn định vào tháng 5 năm 2018.

Sau khi nhận được ý kiến phản hồi của cộng đồng phát triển Web Audio, chúng tôi đã trì hoãn việc phát hành phần Web Audio của chính sách tự động phát để nhà phát triển có thêm thời gian cập nhật trang web của họ. Chúng tôi cũng đã thực hiện một số thay đổi đối với việc triển khai chính sách về Âm thanh trên web. Điều này sẽ giúp giảm số lượng trang web cần điều chỉnh mã (đặc biệt là trò chơi trên web), nhờ đó mang đến trải nghiệm tốt hơn cho người dùng.

Thay đổi chính sách này dự kiến sẽ được triển khai cùng với Chrome 71 vào tháng 12 năm 2018.

Chính sách này thay đổi như thế nào?

Tự động phát là tên của một nội dung phát ngay khi trang web tải xong. Đối với những trang web dự kiến có thể tự động phát nội dung, thay đổi này sẽ ngăn việc phát theo mặc định. Trong hầu hết các trường hợp, quá trình phát sẽ tiếp tục, nhưng trong một số trường hợp khác, bạn cần điều chỉnh một chút mã. Cụ thể, nhà phát triển phải thêm mã để tiếp tục nội dung nếu người dùng tương tác với trang web.

Tuy nhiên, nếu người dùng truy cập vào một trang có nội dung tự động phát và họ chuyển đến trang đó từ một trang có cùng nguồn gốc, thì nội dung đó sẽ không bao giờ bị chặn. Hãy đọc bài đăng trước đó của chúng tôi trên blog về chính sách tự động phát để biết các ví dụ chi tiết hơn.

Ngoài ra, chúng tôi đã thêm một thuật toán phỏng đoán để tìm hiểu hành vi trước đây của người dùng liên quan đến các trang web tự động phát âm thanh. Chúng tôi phát hiện thời điểm người dùng thường xuyên để âm thanh phát trong hơn 7 giây trong hầu hết các lần họ truy cập vào một trang web và bật tính năng tự động phát cho trang web đó.

Chúng tôi thực hiện việc này bằng một chỉ mục được lưu trữ cục bộ cho mỗi hồ sơ Chrome trên một thiết bị. Chỉ mục này không được đồng bộ hoá giữa các thiết bị và chỉ được chia sẻ trong số liệu thống kê người dùng ẩn danh. Chúng tôi gọi chỉ mục này là Chỉ mục tương tác với nội dung nghe nhìn (MEI) và bạn có thể xem chỉ mục này thông qua chrome://media-engagement.

MEI theo dõi số lượt truy cập vào một trang web có bao nhiêu lượt phát âm thanh dài hơn 7 giây. Dựa trên MEI của người dùng, chúng tôi tin rằng có thể hiểu được liệu người dùng có mong đợi âm thanh từ một trang web cụ thể hay không và dự đoán ý định của người dùng trong tương lai.

Nếu người dùng thường cho phép miền của một trang web phát âm thanh trong hơn 7 giây, thì chúng tôi giả định rằng trong tương lai, người dùng sẽ mong đợi trang web này có quyền tự động phát âm thanh. Do đó, chúng tôi cấp cho trang web đó quyền tự động phát âm thanh mà không yêu cầu người dùng tương tác với một thẻ trên miền đó.

Tuy nhiên, quyền này không được đảm bảo vô thời hạn. Nếu hành vi của người dùng thay đổi (ví dụ: dừng phát âm thanh hoặc đóng thẻ trong ngưỡng 7 giây trong một vài lượt truy cập), thì chúng tôi sẽ xoá quyền tự động phát của trang web.

Cả việc sử dụng các phần tử HTML nội dung nghe nhìn (video và âm thanh) và Web Audio (đối tượng AudioContext được tạo bản sao bằng JavaScript) đều sẽ góp phần vào MEI. Để chuẩn bị cho việc triển khai chính sách này, hành vi của người dùng liên quan đến Web Audio sẽ bắt đầu đóng góp vào MEI từ Chrome 70 trở đi. Điều này sẽ đảm bảo chúng tôi có thể dự đoán ý định mong muốn của người dùng liên quan đến tính năng tự động phát và những trang web mà họ thường truy cập.

Xin lưu ý rằng iframe chỉ có thể có quyền tự động phát mà không cần người dùng tương tác nếu trang web gốc nhúng iframe mở rộng quyền đó cho iframe đã cho.

Chậm trễ thay đổi để hỗ trợ cộng đồng

Cộng đồng nhà phát triển Web Audio – đặc biệt là các nhà phát triển trò chơi trên web và nhà phát triển WebRTC trong cộng đồng này – đã chú ý khi thay đổi này xuất hiện trong kênh Chrome Stable.

Cộng đồng phản hồi rằng nhiều trò chơi trên web và trải nghiệm âm thanh trên web sẽ bị thay đổi này ảnh hưởng tiêu cực – cụ thể là nhiều trang web chưa được cập nhật sẽ không còn phát âm thanh cho người dùng. Do đó, nhóm chúng tôi quyết định nên trì hoãn thay đổi này để các nhà phát triển âm thanh trên web có thêm thời gian cập nhật trang web của họ.

Ngoài ra, chúng tôi cũng đã dành thời gian này để:

  • Hãy cân nhắc kỹ xem việc thay đổi chính sách này có phải là cách tốt nhất hay không.
  • Tìm hiểu các cách giúp giảm số lượng trang web có âm thanh bị ảnh hưởng.

Đối với trường hợp đầu tiên, cuối cùng chúng tôi quyết định rằng việc thay đổi chính sách là thực sự cần thiết để cải thiện trải nghiệm người dùng cho phần lớn người dùng. Bạn có thể đọc thêm thông tin chi tiết về vấn đề mà thay đổi về chính sách này sẽ giải quyết trong phần tiếp theo của bài viết này.

Đối với trường hợp thứ hai, chúng tôi đã điều chỉnh cách triển khai Web Audio để giảm số lượng trang web bị ảnh hưởng ban đầu. Trong số các trang web mà chúng tôi biết đã bị lỗi do thay đổi này (nhiều trang web trong số đó được cộng đồng phát triển trò chơi trên web cung cấp làm ví dụ), việc điều chỉnh này có nghĩa là hơn 80% trang web sẽ hoạt động tự động. Bạn có thể xem bài phân tích và thử nghiệm của chúng tôi về các trang web mẫu này tại đây. Bạn có thể xem thông tin chi tiết hơn về mức điều chỉnh mới này ở bên dưới.

Chúng tôi cũng đã thay đổi để hỗ trợ các ứng dụng WebRTC; trong khi có một phiên quay video đang hoạt động, tính năng tự động phát sẽ được cho phép.

Thay đổi hành vi này nhằm giải quyết vấn đề gì?

Trước đây, trình duyệt không hỗ trợ tốt người dùng quản lý âm thanh. Khi người dùng mở một trang web và nhận được âm thanh mà họ không mong muốn hoặc không muốn, họ sẽ có trải nghiệm người dùng không tốt. Trải nghiệm người dùng kém chính là vấn đề mà chúng tôi đang cố gắng giải quyết. Âm thanh không mong muốn là lý do chính khiến người dùng không muốn trình duyệt tự động phát nội dung.

Tuy nhiên, đôi khi người dùng muốn nội dung tự động phát và sau đó, người dùng sẽ phát một số lượng đáng kể nội dung tự động phát bị chặn trong Chrome.

Do đó, chúng tôi tin rằng bằng cách học hỏi từ người dùng và dự đoán ý định của họ trên mỗi trang web, chúng tôi có thể tạo ra trải nghiệm tốt nhất cho người dùng. Nếu người dùng thường để nội dung phát từ một trang web, thì chúng tôi sẽ tự động phát nội dung từ trang web đó trong tương lai. Ngược lại, nếu người dùng có xu hướng dừng nội dung tự động phát trên một trang web nhất định, thì theo mặc định, chúng tôi sẽ ngăn nội dung đó tự động phát.

Một đề xuất mà cộng đồng đưa ra là tắt tiếng của một thẻ thay vì tạm dừng chế độ tự động phát. Tuy nhiên, chúng tôi cho rằng tốt hơn hết là bạn nên tạm dừng trải nghiệm tự động phát để trang web biết rằng tính năng tự động phát đã bị chặn và cho phép nhà phát triển trang web phản ứng với điều này. Ví dụ: trong khi một số nhà phát triển chỉ muốn tắt tiếng, thì một số nhà phát triển khác lại muốn tạm dừng nội dung âm thanh cho đến khi người dùng chủ động tương tác với nội dung đó – nếu không, người dùng có thể bỏ lỡ một phần trải nghiệm âm thanh.

Các mức điều chỉnh mới giúp nhà phát triển trò chơi trên web

Cách phổ biến nhất để nhà phát triển sử dụng API Âm thanh trên web là tạo hai loại đối tượng để phát âm thanh:

Nhà phát triển âm thanh trên web sẽ tạo một AudioContext để phát âm thanh. Để tiếp tục phát âm thanh sau khi chính sách tự động phát tự động tạm ngưng AudioContext, họ cần gọi hàm resume() trên đối tượng này sau khi người dùng tương tác với thẻ:

    const context = new AudioContext();

    // Setup an audio graph with AudioNodes and schedule playback.
    ...

    // Resume AudioContext playback when user clicks a button on the page.
    document.querySelector('button').addEventListener('click', function() {
      context.resume().then(() => {
        console.log('AudioContext playback resumed successfully');
      });
    });

Có nhiều giao diện kế thừa từ AudioNode, một trong số đó là giao diện AudioScheduledSourceNode. Các AudioNode triển khai giao diện AudioScheduledSourceNode thường được gọi là nút nguồn (chẳng hạn như AudioBufferSourceNode, ConstantSourceNode và OscillatorNode). Các nút nguồn triển khai phương thức start().

Các nút nguồn thường đại diện cho các đoạn âm thanh riêng lẻ mà trò chơi phát, ví dụ: âm thanh phát ra khi người chơi thu thập tiền xu hoặc nhạc nền phát trong giai đoạn hiện tại. Các nhà phát triển trò chơi rất có thể sẽ gọi hàm start() trên các nút nguồn bất cứ khi nào cần bất kỳ âm thanh nào trong số này cho trò chơi.

Sau khi nhận ra mẫu phổ biến này trong các trò chơi trên web, chúng tôi quyết định điều chỉnh cách triển khai như sau:

AudioContext sẽ tự động tiếp tục khi đáp ứng hai điều kiện:

  • Người dùng đã tương tác với một trang.
  • Phương thức start() của nút nguồn được gọi.

Do thay đổi này, hầu hết các trò chơi trên web hiện sẽ tiếp tục phát âm thanh khi người dùng bắt đầu chơi trò chơi.

Đưa web phát triển lên phía trước

Để phát triển nền tảng web, đôi khi bạn cần thực hiện những thay đổi có thể làm mất khả năng tương thích. Rất tiếc, tính năng tự động phát âm thanh là một tính năng phức tạp và thuộc danh mục thay đổi này. Tuy nhiên, việc chuyển đổi này là rất quan trọng để đảm bảo rằng web không bị trì trệ hoặc mất đi lợi thế sáng tạo.

Tuy nhiên, chúng tôi nhận thấy rằng việc áp dụng các bản sửa lỗi cho trang web không phải lúc nào cũng khả thi trong ngắn hạn vì nhiều lý do:

  • Nhà phát triển web có thể tập trung vào một dự án mới và không thể bảo trì trang web cũ ngay lập tức.
  • Các cổng trò chơi trên web có thể không kiểm soát được việc triển khai trò chơi trong danh mục của họ và việc cập nhật hàng trăm, nếu không muốn nói là hàng nghìn trò chơi có thể tốn nhiều thời gian và chi phí cho nhà xuất bản.
  • Một số trang web có thể đã rất cũ và vì lý do nào đó không còn được duy trì nhưng vẫn được lưu trữ cho mục đích lưu trữ nội dung cũ.

Dưới đây là một đoạn mã JavaScript ngắn giúp chặn quá trình tạo các đối tượng AudioContext mới và sẽ tự động kích hoạt hàm tiếp tục của các đối tượng này khi người dùng thực hiện nhiều hoạt động tương tác. Bạn nên thực thi mã này trước khi tạo bất kỳ đối tượng AudioContext nào trong trang web của mình – ví dụ: bạn có thể thêm mã này vào thẻ của trang web:

(function () {
  // An array of all contexts to resume on the page
  const audioContextList = [];

  // An array of various user interaction events we should listen for
  const userInputEventNames = [
    'click',
    'contextmenu',
    'auxclick',
    'dblclick',
    'mousedown',
    'mouseup',
    'pointerup',
    'touchend',
    'keydown',
    'keyup',
  ];

  // A proxy object to intercept AudioContexts and
  // add them to the array for tracking and resuming later
  self.AudioContext = new Proxy(self.AudioContext, {
    construct(target, args) {
      const result = new target(...args);
      audioContextList.push(result);
      return result;
    },
  });

  // To resume all AudioContexts being tracked
  function resumeAllContexts(event) {
    let count = 0;

    audioContextList.forEach(context => {
      if (context.state !== 'running') {
        context.resume();
      } else {
        count++;
      }
    });

    // If all the AudioContexts have now resumed then we
    // unbind all the event listeners from the page to prevent
    // unnecessary resume attempts
    if (count == audioContextList.length) {
      userInputEventNames.forEach(eventName => {
        document.removeEventListener(eventName, resumeAllContexts);
      });
    }
  }

  // We bind the resume function for each user interaction
  // event on the page
  userInputEventNames.forEach(eventName => {
    document.addEventListener(eventName, resumeAllContexts);
  });
})();

Xin lưu ý rằng đoạn mã này sẽ không hỗ trợ việc tiếp tục các AudioContext được tạo bản sao trong một iframe, trừ phi đoạn mã này nằm trong phạm vi nội dung của chính iframe đó.

Phục vụ người dùng tốt hơn

Cùng với thay đổi về chính sách này, chúng tôi cũng sẽ ra mắt một cơ chế để người dùng có thể tắt chính sách tự động phát trong trường hợp công nghệ tự động học không hoạt động như mong đợi hoặc đối với những trang web không thể sử dụng được do thay đổi này. Thay đổi này sẽ được triển khai cùng với chính sách mới trong Chrome 71 và có thể được tìm thấy trong phần Cài đặt âm thanh; người dùng có thể thêm các trang web mà họ muốn cho phép tự động phát vào Danh sách cho phép.

MEI được tạo như thế nào cho người dùng mới?

Như đã đề cập trước đó, chúng tôi tự động tạo MEI theo thời gian dựa trên hành vi của người dùng để dự đoán ý định mà họ mong muốn đối với một trang web nhất định có nội dung tự động phát. Mỗi trang web có một điểm số từ 0 đến 1 trong chỉ mục này. Điểm số càng cao thì người dùng càng mong đợi nội dung phát từ trang web đó.

Tuy nhiên, đối với hồ sơ người dùng mới hoặc nếu người dùng xoá dữ liệu duyệt web của họ, thay vì chặn tính năng tự động phát ở mọi nơi, danh sách hạt giống trước dựa trên điểm MEI tổng hợp ẩn danh của người dùng sẽ được dùng để xác định những trang web có thể tự động phát. Dữ liệu này chỉ xác định trạng thái ban đầu của MEI khi tạo hồ sơ người dùng. Khi người dùng duyệt web và tương tác với các trang web có nội dung tự động phát, MEI cá nhân của họ sẽ ghi đè cấu hình mặc định.

Danh sách trang web được tạo sẵn được tạo bằng thuật toán thay vì được tuyển chọn thủ công và mọi trang web đều đủ điều kiện để được đưa vào danh sách này. Các trang web sẽ được thêm vào danh sách nếu có đủ số người dùng truy cập vào trang web đó cho phép tự động phát trên trang web đó. Ngưỡng này dựa trên tỷ lệ phần trăm để không ưu tiên các trang web lớn hơn.

Tìm sự cân bằng

Chúng tôi đã đăng tài liệu mới để cung cấp thêm thông tin chi tiết về quy trình ra quyết định và lý do thiết kế đằng sau chính sách này. Cũng như tài liệu mới về cách hoạt động của danh sách trang web được tạo sẵn.

Chúng tôi luôn đặt người dùng lên hàng đầu nhưng cũng không muốn làm cộng đồng phát triển web thất vọng. Đôi khi, việc trở thành trình duyệt có nghĩa là bạn phải cân bằng cẩn thận hai mục tiêu này. Chúng tôi tin rằng với những điều chỉnh đối với việc triển khai chính sách và thời gian bổ sung mà chúng tôi cung cấp cho các nhà phát triển âm thanh trên web để cập nhật mã, chúng tôi sẽ đạt được sự cân bằng này với Chrome 71.

Phản hồi