تخصيص إشعارات الوسائط وعناصر التحكّم في التشغيل باستخدام واجهة برمجة التطبيقات Media session API

كيفية الدمج مع مفاتيح وسائط الأجهزة وتخصيص إشعارات الوسائط والمزيد

فرانسوا بوفورت
"فرانسوا بوفورت"

تم إطلاق واجهة برمجة التطبيقات لجلسات الوسائط من أجل السماح للمستخدمين بمعرفة المحتوى الذي يتم تشغيله حاليًا في المتصفح والتحكّم فيه بدون العودة إلى الصفحة التي تم تشغيلها. وهي تتيح لمطوّري برامج الويب تخصيص هذه التجربة من خلال البيانات الوصفية في إشعارات الوسائط المخصّصة، وأحداث الوسائط مثل التشغيل والإيقاف المؤقت، والبحث، وتغيير التتبع، وأحداث اجتماعات الفيديو مثل كتم صوت/إعادة صوت الميكروفون، وتشغيل/إيقاف الكاميرا، وإنهاء المكالمة. وتتوفّر عمليات التخصيص هذه في سياقات متعددة، بما في ذلك مراكز وسائط سطح المكتب وإشعارات الوسائط على الأجهزة الجوّالة وحتى على الأجهزة القابلة للارتداء. سأصف هذه التخصيصات في هذه المقالة.

لقطات شاشة لسياقات جلسات تشغيل الوسائط
مركز الوسائط على الكمبيوتر المكتبي، وإشعار الوسائط على الجهاز الجوّال، وجهاز قابل للارتداء.

لمحة عن واجهة برمجة التطبيقات لجلسة الوسائط

توفّر واجهة برمجة التطبيقات لجلسات الوسائط عدة مزايا وإمكانات:

  • مفاتيح وسائط الأجهزة متوافقة.
  • يتم تخصيص إشعارات الوسائط على الأجهزة الجوّالة وأجهزة الكمبيوتر المكتبي والأجهزة المقترنة القابلة للارتداء.
  • يتوفّر مركز الوسائط على أجهزة الكمبيوتر المكتبي.
  • تتوفّر عناصر التحكّم في وسائط شاشة القفل على ChromeOS والأجهزة الجوّالة.
  • تتوفّر عناصر التحكّم في نافذة ميزة "نافذة ضمن النافذة" لتشغيل الصوت ومؤتمرات الفيديو وتقديم الشرائح.
  • تتوفر إمكانية دمج "مساعد Google" على الأجهزة الجوّالة.

التوافق مع المتصفح

  • 73
  • 79
  • 82
  • 15

المصدر

فيما يلي بعض الأمثلة لتوضيح بعض هذه النقاط.

المثال 1: إذا ضغط المستخدمون على مفتاح الوسائط "المقطع الصوتي التالي" من لوحة المفاتيح، يمكن لمطوّري الويب معالجة إجراء المستخدم هذا سواء كان المتصفّح في المقدّمة أو في الخلفية.

المثال 2: إذا يستمع المستخدمون إلى بودكاست على الويب عندما تكون شاشة أجهزتهم مقفلة، سيظل بإمكانهم النقر على رمز "الترجيع إلى الخلف" من عناصر التحكم في الوسائط على شاشة القفل حتى يتمكّن مطوّرو الويب من إرجاع وقت التشغيل إلى الخلف بضع ثوانٍ.

المثال 3: إذا كانت لدى المستخدمين علامات تبويب تشغّل الصوت، يمكنهم بسهولة إيقاف التشغيل من مركز الوسائط على جهاز كمبيوتر سطح المكتب حتى تتاح لمطوّري برامج الويب فرصة إخلاء حالتهم.

مثال 4: إذا كان المستخدمون يجرون مكالمة فيديو، يمكنهم الضغط على عنصر التحكّم "تبديل الميكروفون" في نافذة "نافذة ضمن النافذة" لمنع الموقع الإلكتروني من تلقّي بيانات الميكروفون.

يتم ذلك من خلال واجهتَين مختلفتَين: واجهة MediaSession وMediaMetadata. الأول يتيح للمستخدمين التحكم في كل ما يتم تشغيله. الطريقة الثانية هي إخبار MediaSession بما يجب التحكّم به.

للتوضيح، توضّح الصورة أدناه كيفية ارتباط هذه الواجهات بعناصر تحكم معينة في الوسائط، وهي في هذه الحالة إشعار وسائط على الجوّال.

صورة توضيحية لواجهات جلسات تشغيل الوسائط
بنية إشعار الوسائط على الأجهزة الجوّالة

إطلاع المستخدمين على ما يتم تشغيله

عند تشغيل صوت أو فيديو على موقع إلكتروني، يتلقّى المستخدمون تلقائيًا إشعارات الوسائط، سواء في لوحة الإشعارات على الجهاز الجوّال أو في مركز الوسائط على الكمبيوتر المكتبي. ويبذل المتصفّح قصارى جهده لعرض المعلومات المناسبة باستخدام عنوان المستند وأكبر صورة رمز يمكن العثور عليها. باستخدام واجهة برمجة التطبيقات 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 للنقاط الثنائية الكبيرة وعناوين URL للبيانات.
  • إذا لم يتم تحديد أي عمل فني وكانت هناك صورة رمز (محددة باستخدام <link rel=icon>) بالحجم المطلوب، ستستخدمه إشعارات الوسائط.
  • الحجم المستهدف للأعمال الفنية للإشعارات في Chrome لنظام Android هو 512x512. بالنسبة للأجهزة المنخفضة، هو 256x256.
  • يتم استخدام السمة title لعنصر HTML للوسائط في تطبيق macOS المصغّر "يجري التشغيل الآن".
  • إذا كان مورد الوسائط مضمّنًا (على سبيل المثال في إطار iframe)، يجب ضبط معلومات واجهة برمجة التطبيقات لجلسات الوسائط من السياق المضمّن. يُرجى الاطّلاع على المقتطف أدناه.
<iframe id="iframe">
  <video>...</video>
</iframe>
<script>
  iframe.contentWindow.navigator.mediaSession.metadata = new MediaMetadata({
    title: 'Never Gonna Give You Up',
    ...
  });
</script>

السماح للمستخدمين بالتحكّم في المحتوى الذي يتم تشغيله

إجراء جلسة الوسائط هو إجراء (على سبيل المثال "تشغيل" أو "إيقاف مؤقت") يمكن لموقع الويب التعامل معه للمستخدمين عندما يتفاعلون مع تشغيل الوسائط الحالية. الإجراءات مماثلة للأحداث وتعمل بنفس طريقة العمل. ومثل الأحداث، يتم تنفيذ الإجراءات من خلال ضبط المعالجات على كائن مناسب، مثل 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.`);
}

وبعد ضبط الإعدادات، ستستمر معالِجات إجراءات جلسة الوسائط خلال عمليات تشغيل الوسائط. ويشبه ذلك نمط أداة معالجة الحدث، باستثناء أنّ معالجة حدث تعني أنّ المتصفّح يتوقّف عن القيام بأي سلوك تلقائي ويستخدم ذلك كإشارة إلى أنّ الموقع الإلكتروني يتيح تنفيذ إجراء الوسائط. وبالتالي، لن يتم عرض عناصر التحكم في إجراءات الوسائط ما لم يتم تعيين معالج الإجراءات المناسب.

لقطة شاشة للتطبيق المصغّر &quot;التعرّف التلقائي على الموسيقى&quot; في 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 المقدَّمة في معالج الإجراءات هي الوقت بالثواني الذي يتم خلاله نقل وقت تشغيل الوسائط. وإذا لم يتم تقديمه (على سبيل المثال 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 المنطقية المتوفّرة في معالج الإجراءات تكون صحيحة إذا كان يتم استدعاء الإجراء عدة مرات كجزء من التسلسل وليس هذا الطلب الأخير في ذلك التسلسل.

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);

إجراءات اجتماعات الفيديو

عندما يضع المستخدم مكالمة الفيديو في نافذة نافذة ضمن النافذة، قد يعرض المتصفح عناصر التحكم في الميكروفون والكاميرا ولإنهاء المكالمة. عندما ينقر المستخدم عليها، سيعالجها موقع الويب من خلال إجراءات مؤتمرات الفيديو أدناه. على سبيل المثال، راجع نموذج اجتماع الفيديو.

لقطة شاشة لعناصر التحكّم في اجتماع الفيديو في نافذة &quot;نافذة ضمن النافذة&quot;
عناصر التحكّم الخاصة باجتماعات الفيديو في نافذة ضمن النافذة

إيقاف/تفعيل الميكروفون

يشير الإجراء "togglemicrophone" إلى أنّ المستخدم يريد كتم صوت الميكروفون أو إعادته. تحدّد الطريقة 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.
});

إجراءات مشاركة العروض التقديمية

عندما يضع المستخدم العرض التقديمي في نافذة "نافذة ضمن النافذة"، قد يعرض المتصفح عناصر تحكم للتنقل عبر الشرائح. عندما ينقر المستخدم عليها، سيعالجها الموقع من خلال واجهة برمجة تطبيقات جلسة الوسائط. للحصول على مثال، راجِع نموذج مشاركة "العروض التقديمية من Google".

الشريحة السابقة

يشير إجراء "previousslide" إلى أن المستخدم يريد العودة إلى الشريحة السابقة عند تقديم الشرائح.

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

التوافق مع المتصفح

  • 111
  • 111
  • x
  • x

الشريحة التالية

يشير الإجراء "nextslide" إلى أن المستخدم يريد الانتقال إلى الشريحة التالية عند تقديم الشرائح.

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

التوافق مع المتصفح

  • 111
  • 111
  • x
  • x

عيّنات

يمكنك الاطّلاع على بعض عيّنات الجلسات الإعلامية التي شارك فيها Blender Foundation وأعمال "جان مورغنسترن".

تسجيل رقمي للشاشة يوضّح واجهة برمجة التطبيقات لجلسات الوسائط.

المراجِع