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

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

שאלה: אי אפשר ליצור צלילים!

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

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

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

שאלה: יש לי 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 להטמיע קריאה חוזרת מדויקת יותר.

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

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

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

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

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

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

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

שאלה: איך אפשר לשנות את גובה הצליל של צליל באמצעות Web Audio API?

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

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

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

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

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

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

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

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