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

טום גרינוויי
הונגצ'אן צ'וי

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

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

אנחנו מתכננים להשיק את השינוי הזה במדיניות ב-Chrome 71 בדצמבר 2018.

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

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

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

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

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

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

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

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

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

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

עיכוב השינוי לצורך תמיכה בקהילה

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

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

כמו כן, לקחנו את הזמן הזה:

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

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

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

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

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

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

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

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

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

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

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

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

    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. AudioNodes שמטמיעים את הממשק AudioScheduledSourceNode, מכונים בדרך כלל צומתי מקור (כגון AudioBufferSourceNode, ConstantSourceNode ו-OscillatorNode). צומתי המקור מטמיעים שיטת start() .

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

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

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

  • המשתמש יצר אינטראקציה עם דף כלשהו.
  • שיטת ה-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.

משוב