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

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

ถาม: ช่วยด้วย ฉันเปิดเสียงไม่ได้

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

ถาม: ฉันควรมี AudioContext กี่รายการ

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

ถาม: ฉันมี 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 จะสามารถเรียกกลับในเวลาที่เฉพาะเจาะจงได้โดยใช้ตัวจับเวลาภายในของ Web Audio (แอตทริบิวต์ context.currentTime) ดูข้อมูลเพิ่มเติมได้ที่คำขอฟีเจอร์นี้

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

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

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

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

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

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

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

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

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

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