Thay đổi thiết bị đầu ra đích trong Web Audio

François Beaufort
François Beaufort

Cho đến nay, bạn chỉ có thể đặt thiết bị đầu ra âm thanh đích cho <video><audio> bằng HTMLMediaElement.setSinkId(). Trong Web Audio, AudioContext sử dụng thiết bị mặc định, khiến người dùng phải thay đổi thiết bị đầu ra âm thanh của hệ thống theo cách thủ công.

Từ Chrome 110, bạn có thể dùng AudioContext.setSinkId() để lập trình hướng đầu ra âm thanh trong Web Audio đến bất kỳ thiết bị nào được phép.

Tính năng này đặc biệt hữu ích trong nhiều trường hợp giao tiếp theo thời gian thực. Ví dụ: một ứng dụng web có thể dùng API này để lập trình hướng đầu ra đến một thiết bị đầu ra âm thanh cụ thể, chẳng hạn như tai nghe Bluetooth hoặc loa ngoài.

Định tuyến đầu ra âm thanh đến một thiết bị cụ thể

Trước tiên, bạn cần có giá trị nhận dạng của thiết bị đầu ra âm thanh mà bạn muốn dùng làm đích đến. Lấy danh sách các thiết bị đa phương tiện có sẵn bằng navigator.mediaDevices.enumerateDevices(), chỉ lọc trên các thiết bị đầu ra âm thanh và lấy thuộc tính deviceId của thiết bị đầu ra âm thanh mà bạn chọn. Bạn cũng có thể dùng giá trị chuỗi trống "" làm thiết bị mặc định cho deviceId.

Sau khi bạn có mã nhận dạng của thiết bị đầu ra âm thanh, hãy tạo một AudioContext và gọi audioContext.setSinkId(deviceId). Khi thành công, lời hứa được trả về sẽ phân giải khi âm thanh được chuyển đến thiết bị đầu ra được kết nối đã chọn. Thao tác này có thể không thành công nếu AudioContext bị đóng.

Ví dụ bên dưới cho thấy cách yêu cầu quyền sử dụng micrô (nếu cần) và chuyển hướng đầu ra âm thanh trong Web Audio đến thiết bị đầu ra có sẵn đầu tiên.

const permission = await navigator.permissions.query({ name: "microphone" });
if (permission.state == "prompt") {
  // More audio outputs are available when user grants access to the mic.
  const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
  stream.getTracks().forEach((track) => track.stop());
}

// Request a list of media devices and filter audio output devices.
const devices = await navigator.mediaDevices.enumerateDevices();
const audioOutputs = devices.filter(device => device.kind == "audiooutput");

const audioContext = new AudioContext();

// Pick the first available audio output.
const deviceId = audioOutputs[0].deviceId;
await audioContext.setSinkId(deviceId);

Xin lưu ý rằng bạn cũng có thể truyền deviceId dưới dạng tham số sinkId khi tạo AudioContext.

const audioContext = new AudioContext({ sinkId: deviceId });

Kết xuất âm thanh bằng AudioContext bị tắt tiếng

Giờ đây, bạn có thể chỉ định một "thiết bị đầu ra im lặng" trong Web Audio để giảm thiểu mức tiêu thụ điện năng. Lần này, thay vì giá trị chuỗi, hãy truyền { type: "none" } đến AudioContext.setSinkId().

Xin lưu ý rằng đồng hồ âm thanh có thể truy cập thông qua audioContext.currentTime vẫn sẽ tiến hành kết xuất biểu đồ âm thanh. Mục tiêu chính của AudioContext bị tắt tiếng này là kết xuất biểu đồ âm thanh mà không tạo ra âm thanh có thể nghe được. Trường hợp sử dụng chính là phân tích dữ liệu đầu vào từ micrô mà không tạo ra âm thanh.

// Silent Web Audio output.
await audioContext.setSinkId({ type: "none" });

Phát hiện đối tượng

Để kiểm tra xem AudioContext.setSinkId() có được hỗ trợ hay không, hãy sử dụng:

if ("setSinkId" in AudioContext.prototype) {
  // AudioContext.setSinkId() is supported.
}

Mẫu

Bạn có thể xem bản minh hoạ tại https://codepen.io/web-dot-dev/pen/emNwEaN/ để dùng thử AudioContext.setSinkId().

Hỗ trợ trình duyệt

AudioContext.setSinkId() có trong Chrome 110 trở lên.

Phản hồi

Nhóm Chrome và cộng đồng tiêu chuẩn web muốn biết trải nghiệm của bạn với AudioContext.setSinkId(). Vui lòng đưa ra ý kiến phản hồi bằng cách bình luận về các vấn đề hiện có trên GitHub hoặc gửi vấn đề mới.

Lời cảm ơn

Cảm ơn Hongchan ChoiMichael Wilson đã xem xét bài viết này.

Ảnh lịch của Steve Harvey trên Unsplash.