الأسئلة الشائعة حول Web Audio

خلال الأشهر القليلة الماضية، برزت واجهة برمجة التطبيقات Web Audio API في WebKit كنظام أساسي مؤثر للألعاب وتطبيقات الصوت على الويب. ومع تعرّف المطوّرين على هذه الميزة، نتلقّى أسئلة مشابهة بشكل متكرّر. نهدف من خلال هذا التعديل السريع إلى الردّ على بعض الأسئلة الشائعة لتحسين تجربتك مع Web Audio API.

س: أحتاج إلى مساعدة، لا يمكنني إنشاء أصوات.

ج: إذا كنت مبتدئًا في استخدام واجهة برمجة التطبيقات Web Audio API، يمكنك الاطّلاع على الدليل التعليمي للبدء أو على طريقة "إريك" لتشغيل الصوت استنادًا إلى تفاعل المستخدم.

س: كم عدد سياقات الصوت التي يجب أن أمتلكها؟

ج: بشكل عام، يجب تضمين 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 تنفِّذ طلب استدعاء أكثر دقة.

س: يؤدي تحميل الأصوات إلى قفل سلسلة واجهة المستخدم بالكامل وتوقّف واجهة المستخدم عن الاستجابة. مساعدة**

ج: استخدِم واجهة برمجة التطبيقات 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.