خلال الأشهر القليلة الماضية، برزت Web Audio API في WebKit كمنصة جذابة للألعاب وتطبيقات الصوت على الويب. وبعد أن يتعرّف المطوّرون على هذه الميزة، أسمع أسئلة مشابهة تتكرّر باستمرار. يهدف هذا التحديث السريع إلى الإجابة عن بعض الأسئلة الأكثر شيوعًا لجعل تجربتك مع Web Audio API أكثر متعة.
س: لا يمكنني إصدار أصوات.
ج: إذا كنت مبتدئًا في استخدام Web Audio API، يمكنك الاطّلاع على البرنامج التعليمي الخاص ببدء الاستخدام، أو وصفة إريك لتشغيل الصوت استنادًا إلى تفاعل المستخدم.
س: كم عدد "سياقات الصوت" التي يجب أن أملكها؟
ج: بشكل عام، يجب تضمين AudioContext واحد في كل صفحة، ويمكن أن يتيح سياق صوتي واحد العديد من العُقد المرتبطة به. على الرغم من أنّه يمكنك تضمين عدة 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);
يمكنك تتبُّع هذه الميزة في هذا الخطأ. يُرجى العِلم أنّه في عملية الإعداد هذه، لا حاجة إلى استدعاء 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 تنفّذ دالة ردّ أكثر دقة.
س: يؤدي تحميل الأصوات إلى قفل سلسلة واجهة المستخدم بالكامل، وتصبح واجهة المستخدم غير متجاوبة. ساعدني!**
ج: استخدِم واجهة برمجة التطبيقات decodeAudioData للتحميل غير المتزامن لتجنُّب حظر سلسلة التعليمات الرئيسية. الاطّلاع على هذا المثال
س: هل يمكن استخدام Web Audio API لمعالجة الأصوات بشكل أسرع من الوقت الفعلي؟
ج: نعم، نعمل على إيجاد حلّ. يُرجى ترقُّب آخر الأخبار.
س: لقد أنشأتُ تطبيقًا رائعًا باستخدام Web Audio API، ولكن عندما يتم تصغير علامة التبويب التي يتم تشغيل التطبيق فيها، يصبح الصوت غريبًا.
ج: من المحتمل أنّ السبب هو استخدامك setTimeouts، التي تتصرف بشكل مختلف إذا تم تصغير الصفحة. في المستقبل، ستتمكّن واجهة برمجة التطبيقات Web Audio API من تنفيذ عمليات معاودة الاتصال في أوقات محدّدة باستخدام المؤقت الداخلي لصوت الويب (السمة context.currentTime). لمزيد من المعلومات، يُرجى الاطّلاع على طلب الميزة هذا.
بشكل عام، قد يكون من الأفضل إيقاف التشغيل مؤقتًا عندما ينتقل تطبيقك إلى الخلفية. يمكنك رصد وقت انتقال الصفحة إلى الخلفية باستخدام Page Visibility API.
س: كيف يمكنني تغيير درجة الصوت باستخدام Web Audio API؟
ج: غيِّر playbackRate في عقدة المصدر.
س: هل يمكنني تغيير درجة الصوت بدون تغيير السرعة؟
ج: يمكن أن تتضمّن Web Audio API عنصر PitchNode في سياق الصوت، ولكن يصعب تنفيذ ذلك. يعود السبب إلى عدم توفّر خوارزمية بسيطة لتغيير درجة الصوت في منتدى الصوت. تؤدي التقنيات المعروفة إلى إنشاء تشوّهات، خاصةً في الحالات التي يكون فيها تغيير درجة الصوت كبيرًا. هناك نوعان من الأساليب لحلّ هذه المشكلة:
- خوارزميات المجال الزمني، التي تتسبّب في ظهور تشوّهات ناتجة عن تكرار أصداء المقاطع
- تقنيات مجال التردد التي تتسبّب في حدوث تشوّهات صوتية ناتجة عن الصدى
على الرغم من عدم توفّر عقدة أصلية لتنفيذ هذه الأساليب، يمكنك تنفيذها باستخدام JavaScriptAudioNode. يمكن أن يكون مقتطف الرمز هذا نقطة بداية.
س: كيف يمكنني إنشاء AudioContext بمعدّل عيّنة من اختياري؟
ج: لا تتوفّر هذه الميزة حاليًا، ولكنّنا نعمل على توفيرها. يمكنك الاطّلاع على طلب الميزة هذا.
إذا كانت لديك أسئلة إضافية، يمكنك طرحها على StackOverflow باستخدام العلامة web-audio.