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

בוריס סמוס

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

המעקב אחר התכונה הזו מתבצע בניפוי הבאגים הזה. הערה: בהגדרה הזו אין צורך לקרוא ל-mediaSourceNode.noteOn(), תג האודיו שולט בהפעלה.

שאלה: מתי אפשר להשמיע צליל ממיקרופון?

ת: החלק הזה של קלט האודיו יוטמע כחלק מ-WebRTC באמצעות getUserMedia, ויהיה זמין כצומת מקור מיוחד ב-Web Audio API. היא תעבוד יחד עם createMediaElementSource.

שאלה: איך אפשר לבדוק מתי AudioSourceNode סיים לשחק?

ת: בשלב זה עליך להשתמש בטיימר של JavaScript מכיוון שממשק ה-API של Web Audio לא תומך בפונקציונליות הזו. קטע הקוד הבא מתוך המדריך לתחילת העבודה עם 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 להטמיע קריאה חוזרת (callback) מדויקת יותר.

שאלה: צלילי הטעינה גורמים לכל ה-thread של ממשק המשתמש להינעל וממשק המשתמש לא מגיב. עזרה!**

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

ש: האם ניתן להשתמש ב-Web Audio API כדי לעבד צלילים מהר יותר מזמן אמת?

ת': כן, אנחנו עובדים על פתרון. מומלץ לעקוב אחר העדכונים.

ש: יצרתי אפליקציה מדהימה של Web Audio API, אבל בכל פעם שהכרטיסייה שבה היא פועלת יושמעו ברקע, הקול נשמע מוזר!

תשובה: סביר להניח שהסיבה לכך היא שאתם משתמשים ב-setTimeouts, והתנהגות שונה אם הדף מופיע ברקע. בעתיד, תהיה ל-Web Audio API אפשרות לבצע קריאה חוזרת בשעות ספציפיות באמצעות הטיימר הפנימי של האודיו באינטרנט (מאפיין context.currentTime). מידע נוסף זמין במאמר בקשה להוספת תכונה.

באופן כללי, מומלץ להפסיק את ההפעלה כאשר האפליקציה עוברת לרקע. אפשר לזהות מתי דף עובר לרקע באמצעות ממשק API של חשיפת דף.

ש: כיצד ניתן לשנות את גובה הצליל באמצעות ממשק ה-API של Web Audio?

ת: שינוי של playbackRate בצומת המקור.

ש: אפשר לשנות את גובה הצליל בלי לשנות את המהירות?

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

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

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

ש: כיצד ניתן ליצור AudioContext בקצב דגימה לבחירתי?

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

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