ในช่วงไม่กี่เดือนที่ผ่านมา 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