เปลี่ยนอุปกรณ์เอาต์พุตปลายทางใน Web Audio

François Beaufort
François Beaufort

ก่อนหน้านี้ การตั้งค่าอุปกรณ์เอาต์พุตเสียงปลายทางทำได้เฉพาะใน <video> และ <audio> ที่มี HTMLMediaElement.setSinkId() ใน Web Audio, AudioContext ใช้ค่าเริ่มต้นของอุปกรณ์ ทำให้ผู้ใช้ต้องเปลี่ยนอุปกรณ์เอาต์พุตเสียงของระบบด้วยตนเอง

ตั้งแต่ Chrome 110 เป็นต้นไป คุณสามารถใช้ AudioContext.setSinkId() เพื่อกำหนดเอาต์พุตเสียงใน Web Audio ไปยังอุปกรณ์ที่ได้รับอนุญาตได้โดยอัตโนมัติ

ซึ่งจะมีประโยชน์อย่างยิ่งในสถานการณ์การสื่อสารแบบเรียลไทม์ที่หลากหลาย ตัวอย่างเช่น เว็บแอปสามารถใช้ API นี้เพื่อกำหนดเส้นทางเอาต์พุตไปยังอุปกรณ์เอาต์พุตเสียงที่เฉพาะเจาะจง เช่น ชุดหูฟังบลูทูธหรือลำโพงโทรศัพท์ ได้โดยอัตโนมัติ

กำหนดเส้นทางเอาต์พุตเสียงไปยังอุปกรณ์ที่ต้องการ

ก่อนอื่นคุณต้องมีตัวระบุของอุปกรณ์เอาต์พุตเสียงที่ต้องการใช้เป็นปลายทาง รับรายการอุปกรณ์สื่อที่พร้อมใช้งานด้วย navigator.mediaDevices.enumerateDevices() กรองเฉพาะอุปกรณ์เอาต์พุตเสียง และรับแอตทริบิวต์ deviceId ของอุปกรณ์เอาต์พุตเสียงที่คุณเลือก นอกจากนี้ยังใช้ค่าสตริงว่าง "" เป็นอุปกรณ์เริ่มต้นสำหรับ deviceId ได้ด้วย

เมื่อมีตัวระบุของอุปกรณ์เอาต์พุตเสียงแล้ว ให้สร้าง AudioContext และเรียกใช้ audioContext.setSinkId(deviceId) เมื่อสำเร็จแล้ว สัญญาที่ส่งคืนจะได้รับการแก้ไขเมื่อมีการกำหนดเส้นทางเสียงไปยังอุปกรณ์เอาต์พุตที่เชื่อมต่อที่เลือก ซึ่งอาจไม่สำเร็จหากปิด AudioContext

ตัวอย่างด้านล่างแสดงวิธีขอสิทธิ์เข้าถึงไมโครโฟนหากจำเป็น และส่งเอาต์พุตเสียงใน Web Audio ไปยังอุปกรณ์เอาต์พุตแรกที่พร้อมใช้งาน

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);

โปรดทราบว่าคุณยังส่ง deviceId เป็นพารามิเตอร์ sinkId เมื่อสร้าง AudioContext ได้ด้วย

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

แสดงเสียงด้วย AudioContext ที่ปิดเสียง

ตอนนี้คุณระบุ "อุปกรณ์เอาต์พุตแบบไม่มีเสียง" ใน Web Audio เพื่อลดการใช้พลังงานได้แล้ว คราวนี้ให้ส่ง { type: "none" } ถึง AudioContext.setSinkId() แทนค่าสตริง

โปรดทราบว่านาฬิกาเสียงที่เข้าถึงได้ผ่าน audioContext.currentTime จะยังคงเลื่อนไปเพื่อแสดงกราฟเสียง เป้าหมายหลักของ AudioContext ที่ปิดเสียงนี้คือการแสดงผลกราฟเสียงโดยไม่สร้างเสียงที่ได้ยิน Use Case หลักคือการวิเคราะห์อินพุตจากไมโครโฟนโดยไม่ส่งเสียง

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

การตรวจหาฟีเจอร์

หากต้องการตรวจสอบว่าระบบรองรับ AudioContext.setSinkId() หรือไม่ ให้ใช้คำสั่งต่อไปนี้

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

ตัวอย่าง

คุณดูการสาธิตได้ที่ https://codepen.io/web-dot-dev/pen/emNwEaN/ เพื่อทดลองใช้ AudioContext.setSinkId()

การสนับสนุนเบราว์เซอร์

AudioContext.setSinkId() พร้อมใช้งานใน Chrome 110 ขึ้นไป

ความคิดเห็น

ทีม Chrome และชุมชนมาตรฐานเว็บอยากทราบความคิดเห็นของคุณเกี่ยวกับ AudioContext.setSinkId() โปรดแสดงความคิดเห็นโดยการแสดงความคิดเห็นเกี่ยวกับปัญหาใน GitHub ที่มีอยู่หรือแจ้งปัญหาใหม่

คำขอบคุณ

ขอขอบคุณ Hongchan Choi และ Michael Wilson ที่ตรวจสอบบทความนี้

ภาพปฏิทินถ่ายโดย Steve Harvey บน Unsplash