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ể sử dụng AudioContext.setSinkId() để hướng đầu ra âm thanh trong Web Audio đến bất kỳ thiết bị được phép nào theo phương thức lập trình.

Điều 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ể sử dụng tính năng này để hướng đầu ra đến một thiết bị đầu ra âm thanh cụ thể theo phương thức lập trình, 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 sử dụng làm đích. 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ể sử dụng giá trị chuỗi rỗng "" làm thiết bị mặc định cho deviceId.

Sau khi có giá trị nhận dạng của thiết bị đầu ra âm thanh, hãy tạo 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 định tuyến đến thiết bị đầu ra được kết nối đã chọn. Lệnh 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à 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 "thiết bị đầu ra im lặng" trong Web Audio để giảm thiểu mức tiêu thụ điện. 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 sẽ là phân tích dữ liệu đầu vào của micrô mà không tạo ra âm thanh.

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

Phát hiện tính nă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ề 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ó hoặc gửi vấn đề mới trên GitHub.

Lời cảm ơn

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