كيف يتم دمج الجهاز مع مفاتيح الوسائط الخارجية وتخصيص إشعارات الوسائط والمزيد.
تم طرح واجهة برمجة تطبيقات جلسات الوسائط للسماح للمستخدمين بمعرفة المحتوى الذي يتم تشغيله حاليًا في المتصفّح والتحكم فيه بدون العودة إلى الصفحة التي أطلقته. وهي تسمح لمطوّري البرامج على الويب بتخصيص هذه التجربة من خلال البيانات الوصفية في إشعارات الوسائط المخصّصة، والفعاليات المتعلقة بالوسائط، مثل التشغيل والإيقاف المؤقت والبحث وتغيير تتبُّع أحداث ومؤتمرات الفيديو مثل كتم صوت/إعادة صوت الميكروفون وتشغيل/إيقاف الكاميرا وإنهاء المكالمة. وتتوفّر هذه التخصيصات في سياقات متعددة، بما في ذلك مراكز وسائط سطح المكتب وإشعارات الوسائط على الأجهزة الجوّالة وحتى على الأجهزة القابلة للارتداء. سأصف هذه التخصيصات في هذه المقالة.
![لقطات شاشة لسياقات جلسات تشغيل الوسائط](https://web.dev/static/articles/media-session/image/screenshots-media-sessio-f4629fe9ea633.jpg?authuser=6&hl=ar)
لمحة عن واجهة برمجة التطبيقات لجلسات الوسائط
توفّر واجهة برمجة التطبيقات لجلسة الوسائط العديد من المزايا والإمكانات:
- مفاتيح وسائط الأجهزة متوافقة.
- يتم تخصيص إشعارات الوسائط على الأجهزة الجوّالة والكمبيوتر المكتبي والأجهزة القابلة للارتداء المقترنة.
- يتوفر مركز الوسائط على أجهزة الكمبيوتر المكتبي.
- تتوفّر عناصر التحكّم في الوسائط على شاشة القفل على أجهزة ChromeOS والأجهزة الجوّالة.
- تتوفّر عناصر التحكّم في النوافذ ضمن ميزة "نافذة ضمن النافذة" لتشغيل الصوت ومؤتمرات الفيديو وعرض الشرائح.
- يمكن دمج "مساعد Google" على الأجهزة الجوّالة.
بعض الأمثلة ستوضح بعض هذه النقاط.
المثال 1: إذا ضغط المستخدمون على مفتاح الوسائط "المقطع الصوتي التالي" في لوحة المفاتيح، يمكن لمطوّري الويب معالجة هذا الإجراء سواء كان المتصفّح في المقدّمة أو في الخلفية.
المثال 2: إذا استمع المستخدمون إلى بودكاست على الويب عندما تكون شاشة أجهزتهم مقفلة، سيظل بإمكانهم النقر على رمز "الترجيع إلى الخلف" من عناصر التحكّم في الوسائط على شاشة القفل حتى يتمكّن مطوِّرو الويب من ترجيع وقت التشغيل ببضع ثوانٍ.
المثال 3: إذا كانت لدى المستخدمين علامات تبويب تشغِّل الصوت، يمكنهم بسهولة إيقاف التشغيل من مركز الوسائط على سطح المكتب حتى تتاح لمطوّري البرامج على الويب فرصة محو حالتهم.
مثال 4: إذا كان المستخدمون يجرون مكالمة فيديو، يمكنهم الضغط على عنصر التحكّم "تبديل الميكروفون" في نافذة "نافذة ضمن النافذة" لإيقاف الموقع الإلكتروني عن استلام بيانات الميكروفون.
تتم هذه العملية من خلال واجهتَين مختلفتَين: واجهة MediaSession
وMediaMetadata
الأول يتيح للمستخدمين التحكم
في أي شيء يتم تشغيله. والطريقة الثانية هي إخبار MediaSession
بما يجب التحكّم به.
للتوضيح، توضح الصورة أدناه كيفية ارتباط هذه الواجهات بعناصر تحكم معينة في الوسائط، وفي هذه الحالة إشعار وسائط على الهاتف المحمول.
![صورة توضيحية لواجهات جلسات تشغيل الوسائط](https://web.dev/static/articles/media-session/image/media-session-interfaces-c7bc0962a921c.jpg?authuser=6&hl=ar)
السماح للمستخدمين بمعرفة ما يتم تشغيله
عند تشغيل محتوى صوتي أو فيديو على موقع إلكتروني، يتلقّى المستخدمون إشعارات الوسائط تلقائيًا إما في قائمة الإشعارات على الأجهزة الجوّالة أو في مركز الوسائط على الكمبيوتر المكتبي. ويبذل المتصفح قصارى جهده لعرض المعلومات المناسبة باستخدام عنوان المستند وأكبر صورة رمز يمكنه العثور عليها. باستخدام واجهة برمجة التطبيقات 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>
ويمكنك أيضًا إضافة معلومات فصل فردي إلى البيانات الوصفية للوسائط، مثل عنوان القسم والطابع الزمني وصورة لقطة شاشة. ويسمح هذا للمستخدمين بالتنقل عبر محتوى الوسائط.
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](https://web.dev/static/articles/media-session/image/screenshot-notification-chapter.jpg?authuser=6&hl=ar)
السماح للمستخدمين بالتحكّم في المحتوى الذي يتم تشغيله
إجراء جلسة الوسائط هو إجراء (على سبيل المثال "تشغيل" أو "إيقاف مؤقت") يمكن أن يعالجه موقع
الويب للمستخدمين عندما يتفاعلون مع تشغيل الوسائط الحالي. الإجراءات تشبه الأحداث
وتعمل بنفس الطريقة التي تعمل بها إلى حد كبير. وتمامًا مثل الأحداث، يتم تنفيذ الإجراءات من خلال ضبط المعالِجات على عنصر مناسب، مثل MediaSession
، في هذه الحالة. يتم تشغيل بعض الإجراءات عندما يضغط المستخدمون على
الأزرار من سماعة رأس أو جهاز بعيد آخر أو لوحة مفاتيح أو عندما يتفاعلوا مع إشعار وسائط.
![لقطة شاشة لإشعار وسائط في نظام التشغيل Windows 10.](https://web.dev/static/articles/media-session/image/screenshot-a-media-notif-0b640cbe50bb1.jpg?authuser=6&hl=ar)
لأنّ بعض إجراءات جلسات الوسائط قد لا تتوفّر، ننصحك
باستخدام مجموعة 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.`);
}
بعد الضبط، ستستمر معالِجات إجراءات جلسات الوسائط خلال عمليات تشغيل الوسائط. وتتشابه هذه الطريقة مع نمط أداة معالجة الحدث، باستثناء أنّ التعامل مع حدث تعني أنّ المتصفّح يتوقف عن اتخاذ أي سلوك تلقائي ويستخدم ذلك كإشارة إلى أنّ الموقع الإلكتروني يتيح تنفيذ هذا الإجراء على الوسائط. وبالتالي، لن يتم عرض عناصر التحكم في إجراءات الوسائط ما لم يتم تعيين معالج الإجراءات المناسب.
![لقطة شاشة لأداة "التعرّف التلقائي على الموسيقى" في macOS Big Sur.](https://web.dev/static/articles/media-session/image/screenshot-the-playing-178373d8aea09.jpg?authuser=6&hl=ar)
التشغيل / الإيقاف المؤقت
يشير الإجراء "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](https://web.dev/static/articles/media-session/image/screenshot-lock-screen-m-e71582de5ca3d.jpg?authuser=6&hl=ar)
يجب تحديد المدة وأن تكون موجبة. يجب أن يكون الموضع موجبًا وأقل من المدة. يجب أن يكون معدل التشغيل أكبر من 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);
إجراءات اجتماعات الفيديو
عندما يضع المستخدم مكالمة الفيديو في نافذة ميزة "نافذة ضمن النافذة"، قد يعرض المتصفح عناصر التحكم في الميكروفون والكاميرا ولإنهاء المكالمة. عندما ينقر المستخدم عليها، سيعالجها موقع الويب من خلال إجراءات مؤتمرات الفيديو أدناه. على سبيل المثال، يمكنك الاطّلاع على نموذج اجتماع الفيديو.
![لقطة شاشة لعناصر التحكّم في اجتماع الفيديو في نافذة ميزة "نافذة ضمن النافذة".](https://web.dev/static/articles/media-session/image/screenshot-video-confere-7e82acef00cdb.jpg?authuser=6&hl=ar)
إيقاف/تفعيل الميكروفون
يشير الإجراء "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.
});
إجراءات مشاركة العروض التقديمية
عندما يضع المستخدم العرض التقديمي للشرائح في نافذة نافذة ضمن النافذة، قد يعرض المتصفح عناصر تحكم للتنقل عبر الشرائح. عندما ينقر المستخدم عليها، سيعالجها الموقع من خلال واجهة برمجة تطبيقات جلسات الوسائط. للحصول على مثال، يمكنك الاطّلاع على نموذج مشاركة العروض التقديمية.
الشريحة السابقة
يشير إجراء "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 وأعمال "جان مورغنسترن".
المراجع
- مواصفات جلسة الوسائط: wicg.github.io/mediasession
- المشاكل في المواصفات: github.com/WICG/mediasession/issues
- أخطاء Chrome : crbug.com