אודיו באינטרנט, מדיניות הפעלה אוטומטית ומשחקים

Tom Greenaway
Hongchan Choi

בספטמבר 2017 הודענו על שינוי שיחול בקרוב באופן שבו נעבד אודיו בהתאם למדיניות ההתנהגות של הפעלה אוטומטית ב-Chrome. שינוי המדיניות פורסם ב-Chrome 66 Stable במאי 2018.

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

שינוי המדיניות הזה מתוכנן עכשיו להשקה עם גרסה 71 של Chrome בדצמבר 2018.

מהו בדיוק השינוי במדיניות?

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

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

בנוסף, הוספנו שיטת ניתוח (heuristic) כדי ללמוד מהתנהגות קודמת של משתמשים לגבי אתרים שמפעילים אודיו באופן אוטומטי. אנחנו מזהים מקרים שבהם משתמשים מאפשרים באופן קבוע להפעיל אודיו למשך יותר מ-7 שניות במהלך רוב הביקורים שלהם באתר, ומפעילים את ההפעלה האוטומטית באתר הזה.

אנחנו עושים זאת באמצעות אינדקס שנשמר באופן מקומי לכל פרופיל Chrome במכשיר – הוא לא מסתנכרן בין מכשירים, והוא משותף רק כחלק מנתונים סטטיסטיים אנונימיים של משתמשים. האינדקס הזה נקרא 'מדד ההתעניינות במדיה' (MEI), וניתן להציג אותו בכתובת chrome://media-engagement.

המדד MEI עוקב אחרי מספר הביקורים באתר שכוללים הפעלת אודיו באורך של יותר מ-7 שניות. על סמך MEI של משתמש, אנחנו מאמינים שאנחנו יכולים להבין אם המשתמש מצפה לאודיו מאתר מסוים או לא – ולחזות את כוונת המשתמש בעתיד.

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

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

גם השימוש ברכיבי HTML של מדיה (וידאו ואודיו) וגם השימוש ב-Web Audio (אובייקטים של AudioContext שנוצרו ב-JavaScript) ישפיעו על MEI. לקראת ההשקה של המדיניות הזו, התנהגות המשתמשים ביחס ל-Web Audio תתחיל להשפיע על ה-MEI מ-Chrome 70 ואילך. כך נוכל כבר לצפות את הכוונה הרצויה של המשתמש בנוגע להפעלה האוטומטית ולאתרים שבהם הוא מבקר לעיתים קרובות.

חשוב לציין שפריטי iframe יכולים לקבל את הזכות להפעלה אוטומטית ללא אינטראקציה מצד המשתמש רק אם דף האינטרנט הראשי שבו מוטמע ה-iframe מרחיב את הזכות הזו ל-iframe הנתון.

דחיית השינוי כדי לתמוך בקהילה

קהילת המפתחים של Web Audio – במיוחד החלק של מפתחי משחקים באינטרנט ומפתחי WebRTC בקהילה הזו – שמה לב לשינוי הזה כשהופיע בערוץ Chrome Stable.

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

בנוסף, נצלנו את הזמן הזה כדי:

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

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

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

ביצענו גם שינוי כדי לתמוך באפליקציות WebRTC. כשיש סשן צילום פעיל, ההפעלה האוטומטית תהיה מותרת.

מהי הבעיה ששינוי ההתנהגות הזה נועד לפתור?

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

עם זאת, לפעמים המשתמשים רוצים שהתוכן יופעל באופן אוטומטי, ומספר משמעותי של הפעלות אוטומטיות שחוסמו ב-Chrome מופעלות על ידי המשתמש בהמשך.

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

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

התאמות חדשות שיעזרו למפתחי משחקי אינטרנט

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

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

    const context = new AudioContext();

    // Setup an audio graph with AudioNodes and schedule playback.
    ...

    // Resume AudioContext playback when user clicks a button on the page.
    document.querySelector('button').addEventListener('click', function() {
      context.resume().then(() => {
        console.log('AudioContext playback resumed successfully');
      });
    });

יש הרבה ממשקים שעוברים בירושה מ-AudioNode, אחד מהם הוא הממשק AudioScheduledSourceNode. רכיבי AudioNode שמטמיעים את הממשק AudioScheduledSourceNode נקראים בדרך כלל צומתי מקור (כמו AudioBufferSourceNode,‏ ConstantSourceNode ו-OscillatorNode). צמתים מקור מטמיעים את ה-method‏ start().

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

אחרי שזיהינו את התבנית הנפוצה הזו במשחקים באינטרנט, החלטנו לשנות את ההטמעה שלנו באופן הבא:

הפעלת AudioContext תתחדש באופן אוטומטי כששני התנאים הבאים מתקיימים:

  • המשתמש יצר אינטראקציה עם דף.
  • מתבצעת קריאה ל-method‏ start() של צומת מקור.

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

איך אנחנו מקדמים את האינטרנט

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

עם זאת, אנחנו מבינים שלא תמיד אפשר להחיל תיקונים לאתרים בטווח הקצר מסיבות שונות:

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

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

(function () {
  // An array of all contexts to resume on the page
  const audioContextList = [];

  // An array of various user interaction events we should listen for
  const userInputEventNames = [
    'click',
    'contextmenu',
    'auxclick',
    'dblclick',
    'mousedown',
    'mouseup',
    'pointerup',
    'touchend',
    'keydown',
    'keyup',
  ];

  // A proxy object to intercept AudioContexts and
  // add them to the array for tracking and resuming later
  self.AudioContext = new Proxy(self.AudioContext, {
    construct(target, args) {
      const result = new target(...args);
      audioContextList.push(result);
      return result;
    },
  });

  // To resume all AudioContexts being tracked
  function resumeAllContexts(event) {
    let count = 0;

    audioContextList.forEach(context => {
      if (context.state !== 'running') {
        context.resume();
      } else {
        count++;
      }
    });

    // If all the AudioContexts have now resumed then we
    // unbind all the event listeners from the page to prevent
    // unnecessary resume attempts
    if (count == audioContextList.length) {
      userInputEventNames.forEach(eventName => {
        document.removeEventListener(eventName, resumeAllContexts);
      });
    }
  }

  // We bind the resume function for each user interaction
  // event on the page
  userInputEventNames.forEach(eventName => {
    document.addEventListener(eventName, resumeAllContexts);
  });
})();

חשוב לציין שקטע הקוד הזה לא יעזור בהמשך של AudioContexts שנוצרו בתוך iframe, אלא אם קטע הקוד הזה נכלל בהיקף התוכן של ה-iframe עצמו.

שירות טוב יותר למשתמשים שלנו

במקביל לשינוי המדיניות, אנחנו משיקים גם מנגנון שמאפשר למשתמשים להשבית את המדיניות בנושא הפעלה אוטומטית. המנגנון הזה מיועד למקרים שבהם למידת המכונה לא פועלת כצפוי, או לאתרים שהשינוי הופך אותם לבלתי ניתנים לשימוש. השינוי הזה יושק עם המדיניות החדשה ב-Chrome 71, ותוכלו למצוא אותו בהגדרות האודיו. אתרים שבהם המשתמש רוצה לאפשר הפעלה אוטומטית אפשר להוסיף לרשימת ההיתרים.

איך נוצר ה-MEI למשתמשים חדשים?

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

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

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

איך מוצאים את האיזון

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

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

משוב