שאלות נפוצות בנושא אודיו באינטרנט

במהלך החודשים האחרונים, Web Audio API של WebKit הפך לפלטפורמה אטרקטיבית למשחקים ולאפליקציות אודיו באינטרנט. ככל שהמפתחים מתרגלים לעבוד עם הכלי, אני שומע שוב ושוב שאלות דומות. העדכון המהיר הזה נועד לתת מענה לכמה מהשאלות הנפוצות ביותר, כדי לשפר את חוויית השימוש ב-Web Audio API.

שאלה: עזרה, אני לא מצליח להשמיע צלילים!

ת: אם אתם חדשים ב-Web Audio API, כדאי לעיין במדריך לתחילת העבודה או במתכון של אריק להפעלת אודיו על סמך אינטראקציה של המשתמש.

שאלה: כמה הקשרים של אודיו צריכים להיות לי?

ת: בדרך כלל, כדאי לכלול AudioContext אחד לכל דף, והקשר אודיו יחיד יכול לתמוך בהרבה צמתים שמחוברים אליו. אפשר לכלול כמה AudioContext בדף אחד, אבל זה עלול לפגוע בביצועים.

שאלה: יש לי AudioBufferSourceNode, שהפעלתי אותו באמצעות noteOn(), ואני רוצה להפעיל אותו שוב, אבל noteOn() לא עושה כלום! איך אוכל לקבל עזרה?

תשובה: אחרי שצומת מקור מסיים את ההפעלה, הוא לא יכול להפעיל עוד. כדי להפעיל שוב את המאגר הבסיסי, צריך ליצור AudioBufferSourceNode חדש ולהתקשר אל noteOn().

יכול להיות שייראה לכם לא יעיל ליצור מחדש את צומת המקור, אבל צמתי המקור עוברים אופטימיזציה משמעותית לדפוס הזה. בנוסף, אם שומרים את ה-handle של 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, וממשק המשתמש מפסיק להגיב. עזרה!**

תשובה: משתמשים ב-API ‏decodeAudioData לטעינה אסינכרונית כדי להימנע מחסימה של ה-thread הראשי. לדוגמה

ש: האם אפשר להשתמש ב-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 בהקשר של האודיו, אבל קשה להטמיע את זה. הסיבה לכך היא שאין אלגוריתם פשוט לשינוי גובה הצליל בקהילת האודיו. טכניקות מוכרות יוצרות ארטיפקטים, במיוחד במקרים שבהם שינוי הגובה גדול. יש שני סוגים של גישות לפתרון הבעיה הזו:

  • אלגוריתמים של תחום הזמן, שגורמים לארטיפקטים של הד חוזר בפלח.
  • טכניקות של תחום התדר, שגורמות לארטיפקטים של צליל מהדהד.

אין צומת מקורי לביצוע הטכניקות האלה, אבל אפשר לעשות את זה באמצעות JavaScriptAudioNode. קטע הקוד הזה יכול לשמש כנקודת התחלה.

שאלה: איך אפשר ליצור AudioContext בקצב דגימה לפי בחירה?

תשובה: כרגע אין תמיכה באפשרות הזו, אבל אנחנו בודקים את האפשרות הזו. הגשת בקשה להוספת תכונה זו

אם יש לכם שאלות נוספות, אתם יכולים לפרסם אותן ב-StackOverflow באמצעות התג web-audio.