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

Điều này đặc biệt hữu ích trong nhiều tình huống 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 để chuyển đầu ra theo phương thức lập trình tới 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. Nhận danh sách thiết bị truyền thông hiện có với navigator.mediaDevices.enumerateDevices(), chỉ lọc trên các thiết bị đầu ra âm thanh và nhận thuộc tính deviceId của thiết bị đầu ra âm thanh mà bạn chọn. Giá trị "" của chuỗi trống cũng có thể được dùng làm thiết bị mặc định cho deviceId.

Sau khi bạn có giá trị nhận dạng của thiết bị đầu ra âm thanh, hãy tạo AudioContext rồi gọi audioContext.setSinkId(deviceId). Khi thành công, lệnh trả về sẽ được phân giải khi âm thanh được định tuyế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 đã đóng.

Ví dụ bên dưới cho bạn thấy cách yêu cầu quyền truy cập 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 đã 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 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 được qua audioContext.currentTime sẽ vẫn tiếp tục kết xuất biểu đồ âm thanh. Mục đích chính của AudioContext bị tắt tiếng này là hiển thị 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 đầu vào 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 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://sinkid.glitch.me/ để chơi với AudioContext.setSinkId().

Hỗ trợ trình duyệt

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

Ý kiến phản hồi

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

Xác nhậ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.