Â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ề thay đổi sắp tới về cách xử lý âm thanh bằng chính sách hành vi tự động phát trong Chrome. Chúng tôi đã phát hành sự thay đổi này về chính sách đối với Bản ổn định của Chrome 66 vào tháng 5 năm 2018.

Sau khi cộng đồng phát triển Âm thanh web phản hồi, chúng tôi đã hoãn phát hành phần Âm thanh trên web trong 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 dành cho Âm thanh trên web. Theo đó, số lượng trang web cần điều chỉnh mã (đặc biệt là trò chơi trên web) sẽ giảm thiểu số lượng trang web cần điều chỉnh mã, từ đó mang lại trải nghiệm tốt hơn cho người dùng.

Thay đổi về 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 xác thì thay đổi chính sách có tác dụng gì?

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

Tuy nhiên, nếu người dùng đến 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. Đọc bài đăng trước trên blog của chúng tôi về chính sách tự động phát để biết ví dụ chi tiết hơn.

Ngoài ra, chúng tôi đã thêm phương pháp suy nghiệm để tìm hiểu từ 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 phát âm thanh lâu hơn 7 giây trong hầu hết những 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ộ theo hồ sơ Chrome trên 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ê ẩn danh về người dùng. Chúng tôi gọi chỉ mục này là Chỉ số tương tác truyền thông (MEI) và bạn có thể xem chỉ số này thông qua chrome://media-engagement.

MEI theo dõi số lượt truy cập vào một trang web, bao gồm cả việc 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 chúng ta có thể hiểu được liệu người dùng có muốn nhận âm thanh từ một trang web cụ thể hay không, đồng thời dự đoán ý định của người dùng trong tương lai.

Nếu người dùng thường để miền của một trang web phát âm thanh trong hơn 7 giây, thì chúng tôi sẽ giả định trong tương lai rằng người dùng muốn 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 phải tương tác với thẻ trong 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 chuyển đổi (ví dụ: dừng phát âm thanh hoặc đóng thẻ trong phạm vi 7 giây trong nhiều 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 phần tử HTML của nội dung đa phương tiện (video và âm thanh) và Âm thanh web (đối tượng AudioContext dựa trên JavaScript) đều sẽ đóng góp 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 âm thanh trên web sẽ bắt đầu đóng góp vào MEI từ Chrome 70 trở đi. Điều này sẽ đảm bảo rằng chúng tôi có thể dự đoán được ý định mong muốn của người dùng đối với tính năng tự động phát và các 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 sự tương tác của người dùng nếu trang web gốc nhúng iframe mở rộng quyền đó đến iframe nhất định.

Trì hoãn thay đổi để hỗ trợ cộng đồng

Cộng đồng nhà phát triển Web âm thanh – đặc biệt là nhà phát triển trò chơi web và phần nhà phát triển WebRTC của cộng đồng này – đã chú ý đến thời điểm thay đổi này xuất hiện trên Kênh chính thức của Chrome.

Ý kiến phản hồi của cộng đồng cho biết thay đổi này sẽ ảnh hưởng tiêu cực đến nhiều trò chơi trên web và trải nghiệm âm thanh trên web, cụ thể là nhiều trang web không được cập nhật sẽ không phát âm thanh cho người dùng được nữa. Do đó, nhóm chúng tôi quyết định tạm 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 đã dành thời gian này để:

  • Hãy nghiêm túc cân nhắc xem thay đổi này có phải là hành động tốt nhất hay không.
  • Khám phá các cách chúng tôi có thể giúp giảm số lượng trang web có nội dung âm thanh sẽ bị ảnh hưởng.

Trước đây, cuối cùng chúng tôi quyết định rằng thay đổi về chính sách 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 về vấn đề mà thay đổi chính sách này đang giải quyết trong phần tiếp theo của bài viết này.

Về sau, chúng tôi đã thực hiện điều chỉnh đối với việc triển khai Âm thanh web để 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 là bị hỏng 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 đưa ra làm ví dụ), thì sự điều chỉnh này có nghĩa là hơn 80% trong số đó sẽ tự động hoạt động. Bạn có thể xem phân tích và thử nghiệm của chúng tôi đối với các trang web mẫu này tại đây. Điều chỉnh mới này được mô tả chi tiết hơn bên dưới.

Chúng tôi cũng đã thực hiện một thay đổi để hỗ trợ các ứng dụng WebRTC; mặc dù phiên chụp đang hoạt động nhưng tính năng tự động phát sẽ được cho phép.

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

Trước đây, các trình duyệt thường không hỗ trợ 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 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 kém này cho người dùng chính là vấn đề mà chúng tôi đang cố gắng giải quyết. Tiếng ồn không mong muốn là lý do chính khiến người dùng không muốn trình duyệt của họ tự động phát nội dung.

Tuy nhiên, đôi khi người dùng muốn tự động phát nội dung nên sau đó, người dùng sẽ phát một số nội dung tự động phát bị chặn đáng kể 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 từng trang web, chúng tôi có thể tạo ra trải nghiệm người dùng tốt nhất. Nếu người dùng có xu hướng để nội dung phát trên một trang web, 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 tự động phát nội dung từ một trang web cụ thể, chúng tôi sẽ chặn tự động phát cho nội dung đó theo mặc định.

Một đề xuất do cộng đồng đề xuất là tắt tiếng của một thẻ thay vì tạm dừng tính năng tự động phát. Tuy nhiên, chúng tôi cho rằng bạn nên tạm dừng chế độ tự động phát để trang web biết rằng chế độ này đã bị chặn và nhà phát triển trang web có thể phản ứng với việc này. Ví dụ: trong khi một số nhà phát triển có thể chỉ muốn tắt tiếng, thì các nhà phát triển khác có thể 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 điều chỉnh mới để trợ giúp nhà phát triển trò chơi trên web

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

Các 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àmResume() 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, trong đó có một giao diện là giao diện AudioScheduledSourceNode. AudioNodes triển khai giao diện AudioScheduleSourceNode thường được gọi là nút nguồn (chẳng hạn như AudioBufferSourceNode, ConstantSourceNode và OscillatorNode). Nút nguồn triển khai một phương thức start().

Nút nguồn thường biểu thị các đoạn âm thanh riêng lẻ mà trò chơi phát. Ví dụ: âm thanh được phát khi người chơi thu thập một đồng xu hoặc nhạc nền phát trong giai đoạn hiện tại. 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 thấy dạng thức phổ biến này trong trò chơi web, chúng tôi quyết định điều chỉnh việc triển khai của mình như sau:

AudioContext sẽ tự động tiếp tục khi đáp ứng 2 đ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 giờ đây sẽ tiếp tục phát âm thanh khi người dùng bắt đầu chơi trò chơi.

Tiến bộ trên web

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

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

  • Các nhà phát triển web có thể tập trung vào một dự án mới và việc bảo trì một trang web cũ là không thể ngay lập tức.
  • Cổng trò chơi trên web có thể không có quyền kiểm soát 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 phải hàng nghìn trò chơi – có thể khiến nhà xuất bản mất thời gian và tốn kém.
  • Chỉ đơn giản là một số trang web đã quá cũ và – vì lý do này hay lý do khác – không còn được duy trì nhưng vẫn được lưu trữ cho mục đích lịch sử.

Dưới đây là một đoạn mã JavaScript ngắn chặn việc tạo đối tượng AudioContext mới và sẽ tự động kích hoạt chức năng tiếp tục của các đối tượng này khi người dùng thực hiện nhiều tương tác với người dùng. Bạn phải thực thi mã này trước khi tạo bất kỳ đối tượng AudioContext nào trên trang web của bạn, 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);
  });
})();

Lưu ý rằng đoạn mã này sẽ không hỗ trợ tiếp tục AudioContexts đã tạo thực thể trong iframe, trừ khi đoạn mã này nằm trong phạm vi nội dung của iframe đó.

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

Cùng với thay đổi này về chính sách, chúng tôi cũng giới thiệu một cơ chế để người dùng tắt chính sách tự động phát để xử lý trường hợp tính năng tự động học không hoạt động như mong đợi hoặc đối với những trang web không 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. Bạn có thể tìm thấy thay đổi này trong phần Cài đặt âm thanh. Những trang web mà người dùng muốn cho phép tự động phát có thể được thêm vào danh sách Cho phép.

MEI được xây dựng 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 mong muốn của họ đối với một trang web nhất định có nội dung tự động phát. Mỗi trang web sẽ có điểm trong chỉ mục này nằm trong khoảng từ 0 đến 1. Điểm số cao hơn cho biết người dùng mong đợi nội dung sẽ phát trên 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ự động phát ở mọi nơi, một danh sách gốc dựa trên điểm MEI tổng hợp của người dùng ẩn danh sẽ được sử dụng để xác định trang web nào 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 chuẩn bị trước được tạo bằng thuật toán, thay vì được tuyển chọn theo cách thủ công, và bất kỳ trang web nào cũng đủ điều kiện để đưa vào. Các trang web sẽ được thêm vào danh sách nếu có đủ 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 đưa ra quyết định và cơ sở thiết kế của chính sách này. Ngoài ra, chúng tôi còn có các tài liệu mới về cách hoạt động của danh sách trang web được chuẩn bị sẵn.

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

Ý kiến phản hồi