คำถามที่พบบ่อยเกี่ยวกับ Web Audio

ในช่วงไม่กี่เดือนที่ผ่านมา Web Audio API ได้กลายเป็นแพลตฟอร์มที่น่าสนใจสำหรับเกมและแอปพลิเคชันเสียงบนเว็บ เมื่อนักพัฒนาซอฟต์แวร์เริ่มคุ้นเคยกับเรื่องนี้แล้ว ฉันได้ยินคำถามที่คล้ายกันปรากฏขึ้นมาซ้ำๆ การอัปเดตสั้นๆ นี้เป็นการพยายามตอบคำถามที่พบบ่อยบางข้อ เพื่อให้คุณได้รับประสบการณ์การใช้งาน Web Audio API ที่น่าพึงพอใจยิ่งขึ้น

ถาม: ช่วยด้วย ฉันไม่ออกเสียงหรอก!

ตอบ: หากคุณยังไม่คุ้นเคยกับ Web Audio API โปรดดูบทแนะนำการเริ่มต้นใช้งาน หรือสูตรการเล่นเสียงตามการโต้ตอบของผู้ใช้ของ Eric

ถ. ฉันควรมีบริบทเสียงกี่รายการ

ตอบ: โดยทั่วไปแล้ว คุณควรใส่ AudioContext จำนวน 1 รายการต่อหน้า และบริบทเสียงรายการเดียวสามารถรองรับโหนดหลายรายการที่เชื่อมต่อกับพร็อพเพอร์ตี้ดังกล่าวได้ แม้ว่าคุณจะรวม AudioContexts หลายรายการไว้ในหน้าเดียว แต่ก็อาจทำให้มีการแสดงผลด้านประสิทธิภาพได้

ถาม: ฉันมี AudioBufferSourceNode ซึ่งเพิ่งเล่นด้วย noteOn() และฉันต้องการเล่นอีกครั้ง แต่ noteOn() ไม่มีอะไรเลย ช่วยด้วย

ตอบ: เมื่อโหนดแหล่งที่มาเล่นจบแล้ว โหนดดังกล่าวจะไม่สามารถเล่นได้อีก หากต้องการเล่นบัฟเฟอร์ที่ซ่อนอยู่อีกครั้ง คุณควรสร้าง AudioBufferSourceNode ใหม่และเรียกใช้ noteOn()

แม้ว่าการสร้างโหนดต้นทางใหม่อาจรู้สึกว่าไม่มีประสิทธิภาพ แต่โหนดแหล่งที่มาได้รับการเพิ่มประสิทธิภาพอย่างมากสำหรับรูปแบบนี้ นอกจากนี้ หากคุณเก็บ AudioBuffer ไว้ ก็ไม่ต้องส่งคำขอใหม่ไปยังเนื้อหาเพื่อเล่นเสียงเดิมอีกครั้ง หากคุณต้องการให้เล่นซ้ำ ให้ล้อมรอบการเล่นด้วยฟังก์ชันตัวช่วยง่ายๆ เช่น playSound(buffer)

ถาม: เมื่อเล่นเสียง ทำไมคุณจึงต้องสร้างโหนดต้นทางใหม่ทุกครั้ง

ตอบ: สถาปัตยกรรมนี้คือการแยกเนื้อหาเสียงออกจากสถานะการเล่น เมื่อเปรียบเทียบกับเครื่องเล่นแผ่นเสียง บัฟเฟอร์เปรียบได้กับการบันทึกเสียงและแหล่งที่มาของผู้เล่น เนื่องจากแอปพลิเคชันจำนวนมากเกี่ยวข้องกับบัฟเฟอร์เดียวกันในหลายๆ เวอร์ชันที่เล่นพร้อมกัน รูปแบบนี้จึงเป็นสิ่งจำเป็น

ถาม: ฉันจะประมวลผลเสียงจากแท็ก audio และ video ได้อย่างไร

ตอบ: MediaElementAudioSourceNode อยู่ระหว่างดำเนินการ ตัวกรองจะทำงานคร่าวๆ ดังนี้ (เพิ่มเอฟเฟกต์ฟิลเตอร์ในตัวอย่างที่เล่นผ่านแท็กเสียง)

<audio src="sounds/sample.wav" controls>
var audioElement = document.querySelector('audio');
var mediaSourceNode = context.createMediaElementSource(audioElement);
mediaSourceNode.connect(filter);
filter.connect(context.destination);

มีการติดตามฟีเจอร์นี้ใน crbug นี้ โปรดทราบว่าในการตั้งค่านี้ ไม่จำเป็นต้องเรียกใช้ mediaSourceNode.noteOn() เนื่องจากแท็กเสียงจะควบคุมการเล่น

ถาม: ฉันจะรับเสียงจากไมโครโฟนได้เมื่อใด

ตอบ: ส่วนอินพุตเสียงในส่วนนี้จะถูกนำมาใช้ในฐานะส่วนหนึ่งของ WebRTC โดยใช้ getUserMedia และพร้อมใช้งานเป็นโหนดแหล่งที่มาพิเศษใน Web Audio API โดยจะทำงานร่วมกับ createMediaElementSource

ถาม: ฉันจะตรวจสอบได้อย่างไรว่า AudioSourceNode เล่นจบแล้วเมื่อใด

ตอบ: ปัจจุบันคุณต้องใช้ตัวจับเวลา JavaScript เนื่องจาก Web Audio API ไม่รองรับฟังก์ชันนี้ ตัวอย่างต่อไปนี้จากบทแนะนำการเริ่มต้นใช้งาน Web Audio API เป็นตัวอย่างของการใช้งานจริง

// Assume source and buffer are previously defined.
source.noteOn(0);
var timer = setTimeout(function() {
    console.log('playback finished');
}, buffer.duration * 1000);

มีข้อบกพร่องแบบเปิดที่จะทำให้ Web Audio API ใช้โค้ดเรียกกลับที่แม่นยำยิ่งขึ้น

ถาม: เสียงการโหลดทำให้ชุด UI ทั้งชุดล็อกและ UI ไม่ตอบสนอง ช่วยด้วย!**

ตอบ: ใช้ decodeAudioData API สำหรับการโหลดแบบไม่พร้อมกันเพื่อหลีกเลี่ยงการบล็อกเทรดหลัก ดูตัวอย่างนี้

ถาม: สามารถใช้ Web Audio API ในการประมวลผลเสียงที่เร็วกว่าแบบเรียลไทม์ได้ไหม

ตอบ: ใช่ ทางโซลูชันกำลังทำงาน โปรดติดตาม!

ถาม: ฉันสร้างแอปพลิเคชัน Web Audio API ที่ยอดเยี่ยม แต่เมื่อใดก็ตามที่แท็บที่ทำงานอยู่เบื้องหลัง เสียงจะแปลกไปหมด

ตอบ: อาจเป็นเพราะคุณใช้ setTimeouts ซึ่งทํางานแตกต่างออกไปหากหน้าเว็บอยู่ในเบื้องหลัง ในอนาคต Web Audio API จะเรียกกลับในช่วงเวลาที่กำหนดได้โดยใช้ตัวจับเวลาภายในของเสียงบนเว็บ (แอตทริบิวต์ context.currentTime) สำหรับข้อมูลเพิ่มเติม โปรดดูคำขอฟีเจอร์นี้

โดยทั่วไป คุณควรหยุดเล่นเมื่อแอปทำงานในเบื้องหลัง คุณดูได้ว่าหน้าเว็บไปที่พื้นหลังเมื่อใดโดยใช้ Page Visibility API

ถาม: ฉันจะเปลี่ยนระดับเสียงของเสียงโดยใช้ Web Audio API ได้อย่างไร

ตอบ: เปลี่ยน playbackRate ในโหนดต้นทาง

ถาม: ฉันจะเปลี่ยนระดับเสียงโดยไม่เปลี่ยนความเร็วได้ไหม

ตอบ: Web Audio API อาจมี PitchNode ในบริบทของเสียง แต่การดำเนินการนี้ทำได้ยาก เนื่องจากไม่มีอัลกอริทึมการเปลี่ยนระดับเสียงที่ตรงไปตรงมาในชุมชนเสียง เทคนิคที่รู้จักจะสร้างอาร์ติแฟกต์ โดยเฉพาะในกรณีที่ระดับเสียงมีการเปลี่ยนแปลงอย่างมาก วิธีแก้ไขปัญหานี้มี 2 วิธีดังนี้

  • อัลกอริทึมของโดเมนเวลา ซึ่งทำให้เกิดเสียงสะท้อนของส่วนที่เกิดขึ้นซ้ำๆ
  • เทคนิคโดเมนความถี่ ซึ่งทำให้เกิดเสียงก้อง

แม้ว่าจะไม่มีโหนดเนทีฟสำหรับใช้เทคนิคเหล่านี้ แต่คุณสามารถสร้างโดยใช้ JavaScriptAudioNode ได้ ข้อมูลโค้ดนี้อาจเป็นจุดเริ่มต้น

ถาม: ฉันจะสร้าง AudioContext ในอัตราตัวอย่างที่ฉันเลือกได้อย่างไร

ตอบ: ขณะนี้ยังไม่มีการสนับสนุนในเรื่องนี้ แต่เรากำลังตรวจสอบอยู่ ดูคำขอฟีเจอร์นี้

หากมีข้อสงสัยเพิ่มเติม ก็ถามได้เลยใน StackOverflow โดยใช้แท็ก web-audio