ในช่วง 2-3 เดือนที่ผ่านมา Web Audio API ของ WebKit กลายเป็นแพลตฟอร์มที่น่าสนใจสำหรับเกมและแอปพลิเคชันเสียงบนเว็บ เมื่อนักพัฒนาแอปเริ่มคุ้นเคยกับฟีเจอร์นี้ เราได้ยินคำถามที่คล้ายกันเกิดขึ้นซ้ำๆ การอัปเดตสั้นๆ นี้เป็นการพยายามตอบคําถามที่พบบ่อยบางข้อเพื่อให้คุณได้รับประสบการณ์การใช้งาน Web Audio API ที่ดีขึ้น
ถาม: ช่วยด้วย ฉันส่งเสียงไม่ได้
ตอบ: หากคุณเพิ่งเริ่มใช้ Web Audio API โปรดดูบทแนะนำการเริ่มต้นใช้งานหรือสูตรของ Eric สำหรับการเล่นเสียงตามการโต้ตอบของผู้ใช้
ถาม: ฉันควรมีบริบทเสียงกี่รายการ
ตอบ: โดยทั่วไป คุณควรใส่ AudioContext
1 รายการต่อหน้า และบริบทเสียงรายการเดียวรองรับโหนดที่เชื่อมต่อได้หลายโหนด แม้ว่าคุณจะรวม 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
) ดูข้อมูลเพิ่มเติมได้ที่คำขอฟีเจอร์นี้
โดยทั่วไปแล้ว คุณควรหยุดการเล่นเมื่อแอปทำงานอยู่เบื้องหลัง คุณสามารถตรวจจับเมื่อหน้าเว็บเปลี่ยนไปแสดงในเบื้องหลังได้โดยใช้ Page Visibility API
ถาม: ฉันจะเปลี่ยนระดับเสียงของเสียงโดยใช้ Web Audio API ได้อย่างไร
ตอบ: เปลี่ยน playbackRate
ในโหนดต้นทาง
ถาม: ฉันจะเปลี่ยนระดับเสียงโดยไม่เปลี่ยนความเร็วได้ไหม
ตอบ: Web Audio API อาจมี PitchNode ในบริบทเสียง แต่การใช้งานนั้นทำได้ยาก เนื่องจากไม่มีอัลกอริทึมการเปลี่ยนระดับเสียงที่ตรงไปตรงมาในชุมชนเสียง เทคนิคที่รู้จักจะสร้างข้อบกพร่อง โดยเฉพาะในกรณีที่มีการเปลี่ยนระดับเสียงมาก การแก้ปัญหานี้มี 2 วิธี ได้แก่
- อัลกอริทึมโดเมนเวลา ซึ่งทําให้อาร์ติแฟกต์การสะท้อนของกลุ่มซ้ำ
- เทคนิคโดเมนความถี่ ซึ่งทำให้เกิดเสียงสะท้อน
แม้ว่าจะไม่มีโหนดเนทีฟสําหรับเทคนิคเหล่านี้ แต่คุณก็ทําได้ด้วย JavaScriptAudioNode
ข้อมูลโค้ดนี้อาจใช้เป็นจุดเริ่มต้นได้
ถาม: ฉันจะสร้าง AudioContext ที่อัตราตัวอย่างที่เลือกได้อย่างไร
ตอบ: ขณะนี้ระบบยังไม่รองรับการดำเนินการนี้ แต่เรากำลังตรวจสอบอยู่ ดูคำขอฟีเจอร์นี้
หากมีคำถามเพิ่มเติม โปรดถามใน StackOverflow โดยใช้แท็ก web-audio