בעזרת ה-Media Session API, אפשר להתאים אישית את ההתראות של המדיה ואת פקדי ההפעלה

איך משתלבים עם מפתחות מדיה בחומרה, מתאימים אישית התראות מדיה ועוד.

François Beaufort
François Beaufort

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

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

מידע על Media Session API

ל-Media session API יש כמה יתרונות ויכולות:

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

תמיכה בדפדפנים

  • Chrome: 73.
  • Edge:‏ 79.
  • Firefox: 82.
  • Safari: 15.

מקור

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

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

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

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

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

אפשר לעשות את זה דרך שני ממשקים שונים: הממשק MediaSession והממשק MediaMetadata. האפשרות הראשונה מאפשרת למשתמשים לשלוט במה שמופעל. השני הוא איך אומרים ל-MediaSession מה צריך לשלוט בו.

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

איור של ממשקי Media Session.
המבנה של התראה על מדיה בנייד.

מודיע למשתמשים מה מושמע

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

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

// After media (video or audio) starts playing
await document.querySelector("video").play();

if ("mediaSession" in navigator) {
  navigator.mediaSession.metadata = new MediaMetadata({
    title: 'Never Gonna Give You Up',
    artist: 'Rick Astley',
    album: 'Whenever You Need Somebody',
    artwork: [
      { src: 'https://via.placeholder.com/96',   sizes: '96x96',   type: 'image/png' },
      { src: 'https://via.placeholder.com/128', sizes: '128x128', type: 'image/png' },
      { src: 'https://via.placeholder.com/192', sizes: '192x192', type: 'image/png' },
      { src: 'https://via.placeholder.com/256', sizes: '256x256', type: 'image/png' },
      { src: 'https://via.placeholder.com/384', sizes: '384x384', type: 'image/png' },
      { src: 'https://via.placeholder.com/512', sizes: '512x512', type: 'image/png' },
    ]
  });

  // TODO: Update playback state.
}

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

יש כמה דברים שכדאי לזכור לגבי המטא-נתונים של המדיה.

  • מערך הגרפיקה של ההתראות תומך בכתובות URL של blob ובכתובות URL של נתונים.
  • אם לא מגדירים גרפיקה ויש תמונה של סמל (שצוינה באמצעות <link rel=icon>) בגודל הרצוי, המערכת תשתמש בה בהתראות על מדיה.
  • גודל היעד של גרפיקה של התראות ב-Chrome ל-Android הוא 512x512. במכשירים בסיסיים, הערך הוא 256x256.
  • המאפיין title של רכיב ה-HTML של המדיה משמש בווידג'ט 'השיר/הסרטון שמתנגן עכשיו' ב-macOS.
  • אם משאב המדיה מוטמע (למשל ב-iframe), יש להגדיר את פרטי ה-Media Session API מההקשר המוטמע. קטע הקוד לדוגמה מופיע בהמשך.
<iframe id="iframe">
  <video>...</video>
</iframe>
<script>
  iframe.contentWindow.navigator.mediaSession.metadata = new MediaMetadata({
    title: 'Never Gonna Give You Up',
    ...
  });
</script>

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

navigator.mediaSession.metadata = new MediaMetadata({
  // title, artist, album, artwork, ...
  chapterInfo: [{
    title: 'Chapter 1',
    startTime: 0,
    artwork: [
      { src: 'https://via.placeholder.com/128', sizes: '128x128', type: 'image/png' },
      { src: 'https://via.placeholder.com/512', sizes: '512x512', type: 'image/png' },
    ]
  }, {
    title: 'Chapter 2',
    startTime: 42,
    artwork: [
      { src: 'https://via.placeholder.com/128', sizes: '128x128', type: 'image/png' },
      { src: 'https://via.placeholder.com/512', sizes: '512x512', type: 'image/png' },
    ]
  }]
});
פרטי הפרק מוצגים בהתראה על מדיה ב-ChromeOS.
התראה על מדיה שכוללת פרקים ב-ChromeOS.

המשתמשים יכולים לשלוט בתוכן המושמע

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

צילום מסך של התראת מדיה ב-Windows 10.
התראות מדיה מותאמות אישית ב-Windows 10

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

const actionHandlers = [
  ['play',          () => { /* ... */ }],
  ['pause',         () => { /* ... */ }],
  ['previoustrack', () => { /* ... */ }],
  ['nexttrack',     () => { /* ... */ }],
  ['stop',          () => { /* ... */ }],
  ['seekbackward',  (details) => { /* ... */ }],
  ['seekforward',   (details) => { /* ... */ }],
  ['seekto',        (details) => { /* ... */ }],
  /* Video conferencing actions */
  ['togglemicrophone', () => { /* ... */ }],
  ['togglecamera',     () => { /* ... */ }],
  ['hangup',           () => { /* ... */ }],
  /* Presenting slides actions */
  ['previousslide', () => { /* ... */ }],
  ['nextslide',     () => { /* ... */ }],
];

for (const [action, handler] of actionHandlers) {
  try {
    navigator.mediaSession.setActionHandler(action, handler);
  } catch (error) {
    console.log(`The media session action "${action}" is not supported yet.`);
  }
}

כדי לבטל את ההגדרה של בורר הפעולות של סשן המדיה, פשוט מגדירים אותו כ-null.

try {
  // Unset the "nexttrack" action handler at the end of a playlist.
  navigator.mediaSession.setActionHandler('nexttrack', null);
} catch (error) {
  console.log(`The media session action "nexttrack" is not supported yet.`);
}

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

צילום מסך של הווידג&#39;ט &#39;התכנים המוצגים כרגע&#39; ב-macOS Big Sur.
הווידג'ט 'המושמע עכשיו' ב-macOS Big Sur.

הפעלה / השהיה

הפעולה "play" מציינת שהמשתמש רוצה להמשיך את הפעלת המדיה, ואילו הפעולה "pause" מציינת רצון להשהות אותה באופן זמני.

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

לדוגמה, יכול להיות שהדפדפן יקבע שהאתר לא מפעיל מדיה בזמן דילוג או טעינת תוכן. במקרה כזה, אפשר לשנות את ההתנהגות הזו על ידי הגדרת navigator.mediaSession.playbackState לערך "playing" או לערך "paused" כדי לוודא שממשק המשתמש של האתר ימשיך להסתנכרן עם פקדי ההתראות של המדיה.

const video = document.querySelector('video');

navigator.mediaSession.setActionHandler('play', async () => {
  // Resume playback
  await video.play();
});

navigator.mediaSession.setActionHandler('pause', () => {
  // Pause active playback
  video.pause();
});

video.addEventListener('play', () => {
  navigator.mediaSession.playbackState = 'playing';
});

video.addEventListener('pause', () => {
  navigator.mediaSession.playbackState = 'paused';
});

הטראק הקודם

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

navigator.mediaSession.setActionHandler('previoustrack', () => {
  // Play previous track.
});

הטראק הבא

הפעולה "nexttrack" מציינת שהמשתמש רוצה להעביר את הפעלת המדיה לפריט הבא בפלייליסט, אם הפעלת המדיה כוללת פלייליסט.

navigator.mediaSession.setActionHandler('nexttrack', () => {
  // Play next track.
});

עצירה

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

navigator.mediaSession.setActionHandler('stop', () => {
  // Stop playback and clear state if appropriate.
});

הרצה אחורה / קדימה

הפעולה "seekbackward" מציינת שהמשתמש רוצה להזיז את זמן ההפעלה של המדיה אחורה בפרק זמן קצר, ואילו הפעולה "seekforward" מציינת רצון להזיז את זמן ההפעלה של המדיה קדימה בפרק זמן קצר. בשני המקרים, תקופה קצרה היא כמה שניות.

הערך seekOffset שצוין ב-handler של הפעולות הוא הזמן בשניות עד להעברת זמן ההפעלה של המדיה. אם הוא לא מופיע (לדוגמה undefined), צריך להשתמש בטווח זמן סביר (למשל 10 עד 30 שניות).

const video = document.querySelector('video');
const defaultSkipTime = 10; /* Time to skip in seconds by default */

navigator.mediaSession.setActionHandler('seekbackward', (details) => {
  const skipTime = details.seekOffset || defaultSkipTime;
  video.currentTime = Math.max(video.currentTime - skipTime, 0);
  // TODO: Update playback state.
});

navigator.mediaSession.setActionHandler('seekforward', (details) => {
  const skipTime = details.seekOffset || defaultSkipTime;
  video.currentTime = Math.min(video.currentTime + skipTime, video.duration);
  // TODO: Update playback state.
});

דילוג לזמן ספציפי

הפעולה "seekto" מציינת שהמשתמש רוצה להעביר את הזמן של הפעלת המדיה לשעה ספציפית.

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

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

const video = document.querySelector('video');

navigator.mediaSession.setActionHandler('seekto', (details) => {
  if (details.fastSeek && 'fastSeek' in video) {
    // Only use fast seek if supported.
    video.fastSeek(details.seekTime);
    return;
  }
  video.currentTime = details.seekTime;
  // TODO: Update playback state.
});

הגדרת מיקום ההפעלה

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

צילום מסך של פקדי המדיה במסך הנעילה ב-ChromeOS.
אמצעי הבקרה על המדיה במסך הנעילה ב-ChromeOS.

משך הזמן חייב להיות חיובי. המיקום חייב להיות חיובי וקטן מהמשך הזמן. קצב ההפעלה חייב להיות גדול מ-0.

const video = document.querySelector('video');

function updatePositionState() {
  if ('setPositionState' in navigator.mediaSession) {
    navigator.mediaSession.setPositionState({
      duration: video.duration,
      playbackRate: video.playbackRate,
      position: video.currentTime,
    });
  }
}

// When video starts playing, update duration.
await video.play();
updatePositionState();

// When user wants to seek backward, update position.
navigator.mediaSession.setActionHandler('seekbackward', (details) => {
  /* ... */
  updatePositionState();
});

// When user wants to seek forward, update position.
navigator.mediaSession.setActionHandler('seekforward', (details) => {
  /* ... */
  updatePositionState();
});

// When user wants to seek to a specific time, update position.
navigator.mediaSession.setActionHandler('seekto', (details) => {
  /* ... */
  updatePositionState();
});

// When video playback rate changes, update position state.
video.addEventListener('ratechange', (event) => {
  updatePositionState();
});

איפוס מצב המיקום מתבצע בקלות וניתן להגדיר אותו ל-null.

// Reset position state when media is reset.
navigator.mediaSession.setPositionState(null);

פעולות בשיחות ועידה בווידאו

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

צילום מסך של אמצעי הבקרה של שיתוף המסך בחלון מסוג &#39;תמונה בתוך תמונה&#39;.
פקדים של שיחות ועידה בווידאו בחלון 'תמונה בתוך תמונה'.

החלפת מצב מיקרופון

הפעולה "togglemicrophone" מציינת שהמשתמש רוצה להשתיק או לבטל את ההשתקה של המיקרופון. ה-method setMicrophoneActive(isActive) מנחה את הדפדפן אם האתר מחשיב כרגע את המיקרופון כפעיל.

let isMicrophoneActive = false;

navigator.mediaSession.setActionHandler('togglemicrophone', () => {
  if (isMicrophoneActive) {
    // Mute the microphone.
  } else {
    // Unmute the microphone.
  }
  isMicrophoneActive = !isMicrophoneActive;
  navigator.mediaSession.setMicrophoneActive(isMicrophoneActive);
});

החלפת המצב של המצלמה

הפעולה "togglecamera" מציינת שהמשתמש רוצה להפעיל או להשבית את המצלמה הפעילה. השיטה setCameraActive(isActive) מציינת אם הדפדפן מחשיב את האתר כפעיל.

let isCameraActive = false;

navigator.mediaSession.setActionHandler('togglecamera', () => {
  if (isCameraActive) {
    // Disable the camera.
  } else {
    // Enable the camera.
  }
  isCameraActive = !isCameraActive;
  navigator.mediaSession.setCameraActive(isCameraActive);
});

ניתוק

הפעולה "hangup" מציינת שהמשתמש רוצה לסיים שיחה.

navigator.mediaSession.setActionHandler('hangup', () => {
  // End the call.
});

פעולות של הצגת שקפים

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

השקף הקודם

הפעולה "previousslide" מציינת שהמשתמש רוצה לחזור לשקף הקודם במהלך הצגת שקפים.

navigator.mediaSession.setActionHandler('previousslide', () => {
  // Show previous slide.
});

תמיכה בדפדפנים

  • Chrome: ‏ 111.
  • Edge:‏ 111.
  • Firefox: לא נתמך.
  • Safari: לא נתמך.

השקף הבא

הפעולה "nextslide" מציינת שהמשתמש רוצה לעבור לשקף הבא במהלך הצגת שקפים.

navigator.mediaSession.setActionHandler('nextslide', () => {
  // Show next slide.
});

תמיכה בדפדפנים

  • Chrome: ‏ 111.
  • Edge:‏ 111.
  • Firefox: לא נתמך.
  • Safari: לא נתמך.

דוגמאות

כדאי לעיין בדוגמאות ל-Media Session שכוללות את Blender Foundation והעבודה של Jan Morgenstern.

הקלטת מסך שממחישה את Media Session API.

משאבים