navigator.audioSession cho phép trang khai báo loại âm thanh và theo dõi trạng thái interrupted. Nó tiết lộ gì về thiết bị và giới hạn nằm ở đâu.
Một trang web đang phát âm thanh có thể biết khi có thứ gì đó bên ngoài trình duyệt giành lấy kênh âm thanh của nó — chẳng hạn một cuộc gọi đến, hoặc một ứng dụng khác chiếm độc quyền âm thanh. Việc này không cần hộp thoại xin quyền, cũng không cần quyền micro. Đó là tác dụng phụ của một API được thiết kế vì lý do hợp lý: cho hệ điều hành biết trang đang phát loại âm thanh nào. Bài viết này giải thích Audio Session API để lộ gì, không cho trang biết gì, và vì sao nó thuộc cùng họ với các "API thích ứng" vốn đồng thời là công cụ quan sát thụ động.
Điểm chính
navigator.audioSessioncho phép trang khai báo loại âm thanh qua thuộc tínhtype:auto,playback,transient,transient-solo,ambienthoặcplay-and-record. Hệ điều hành dùng nó để quyết định hạ nhỏ, tạm dừng hay trộn âm thanh khác.- Phiên âm thanh còn có
state—active,inactivehoặcinterrupted— và phát sự kiệnstatechangekhi nó thay đổi. interrupteddo những sự việc bên ngoài trình duyệt gây ra, như cuộc gọi đến hoặc ứng dụng khác chiếm quyền ưu tiên âm thanh. Trang chỉ biết có thứ gì đó được ưu tiên và vào lúc nào, không biết ai gọi hay điều gì đã gián đoạn.- Mỗi engine hỗ trợ khác nhau. WebKit đã phát hành một tập con của API trong Safari 16.4, MDN vẫn đánh dấu nó là thử nghiệm và còn hạn chế về khả năng hỗ trợ, còn thế nào là gián đoạn thì do nền tảng quyết định, nên sự hiện diện và hành vi của API cũng là một tín hiệu thô về engine.
- Không có công tắc để tắt. Hành vi này gắn liền với việc trang có âm thanh, nên cách phòng vệ thực tế là nắm rõ vấn đề cộng với thói quen chống fingerprinting chung.
Audio Session API dùng để làm gì
Trước API này, trình duyệt phải đoán âm thanh của trang nên chung sống thế nào với mọi thứ khác trên thiết bị. Trang gọi video, trình phát podcast và trang chỉ phát một tiếng chuông thông báo nhìn từ bên ngoài khá giống nhau, nhưng điện thoại cần đối xử rất khác: cuộc gọi phải được ưu tiên và tắt tiếng các ứng dụng khác, podcast nên tạm dừng khi có cuộc gọi đến, còn tiếng chuông chỉ cần hạ nhỏ âm thanh khác trong chốc lát.
AudioSession giải quyết bằng cách để trang tự nói mình đang làm gì. Thuộc tính type nhận các giá trị sau:
| Loại | Mục đích dự kiến |
|---|---|
auto | Trình duyệt tự chọn dựa trên nội dung đang phát |
playback | Nhạc, video, podcast — âm thanh người dùng chủ động muốn nghe |
transient | Âm thanh ngắn như thông báo; âm thanh khác bị hạ nhỏ |
transient-solo | Âm thanh ngắn cần tạm tắt mọi thứ khác |
ambient | Âm nền có thể trộn với ứng dụng khác |
play-and-record | Âm thanh hai chiều, như cuộc gọi |
Đặc tả của W3C có tên "Audio Session", và WebKit đã công bố hỗ trợ một tập con trong ghi chú phát hành Safari 16.4. Khai báo loại là nửa chính đáng của câu chuyện, và là thiết kế tốt: nó cung cấp thông tin cho nền tảng thay vì bắt nền tảng suy đoán ý định.
Nửa còn lại: trạng thái phiên
Cùng một đối tượng này cũng báo phiên hiện đang ở đâu:
if ("audioSession" in navigator) {
console.log(navigator.audioSession.type); // e.g. "playback"
console.log(navigator.audioSession.state); // "active", "inactive" or "interrupted"
}
Có ba trạng thái. active nghĩa là trang đang phát hoặc ghi âm, inactive (mặc định) nghĩa là không làm cả hai, và interrupted nghĩa là nền tảng đã tạm ngưng một phiên vốn đang hoạt động. Sự kiện statechange được phát khi chuyển trạng thái, nên trang không cần thăm dò liên tục. Trong lúc phiên bị gián đoạn, chính trình duyệt sẽ tạm dừng các phần tử media của trang, tạm ngưng các AudioContext và tắt tiếng track micro, rồi tự khôi phục khi trạng thái trở lại active.
interrupted là trạng thái có sức nặng về quyền riêng tư. Ví dụ MDN đưa ra về nguyên nhân là cuộc gọi đến và một ứng dụng khác chiếm độc quyền âm thanh. Thuộc tính Web Audio liên quan AudioContext.state cũng dùng đúng từ này, định nghĩa là sự gián đoạn do "một sự việc nằm ngoài tầm kiểm soát của ứng dụng web", và MDN ghi chú ngay tại đó rằng cách kích hoạt trạng thái interrupted có thể khác nhau giữa các trình duyệt. Tập hợp chính xác các tác nhân do nền tảng và trình duyệt quyết định, nên mỗi nơi một khác.
Vì sao đây là chuyện quyền riêng tư
Phần lớn tín hiệu về việc người dùng đang làm gì trên thiết bị hoặc cần xin quyền, hoặc web không tiếp cận được. Việc bạn có đang gọi điện hay không không phải điều một trang được phép biết. Audio Session API lại làm rò rỉ một phiên bản mờ nhạt của thông tin đó, như hệ quả phụ của việc phát âm thanh.
Cần nói chính xác về giới hạn, vì điều này rất dễ bị phóng đại:
- Trang không biết ai gọi, cũng không biết nguyên nhân gián đoạn. Nó thấy sự thay đổi trạng thái, không thấy nguyên nhân.
- Chỉ hoạt động khi trang có phiên âm thanh. Trang không có âm thanh thì không có gì để gián đoạn.
- Một sự kiện là bằng chứng yếu. Một cuộc gọi và một ứng dụng khác giành quyền âm thanh có thể trông giống hệt nhau.
Còn lại là một dòng thời gian hành vi. Vì trang cũng thấy lúc trạng thái trở lại active, nó có thể đo thời lượng từng lần gián đoạn. Các lần gián đoạn lặp lại, thời điểm của chúng và thời gian phiên ở trạng thái interrupted cộng lại thành bản ghi về lúc nào thiết bị bận việc khác. Bản thân nó không phải mã định danh, nhưng đúng là loại tín hiệu nhẹ, không cần hỏi mà các hệ thống phân tích và chống gian lận thích thu thập, và là thứ người dùng không ngờ một trang lại thấy được.
Tín hiệu kín đáo hơn: phát hiện tính năng
Còn một đường rò rỉ thứ hai, quen thuộc hơn. navigator.audioSession có tồn tại hay không, và trạng thái interrupted được kích hoạt ra sao, phụ thuộc vào engine. WebKit phát hành một tập con trong Safari 16.4, MDN đánh dấu API là thử nghiệm và chưa thuộc Baseline, và với thuộc tính liên quan mật thiết AudioContext.state, MDN nêu rõ cách kích hoạt gián đoạn có thể khác nhau giữa các trình duyệt. Sự khác biệt này chính là mô hình đã nói trong bài về phát hiện phiên bản engine qua tính năng: một khả năng có ở engine này mà không có ở engine kia sẽ thu hẹp phạm vi trình duyệt và hệ điều hành bạn dùng, mà không cần đọc chuỗi user-agent nào.
Kiểm tra nhân trình duyệt của BrowserInsight làm đúng như vậy với Chromium. Ma trận tính năng của nó kiểm tra các API âm thanh như AudioContext.setSinkId() để đặt trình duyệt lên trục phiên bản. Xin nói rõ phạm vi: trang này không thăm dò navigator.audioSession, AudioSession.state hay AudioContext.state, và không công cụ nào ở đây báo cáo cuộc gọi hay sự kiện gián đoạn. setSinkId() chỉ là ví dụ cụ thể về việc sự hiện diện của một API âm thanh đóng vai trò tín hiệu engine.
Cùng một mô hình với các API trạng thái thiết bị khác
Điều này không riêng gì âm thanh. Bài học lặp lại là: các API được thiết kế để trang thích ứng với thiết bị đồng thời cũng là sự quan sát thụ động thiết bị:
- Battery Status API đưa mức pin và trạng thái sạc cho trang mà không cần hỏi, sau đó bị Firefox gỡ và WebKit chưa từng phát hành.
- Network Information API để lộ loại kết nối và các ước lượng, với dấu vết nghiêng về Chromium.
- Việc liệt kê thiết bị đa phương tiện cho biết camera và micro nào đang được gắn.
- Cảm biến thiết bị để lộ số đo chuyển động và hướng.
Ở mỗi trường hợp, mục đích ban đầu đều có thật. Cái giá về quyền riêng tư đến từ sự kết hợp: không hỏi quyền, cập nhật liên tục, và mỗi trình duyệt triển khai một kiểu.
Vì sao trên di động ảnh hưởng nhiều hơn
Gián đoạn trên điện thoại thường xuyên và có ý nghĩa, còn trên máy tính để bàn thì hiếm. Cuộc gọi và việc các ứng dụng tranh giành quyền âm thanh diễn ra liên tục trên di động, nên tín hiệu ở đó vừa phong phú vừa đặc trưng hơn. Đó là lý do bài này thuộc nhóm di động: cùng API đó trên trình duyệt máy tính phần lớn im lặng. Để xem bức tranh rộng hơn về sự khác biệt của điện thoại, hãy đọc vân tay trình duyệt di động.
Bạn thực sự có thể làm gì
Thành thật mà nói, rất ít. Audio Session API không có công tắc, và hành vi này đến từ việc trang có âm thanh. Trang không phát âm thanh thì không có gì để quan sát. Ngoài ra, câu trả lời thực tế là những biện pháp chung áp dụng cho mọi tín hiệu nhỏ:
- Chặn hoặc hạn chế các script không cần thiết bằng một tiện ích mở rộng chặn nội dung.
- Ưu tiên trình duyệt có mặc định chống fingerprinting chặt chẽ hơn.
- Dùng kiểm tra vân tay để xem trình duyệt của bạn đang để lộ gì, và đọc vân tay trình duyệt là gì để có bức tranh tổng thể.
Sự không nhất quán cũng quan trọng: một hồ sơ tự nhận là nền tảng này nhưng lại phơi ra bề mặt API của nền tảng khác chính là loại sai lệch được nói trong bài về tính nhất quán của vân tay.
Câu hỏi thường gặp
Website có biết tôi đang gọi điện không?
Không trực tiếp. Một trang đang phát âm thanh có thể thấy phiên âm thanh của mình chuyển sang interrupted, và cuộc gọi có thể gây ra điều đó. Nó có thể đo được lần gián đoạn kéo dài bao lâu, nhưng không biết ai gọi, cũng không phân biệt được nguyên nhân là cuộc gọi hay thứ khác, chẳng hạn một ứng dụng khác chiếm lấy âm thanh.
Audio Session API có cần xin quyền không?
Không. Đây là thuộc tính của navigator, và đọc loại cũng như trạng thái của nó không hiện hộp thoại nào. Phần lớn vì thế mà nó quan trọng với quyền riêng tư.
Trình duyệt nào hỗ trợ?
WebKit đã phát hành một tập con trong Safari 16.4. MDN đánh dấu API này là thử nghiệm và còn hạn chế về khả năng hỗ trợ, nên hãy xem bảng tương thích mới nhất trên trang MDN thay vì tự suy đoán.
Tôi có tắt được không?
Không có cài đặt. Trang không phát âm thanh thì không có gì để gián đoạn, và chặn script không cần thiết sẽ thu hẹp số bên có thể quan sát bạn.
Kết luận
Audio Session API là câu trả lời hợp lý cho một vấn đề có thật: hệ điều hành cần biết trang đang phát loại âm thanh nào. Trạng thái interrupted của nó là phần thêm ngoài ý muốn: cho trang nhận ra có thứ gì đó bên ngoài trình duyệt giành quyền ưu tiên, mà không cần hỏi và không biết nguyên nhân. Tín hiệu này tự nó yếu, phong phú hơn trên điện thoại so với máy tính để bàn, và cùng với các API pin, mạng và cảm biến nhắc rằng tính năng thích ứng và tính năng quan sát thường là một.
Đọc thêm:


