تحتوي هذه الصفحة على مقتطفات رموز وأوصاف للميزات المتاحة لتطبيق "أداة استقبال الويب المخصَّصة".
- يمثّل العنصر
cast-media-player
واجهة المستخدم الخاصة بالمشغّل المضمّن المتوفّرة مع "جهاز استقبال الويب". - نمط مخصص يشبه CSS للعنصر
cast-media-player
لتنسيق عناصر واجهة مستخدم مختلفة مثلbackground-image
وsplash-image
وfont-family
. - عنصر نص برمجي لتحميل إطار عمل جهاز استقبال الويب.
- رمز JavaScript لاعتراض الرسائل ومعالجة الأحداث
- قائمة انتظار التشغيل التلقائي.
- خيارات لإعداد التشغيل
- خيارات ضبط سياق جهاز استقبال الويب
- خيارات لضبط الأوامر التي يتيحها تطبيق Web Receiver.
- طلب اتصال JavaScript لبدء تطبيق Web Receiver.
إعدادات التطبيق وخياراته
إعداد التطبيق
CastReceiverContext
هي الفئة الخارجية التي تظهر للمطوّر، وتدير تحميل المكتبات الأساسية وتعالج عملية إعداد حزمة تطوير برامج استقبال الويب. توفِّر حزمة تطوير البرامج (SDK)
واجهات برمجة تطبيقات تسمح لمطوّري التطبيقات بضبط حزمة تطوير البرامج (SDK) من خلال
CastReceiverOptions
.
يتم تقييم عمليات الضبط هذه مرة واحدة لكل عملية تشغيل للتطبيق، ويتم تمريرها إلى
حزمة تطوير البرامج (SDK) عند ضبط المَعلمة الاختيارية في الطلب
start
.
يوضِّح المثال أدناه كيفية تجاوز السلوك التلقائي لرصد ما إذا كان
اتصال المُرسِل لا يزال متصلاً بشكل نشط. عندما يتعذّر على "جهاز استقبال الويب"
التواصل مع المُرسِل لمدة
maxInactivity
ثانية، يتم إرسال حدث SENDER_DISCONNECTED
. يلغي الإعداد أدناه
هذه المهلة. ويمكن أن يكون ذلك مفيدًا عند تصحيح الأخطاء لأنّ ذلك يمنع تطبيق "جهاز استقبال الويب" من إغلاق جلسة "برنامج تصحيح الأخطاء عن بُعد من Chrome" عندما لا يكون هناك أي مُرسِلين متصلين في حالة IDLE
.
const context = cast.framework.CastReceiverContext.getInstance();
const options = new cast.framework.CastReceiverOptions();
options.maxInactivity = 3600; // Development only
context.start(options);
تهيئة المشغّل
عند تحميل المحتوى، توفّر حزمة تطوير البرامج (SDK) لمستلِم الويب طريقة لضبط متغيّرات التشغيل، مثل معلومات إدارة الحقوق الرقمية وإعادة محاولة الضبط ومعالجات الطلبات باستخدام cast.framework.PlaybackConfig
.
تعالج PlayerManager
هذه المعلومات ويتم تقييمها في وقت إنشاء اللاعبين. يتم إنشاء المشغلات في كل مرة يتم فيها تمرير تحميل جديد إلى حزمة تطوير البرامج (SDK) لأداة استقبال الويب. ويتم تقييم التعديلات على
PlaybackConfig
بعد إنشاء المشغّل في تحميل المحتوى التالي. توفّر حزمة تطوير البرامج (SDK) الطرق التالية لتعديل
PlaybackConfig
.
CastReceiverOptions.playbackConfig
لإلغاء خيارات الضبط التلقائية عند إعدادCastReceiverContext
.PlayerManager.getPlaybackConfig()
للحصول على الإعدادات الحالية.PlayerManager.setPlaybackConfig()
لإلغاء الإعدادات الحالية. ويتم تطبيق هذا الإعداد على جميع عمليات التحميل اللاحقة أو حتى يتم تجاوزه مرة أخرى.PlayerManager.setMediaPlaybackInfoHandler()
لتطبيق إعدادات إضافية على عنصر الوسائط الذي يتم تحميله أعلى الإعدادات الحالية. يسمى المعالج قبل إنشاء اللاعب مباشرةً. إنّ التغييرات التي يتم إجراؤها هنا ليست دائمة ولا يتم تضمينها في طلبات البحث المرسَلة إلىgetPlaybackConfig()
. عند تحميل عنصر الوسائط التالي، يتم استدعاء هذا المعالج مرة أخرى.
يوضح المثال أدناه كيفية ضبط PlaybackConfig
عند إعداد CastReceiverContext
. تلغي الإعدادات الطلبات الصادرة
للحصول على البيانات. ويحدد المعالج وجوب تقديم طلبات التحكم في الوصول إلى بروتوكول CORS
باستخدام بيانات اعتماد مثل ملفات تعريف الارتباط أو عناوين التفويض.
const playbackConfig = new cast.framework.PlaybackConfig();
playbackConfig.manifestRequestHandler = requestInfo => {
requestInfo.withCredentials = true;
};
context.start({playbackConfig: playbackConfig});
يوضح المثال أدناه كيفية إلغاء PlaybackConfig
باستخدام دالة getter وsetter المتوفّرة في PlayerManager
. يضبط هذا الإعداد المشغّل لاستئناف
تشغيل المحتوى بعد تحميل مقطع واحد.
const playerManager =
cast.framework.CastReceiverContext.getInstance().getPlayerManager();
const playbackConfig = (Object.assign(
new cast.framework.PlaybackConfig(), playerManager.getPlaybackConfig()));
playbackConfig.autoResumeNumberOfSegments = 1;
playerManager.setPlaybackConfig(playbackConfig);
يوضّح المثال أدناه كيفية إلغاء PlaybackConfig
لطلب تحميل معيّن
باستخدام معالج معلومات تشغيل الوسائط. يستدعي المعالج طريقة getLicenseUrlForMedia
التي تم تنفيذها، للحصول على licenseUrl
من contentId
للعنصر الحالي.
playerManager.setMediaPlaybackInfoHandler((loadRequestData, playbackConfig) => {
const mediaInformation = loadRequestData.media;
playbackConfig.licenseUrl = getLicenseUrlForMedia(mediaInformation.contentId);
return playbackConfig;
});
أداة معالجة الحدث
تسمح "حزمة تطوير البرامج (SDK) لأجهزة الويب لمستلِم الويب" لتطبيق جهاز استقبال الويب بمعالجة أحداث المشغّل. تأخذ
أداة معالجة الحدث معلَمة
cast.framework.events.EventType
(أو مصفوفة من هذه المَعلمات) تحدد الأحداث
التي يجب أن تؤدي إلى تشغيل المستمع. يمكنك العثور في
cast.framework.events.category
على صفائف
cast.framework.events.EventType
التي تم ضبطها مسبقًا ومفيدة لتصحيح الأخطاء.
تقدِّم مَعلمة الحدث معلومات إضافية عن الحدث.
على سبيل المثال، إذا كنت تريد معرفة وقت بث تغيير
mediaStatus
، يمكنك استخدام المنطق التالي للتعامل مع
الحدث:
const playerManager =
cast.framework.CastReceiverContext.getInstance().getPlayerManager();
playerManager.addEventListener(
cast.framework.events.EventType.MEDIA_STATUS, (event) => {
// Write your own event handling code, for example
// using the event.mediaStatus value
});
اعتراض الرسائل
تسمح "حزمة تطوير البرامج (SDK) لاستقبال الويب" لتطبيق Web Receiver باعتراض الرسائل وتنفيذ رمز مخصّص على هذه الرسائل. يستخدم اعتراض الرسائل معلَمة cast.framework.messages.MessageType
التي تحدِّد نوع الرسالة التي يجب اعتراضها.
يجب أن يعرض أداة الاعتراض الطلب المعدّل أو وعدًا يتم حلّه بقيمة الطلب المعدَّلة. سيؤدي عرض الرمز null
إلى منع استدعاء
معالج الرسائل التلقائي. راجع تحميل الوسائط للحصول على مزيد من التفاصيل.
على سبيل المثال، إذا كنت تريد تغيير بيانات طلب التحميل، يمكنك استخدام المنطق التالي لاعتراضها وتعديلها:
const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD, loadRequestData => {
const error = new cast.framework.messages.ErrorData(
cast.framework.messages.ErrorType.LOAD_FAILED);
if (!loadRequestData.media) {
error.reason = cast.framework.messages.ErrorReason.INVALID_PARAM;
return error;
}
if (!loadRequestData.media.entity) {
return loadRequestData;
}
return thirdparty.fetchAssetAndAuth(loadRequestData.media.entity,
loadRequestData.credentials)
.then(asset => {
if (!asset) {
throw cast.framework.messages.ErrorReason.INVALID_REQUEST;
}
loadRequestData.media.contentUrl = asset.url;
loadRequestData.media.metadata = asset.metadata;
loadRequestData.media.tracks = asset.tracks;
return loadRequestData;
}).catch(reason => {
error.reason = reason; // cast.framework.messages.ErrorReason
return error;
});
});
context.start();
معالجة الأخطاء
عند حدوث أخطاء في أداة اعتراض الرسائل، يجب أن يعرض تطبيق Web Receiver
الدالتين
cast.framework.messages.ErrorType
وcast.framework.messages.ErrorReason
المناسبتَين.
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD, loadRequestData => {
const error = new cast.framework.messages.ErrorData(
cast.framework.messages.ErrorType.LOAD_CANCELLED);
if (!loadRequestData.media) {
error.reason = cast.framework.messages.ErrorReason.INVALID_PARAM;
return error;
}
...
return fetchAssetAndAuth(loadRequestData.media.entity,
loadRequestData.credentials)
.then(asset => {
...
return loadRequestData;
}).catch(reason => {
error.reason = reason; // cast.framework.messages.ErrorReason
return error;
});
});
اعتراض الرسائل مقابل أداة معالجة الحدث
في ما يلي بعض الاختلافات الرئيسية بين اعتراض الرسائل وأداة معالجة الأحداث:
- لا تسمح لك أداة معالجة الحدث بتعديل بيانات الطلب.
- من الأفضل استخدام أداة معالجة الحدث لتشغيل إحصاءات أو وظيفة مخصّصة.
playerManager.addEventListener(cast.framework.events.category.CORE,
event => {
console.log(event);
});
- ويتيح لك اعتراض الرسائل الاستماع إلى الرسالة واعتراضها وتعديل بيانات الطلب نفسها.
- يتم استخدام اعتراض الرسائل على أفضل نحو للتعامل مع المنطق المخصص في ما يتعلق بطلب البيانات.
جارٍ تحميل الوسائط
توفِّر MediaInformation
العديد من السمات لتحميل الوسائط في رسالة cast.framework.messages.MessageType.LOAD
، بما في ذلك entity
وcontentUrl
وcontentId
.
السمة
entity
هي السمة المقترَحة لاستخدامها في عملية التنفيذ لكل من تطبيقَي المُرسِل والمستلِم. الموقع هو عنوان URL لرابط يؤدي إلى صفحة معيّنة في التطبيق ويمكن أن يكون إما قائمة تشغيل أو محتوى وسائط محدّدًا.
تم تصميم
contentUrl
لعنوان URL قابل للتشغيل، ويمكن استخدامها عند توفرها.
تم إيقاف
contentId
نهائيًا بسبب غموض ما إذا كانت القيمة عنوان URL للوسائط أو معرّفًا حقيقيًا أو مَعلمة رئيسية للبحث المخصّص.
نقترح عليك استخدام entity
لتخزين المعرّف الفعلي أو المعلَمات الرئيسية،
واستخدام contentUrl
لعنوان URL للوسائط. يظهر مثال على ذلك في المقتطف التالي حيث يتوفّر entity
في طلب LOAD
ويتم استرداد contentUrl
القابل للتشغيل:
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD, loadRequestData => {
...
if (!loadRequestData.media.entity) {
// Copy the value from contentId for legacy reasons if needed
loadRequestData.media.entity = loadRequestData.media.contentId;
}
return thirdparty.fetchAssetAndAuth(loadRequestData.media.entity,
loadRequestData.credentials)
.then(asset => {
loadRequestData.media.contentUrl = asset.url;
...
return loadRequestData;
});
});
إمكانات الجهاز
توفّر الطريقة
getDeviceCapabilities
معلومات الجهاز على جهاز البث المتصل
وجهاز الفيديو أو
الصوت المرفق به. تقدّم الطريقة getDeviceCapabilities
معلومات الدعم الخاصة بخدمة "مساعد Google" والبلوتوث وأجهزة العرض والصوت
المتصلة.
تعرض هذه الطريقة كائنًا يمكنك الاستعلام عنه من خلال تمرير أحد
التعدادات المحددة للحصول على قدرة الجهاز لهذا التعداد. يتم تحديد التعدادات في cast.framework.system.DeviceCapabilities
.
يتحقّق هذا المثال مما إذا كان جهاز استقبال الويب بإمكانه تشغيل نطاق عالي الديناميكية
وDolbyVision (DV) باستخدام المفتاحَين IS_HDR_SUPPORTED
وIS_DV_SUPPORTED
على التوالي.
const context = cast.framework.CastReceiverContext.getInstance();
context.addEventListener(cast.framework.system.EventType.READY, () => {
const deviceCapabilities = context.getDeviceCapabilities();
if (deviceCapabilities &&
deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_HDR_SUPPORTED]) {
// Write your own event handling code, for example
// using the deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_HDR_SUPPORTED] value
}
if (deviceCapabilities &&
deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_DV_SUPPORTED]) {
// Write your own event handling code, for example
// using the deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_DV_SUPPORTED] value
}
});
context.start();
التعامل مع تفاعل المستخدم
ويمكن للمستخدم التفاعل مع تطبيق "جهاز استقبال الويب" من خلال تطبيقات المرسِل (الويب وAndroid وiOS) والأوامر الصوتية على الأجهزة المزوّدة بخدمة "مساعد Google" وعناصر التحكّم باللمس على الشاشات الذكية وعناصر التحكّم عن بُعد في أجهزة Android TV. توفّر حزمة Cast SDK العديد من واجهات برمجة التطبيقات التي تسمح لتطبيق جهاز استقبال الويب بمعالجة هذه التفاعلات وتحديث واجهة مستخدم التطبيق من خلال حالات إجراءات المستخدم وإرسال التغييرات اختياريًا لتحديث أي خدمات في الخلفية.
أوامر الوسائط المتوافقة
تعتمد حالات عناصر التحكّم في واجهة المستخدم على
MediaStatus.supportedMediaCommands
وحدات التحكّم الموسّعة للمرسِلين في أجهزة iOS وAndroid، وتطبيقات الاستقبال والتحكم عن بُعد
التي تعمل على الأجهزة التي تعمل باللمس، وتطبيقات جهاز الاستقبال على أجهزة Android TV. وعند تفعيل Command
محدّد على مستوى البت في الموقع الإلكتروني، يتم تفعيل الأزرار المرتبطة بهذا الإجراء. إذا لم يتم تعيين القيمة، فسيتم إيقاف الزر. يمكن تغيير هذه القيم على "جهاز استقبال الويب" من خلال:
- يمكن استخدام
PlayerManager.setSupportedMediaCommands
لضبط سمةCommands
- إضافة طلب جديد باستخدام
addSupportedMediaCommands
- إزالة طلب حالي باستخدام
removeSupportedMediaCommands
playerManager.setSupportedMediaCommands(cast.framework.messages.Command.SEEK |
cast.framework.messages.Command.PAUSE);
عندما يجهّز المُستلِم السمة MediaStatus
المعدَّلة، سيتم تضمين
التغييرات في السمة supportedMediaCommands
. عند نشر الحالة، ستعمل تطبيقات المُرسِلين المتصلين على تحديث الأزرار في واجهة المستخدم وفقًا لذلك.
لمزيد من المعلومات حول طلبات الوسائط والأجهزة التي تعمل باللمس، يُرجى الاطّلاع على
الدليل
Accessing UI controls
.
إدارة حالات إجراءات المستخدم
عندما يتفاعل المستخدمون مع واجهة المستخدم أو يرسلون أوامر صوتية، يمكنهم التحكم في تشغيل المحتوى والخصائص ذات الصلة بالعنصر قيد التشغيل. تعالج حزمة تطوير البرامج (SDK)
الطلبات التي تتحكم في التشغيل تلقائيًا. تتطلّب الطلبات التي تعدِّل الخصائص للعنصر الحالي قيد التشغيل، مثل أمر LIKE
، أن يعالجها تطبيق المستلِم. توفر SDK سلسلة من
واجهات برمجة التطبيقات لمعالجة هذه الأنواع من الطلبات. ولدعم هذه الطلبات، يجب تنفيذ
ما يلي:
- يمكنك ضبط السمة
MediaInformation
userActionStates
مع الإعدادات المفضّلة للمستخدم عند تحميل ملف وسائط. - تقاطع رسائل
USER_ACTION
وحدِّد الإجراء المطلوب. - يجب تحديث
MediaInformation
UserActionState
لتعديل واجهة المستخدم.
يعترض المقتطف التالي طلب LOAD
ويملأ MediaInformation
للسمة LoadRequestData
. في هذه الحالة، المستخدم يحب
المحتوى الذي يتم تحميله.
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD, (loadRequestData) => {
const userActionLike = new cast.framework.messages.UserActionState(
cast.framework.messages.UserAction.LIKE);
loadRequestData.media.userActionStates = [userActionLike];
return loadRequestData;
});
يعترض المقتطف التالي رسالة USER_ACTION
ويعالج استدعاء الواجهة الخلفية بالتغيير المطلوب. بعد ذلك، يُجري اختبارًا لتعديل
UserActionState
على جهاز الاستقبال.
playerManager.setMessageInterceptor(cast.framework.messages.MessageType.USER_ACTION,
(userActionRequestData) => {
// Obtain the media information of the current content to associate the action to.
let mediaInfo = playerManager.getMediaInformation();
// If there is no media info return an error and ignore the request.
if (!mediaInfo) {
console.error('Not playing media, user action is not supported');
return new cast.framework.messages.ErrorData(messages.ErrorType.BAD_REQUEST);
}
// Reach out to backend services to store user action modifications. See sample below.
return sendUserAction(userActionRequestData, mediaInfo)
// Upon response from the backend, update the client's UserActionState.
.then(backendResponse => updateUserActionStates(backendResponse))
// If any errors occurred in the backend return them to the cast receiver.
.catch((error) => {
console.error(error);
return error;
});
});
يحاكي المقتطف التالي استدعاء إحدى الخدمات الخلفية. تتحقق الدالة من UserActionRequestData
لمعرفة نوع التغيير الذي طلبه المستخدم ولا تجري اتصالاً بالشبكة إلا إذا كان الإجراء يتيحه الخلفية.
function sendUserAction(userActionRequestData, mediaInfo) {
return new Promise((resolve, reject) => {
switch (userActionRequestData.userAction) {
// Handle user action changes supported by the backend.
case cast.framework.messages.UserAction.LIKE:
case cast.framework.messages.UserAction.DISLIKE:
case cast.framework.messages.UserAction.FOLLOW:
case cast.framework.messages.UserAction.UNFOLLOW:
case cast.framework.messages.UserAction.FLAG:
case cast.framework.messages.UserAction.SKIP_AD:
let backendResponse = {userActionRequestData: userActionRequestData, mediaInfo: mediaInfo};
setTimeout(() => {resolve(backendResponse)}, 1000);
break;
// Reject all other user action changes.
default:
reject(
new cast.framework.messages.ErrorData(cast.framework.messages.ErrorType.INVALID_REQUEST));
}
});
}
يأخذ المقتطف التالي السمة UserActionRequestData
ويضيف السمة UserActionState
أو يزيلها من MediaInformation
. يؤدي تعديل UserActionState
الخاص بـ MediaInformation
إلى تغيير حالة الزرّ المرتبط بالإجراء المطلوب. ويظهر هذا التغيير في واجهة المستخدم لعناصر
التحكم في الشاشة الذكية وتطبيق التحكّم عن بُعد وواجهة مستخدم Android TV. يتم أيضًا
بثه من خلال رسائل MediaStatus
الصادرة لتحديث واجهة المستخدم
لوحدة التحكم الموسّعة للمرسِلين في أجهزة iOS وAndroid.
function updateUserActionStates(backendResponse) {
// Unwrap the backend response.
let mediaInfo = backendResponse.mediaInfo;
let userActionRequestData = backendResponse.userActionRequestData;
// If the current item playing has changed, don't update the UserActionState for the current item.
if (playerManager.getMediaInformation().entity !== mediaInfo.entity) {
return;
}
// Check for existing userActionStates in the MediaInformation.
// If none, initialize a new array to populate states with.
let userActionStates = mediaInfo.userActionStates || [];
// Locate the index of the UserActionState that will be updated in the userActionStates array.
let index = userActionStates.findIndex((currUserActionState) => {
return currUserActionState.userAction == userActionRequestData.userAction;
});
if (userActionRequestData.clear) {
// Remove the user action state from the array if cleared.
if (index >= 0) {
userActionStates.splice(index, 1);
}
else {
console.warn("Could not find UserActionState to remove in MediaInformation");
}
} else {
// Add the UserActionState to the array if enabled.
userActionStates.push(
new cast.framework.messages.UserActionState(userActionRequestData.userAction));
}
// Update the UserActionState array and set the new MediaInformation
mediaInfo.userActionStates = userActionStates;
playerManager.setMediaInformation(mediaInfo, true);
return;
}
الطلبات الصوتية
تتوفّر أوامر الوسائط التالية حاليًا في حزمة تطوير برامج استقبال الويب على الأجهزة المزوّدة بخدمة "مساعد Google". ويمكن العثور على التطبيقات التلقائية لهذه الأوامر في cast.framework.PlayerManager
.
Command | الوصف |
---|---|
Play | تشغيل أو استئناف التشغيل من حالة الإيقاف المؤقت. |
إيقاف مؤقت | أوقِف مؤقتًا المحتوى الذي يتم تشغيله حاليًا. |
السابق | يمكنك التخطّي إلى عنصر الوسائط السابق في قائمة انتظار الوسائط. |
التالي | يمكنك التخطّي إلى ملف الوسائط التالي في قائمة انتظار الوسائط. |
إيقاف | أوقِف الوسائط التي يتم تشغيلها حاليًا. |
عدم التكرار | يمكنك إيقاف تكرار عناصر الوسائط في قائمة الانتظار بعد انتهاء تشغيل آخر عنصر في قائمة الانتظار. |
تكرار فردي | تكرار الوسائط التي يتم تشغيلها حاليًا إلى أجل غير مسمى. |
تكرار الكل | تكرار جميع العناصر في قائمة الانتظار بعد تشغيل العنصر الأخير في اللائحة. |
تكرار الكل وترتيب عشوائي | بعد الانتهاء من تشغيل آخر عنصر في اللائحة، يمكنك ترتيب قائمة الانتظار عشوائيًا وتكرار جميع العناصر فيها. |
ترتيب عشوائي | ترتيب الوسائط في قائمة انتظار الوسائط عشوائيًا. |
تفعيل الترجمة والشرح أو إيقافها | تفعيل أو إيقاف الترجمة والشرح للوسائط تتوفر أيضًا ميزة "التفعيل / الإيقاف" حسب اللغة. |
البحث عن الوقت المطلق | للانتقال إلى الوقت المطلق المحدد. |
البحث عن الوقت مقارنةً بالوقت الحالي | للانتقال إلى الأمام أو الخلف خلال الفترة الزمنية المحددة بالنسبة إلى وقت التشغيل الحالي. |
اللعب مرة أخرى | يمكنك إعادة تشغيل الوسائط التي يتم تشغيلها حاليًا أو تشغيل آخر عنصر وسائط تم تشغيله إذا لم يتم تشغيل أي عنصر حاليًا. |
ضبط معدل التشغيل | تنويع معدل تشغيل الوسائط من المفترض أن تتم معالجة هذا الأمر تلقائيًا. يمكنك استخدام أداة اعتراض الرسائل SET_PLAYBACK_RATE لإلغاء طلبات السعر الواردة. |
طلبات الوسائط المتوافقة مع الطلبات الصوتية
لمنع طلب صوتي من تشغيل أمر وسائط على جهاز مزوّد بخدمة "مساعد Google"، يجب أولاً ضبط
طلبات الوسائط المتوافقة
المراد إتاحة هذه الطلبات عليها. بعد ذلك، عليك فرض هذه الأوامر من خلال تفعيل
السمة
CastReceiverOptions.enforceSupportedCommands
. وستتغير واجهة المستخدم على مُرسِلي حزمة تطوير البرامج (SDK) للبث والأجهزة التي تعمل باللمس
لتعكس هذه الإعدادات. إذا لم يتم تمكين العلم، فسيتم تنفيذ
الأوامر الصوتية الواردة.
على سبيل المثال، في حال السماح بالوصول إلى PAUSE
من تطبيقات المُرسِلين والأجهزة التي تعمل باللمس، يجب أيضًا ضبط جهاز الاستقبال ليعكس هذه الإعدادات. عند ضبط الإعدادات، سيتم تجاهل أي طلبات صوتية واردة في حال عدم تضمينها في قائمة الطلبات المتوافقة.
في المثال أدناه، نوفّر السمة CastReceiverOptions
عند بدء CastReceiverContext
. لقد أضفنا دعمًا إلى الأمر PAUSE
وفرضنا على اللاعب إمكانية استخدام هذا الأمر فقط. والآن إذا طلب طلب صوتي
عملية أخرى مثل SEEK
، سيتم رفضها. سيتم إشعار المستخدم
بأن الأمر غير متوافق بعد.
const context = cast.framework.CastReceiverContext.getInstance();
context.start({
enforceSupportedCommands: true,
supportedCommands: cast.framework.messages.Command.PAUSE
});
يمكنك تطبيق منطق منفصل لكل أمر تريد تقييده. عليك إزالة
علامة enforceSupportedCommands
، ولكل أمر تريد تقييده،
يمكنك اعتراض الرسالة الواردة. ويتم هنا اعتراض الطلب المقدَّم من حزمة تطوير البرامج (SDK) كي لا تؤدي أوامر SEEK
الصادرة للأجهزة المزوّدة بخدمة "مساعد Google" إلى تنفيذ عملية البحث في تطبيق "جهاز استقبال الويب".
بالنسبة إلى أوامر الوسائط التي لا يتوافق معها تطبيقك، يمكنك عرض سبب خطأ مناسب، مثل NOT_SUPPORTED
.
playerManager.setMessageInterceptor(cast.framework.messages.MessageType.SEEK,
seekData => {
// Block seeking if the SEEK supported media command is disabled
if (!(playerManager.getSupportedMediaCommands() & cast.framework.messages.Command.SEEK)) {
let e = new cast.framework.messages.ErrorData(cast.framework.messages.ErrorType
.INVALID_REQUEST);
e.reason = cast.framework.messages.ErrorReason.NOT_SUPPORTED;
return e;
}
return seekData;
});
تشغيل المحتوى الصوتي في الخلفية
إذا كانت منصة Cast تعمل في الخلفية بسبب نشاط "مساعد Google"، مثل الاستماع إلى كلام المستخدم أو التحدث إليه، سيتم إرسال رسالة NOT_IN_FOCUS
FocusState
إلى تطبيق Web المستلِم عند بدء النشاط. يتم إرسال رسالة أخرى مع IN_FOCUS
عند انتهاء النشاط.
بناءً على التطبيق والوسائط التي يتم تشغيلها، قد تحتاج إلى إيقاف الوسائط مؤقتًا عندما تكون قيمة FocusState
NOT_IN_FOCUS
من خلال اعتراض نوع الرسالة FOCUS_STATE
.
على سبيل المثال، من المفيد إيقاف تشغيل الكتب المسموعة مؤقتًا إذا استجاب "مساعد Google" لطلب بحث يجريه المستخدم.
playerManager.setMessageInterceptor(cast.framework.messages.MessageType.FOCUS_STATE,
focusStateRequestData => {
// Pause content when the app is out of focus. Resume when focus is restored.
if (focusStateRequestData.state == cast.framework.messages.FocusState.NOT_IN_FOCUS) {
playerManager.pause();
} else {
playerManager.play();
}
return focusStateRequestData;
});
لغة الترجمة المحددة بالصوت
عندما لا يحدّد المستخدم لغة الترجمة بشكل صريح، تكون اللغة المستخدمة في الشرح هي اللغة نفسها التي تم قول الطلب بها.
في هذه السيناريوهات، تشير المعلَمة
isSuggestedLanguage
للرسالة الواردة إلى ما إذا كان المستخدم قد اقترح اللغة
المرتبطة أو طلبها صراحةً.
على سبيل المثال، يتم ضبط isSuggestedLanguage
على true
للأمر "OK Google،
تفعيل الشرح" لأنّ اللغة التي تم نطق
الأمر بها قد تم استنتاجها. وإذا تم طلب اللغة بشكل واضح، مثلاً في عبارة "OK Google، أريد تفعيل الشرح باللغة الإنجليزية"، سيتم ضبط isSuggestedLanguage
على false
.
البيانات الوصفية والبث الصوتي
بينما يعالج مستلم الويب الأوامر الصوتية بشكل تلقائي، يجب أن تتأكد من أنّ البيانات الوصفية للمحتوى كاملة ودقيقة. ويضمن ذلك معالجة "مساعد Google" للأوامر الصوتية بشكل صحيح وظهور البيانات الوصفية بشكل صحيح على أنواع جديدة من الواجهات، مثل تطبيق Google Home والشاشات الذكية مثل Google Home Hub.
نقل البث
إنّ الاحتفاظ بحالة الجلسة هو أساس نقل البث، حيث يمكن للمستخدمين نقل المحتوى الصوتي والفيديوهات المضمّنة حاليًا على مختلف الأجهزة باستخدام الطلبات الصوتية أو تطبيق Google Home أو الشاشات الذكية. يتوقف تشغيل الوسائط على أحد الأجهزة (المصدر) وتستمر على جهاز آخر (الوجهة). يمكن استخدام أي جهاز بث يتضمن أحدث البرامج الثابتة كمصادر أو وجهات في عملية نقل البث.
في ما يلي خطوات نقل الحدث:
- على الجهاز المصدر:
- يتوقف تشغيل الوسائط.
- يتلقى تطبيق استقبال الويب أمرًا لحفظ حالة الوسائط الحالية.
- تم إيقاف تطبيق "جهاز استقبال الويب".
- على جهاز الوجهة:
- يتم تحميل تطبيق "جهاز استقبال الويب".
- يتلقى تطبيق جهاز استقبال الويب أمرًا لاستعادة حالة الوسائط المحفوظة.
- يتم استئناف تشغيل الوسائط.
تشمل عناصر حالة الوسائط ما يلي:
- الموضع أو الطابع الزمني المحدد للأغنية أو الفيديو أو عنصر الوسائط.
- يتم وضعها في قائمة انتظار أوسع (مثل قائمة تشغيل أو راديو لفنّان معيّن).
- المستخدم الذي تمت مصادقته.
- حالة التشغيل (على سبيل المثال، التشغيل أو الإيقاف المؤقت)
تفعيل نقل البث
لنقل محتوى البث لجهاز استقبال الويب، يُرجى اتّباع الخطوات التالية:
- عدِّل
supportedMediaCommands
باستخدام الأمرSTREAM_TRANSFER
:playerManager.addSupportedMediaCommands( cast.framework.messages.Command.STREAM_TRANSFER, true);
- يمكنك اختياريًا إلغاء برنامجَي اعتراض الرسائل
SESSION_STATE
وRESUME_SESSION
على النحو الموضّح في الحفاظ على حالة الجلسة. قم بتجاوز هذه الأمور فقط إذا كانت البيانات المخصصة بحاجة إلى تخزينها كجزء من لقطة الجلسة. بخلاف ذلك، سيوفّر التنفيذ التلقائي للحفاظ على حالات الجلسات إمكانية نقل البث.
الحفاظ على حالة الجلسة
توفّر حزمة تطوير البرامج (SDK) لأداة استقبال الويب تنفيذًا تلقائيًا لتطبيقات جهاز استقبال الويب بهدف الحفاظ على حالات الجلسات من خلال أخذ نبذة عن حالة الوسائط الحالية وتحويل الحالة إلى طلب تحميل واستئناف الجلسة التي تتضمّن طلب التحميل.
يمكن إلغاء طلب التحميل الذي تم إنشاؤه من خلال "جهاز استقبال الويب" في
أداة اعتراض الرسائل في SESSION_STATE
إذا لزم الأمر. إذا كنت تريد إضافة بيانات مخصّصة
في طلب التحميل، نقترح إضافتها في
loadRequestData.customData
.
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.SESSION_STATE,
function (sessionState) {
// Override sessionState.loadRequestData if needed.
const newCredentials = updateCredentials_(sessionState.loadRequestData.credentials);
sessionState.loadRequestData.credentials = newCredentials;
// Add custom data if needed.
sessionState.loadRequestData.customData = {
'membership': 'PREMIUM'
};
return sessionState;
});
ويمكن استرداد البيانات المخصّصة من
loadRequestData.customData
في أداة اعتراض الرسائل RESUME_SESSION
.
let cred_ = null;
let membership_ = null;
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.RESUME_SESSION,
function (resumeSessionRequest) {
let sessionState = resumeSessionRequest.sessionState;
// Modify sessionState.loadRequestData if needed.
cred_ = sessionState.loadRequestData.credentials;
// Retrieve custom data.
membership_ = sessionState.loadRequestData.customData.membership;
return resumeSessionRequest;
});
تحميل المحتوى مسبقًا
يتيح استقبال الويب التحميل المُسبق لعناصر الوسائط بعد عنصر التشغيل الحالي في قائمة الانتظار.
تؤدي عملية التحميل المُسبق إلى تنزيل عدة مقاطع مسبقًا من العناصر القادمة. يتم تحديد القيمة على قيمة preloadTime في الكائن QueueItem (القيمة التلقائية هي 20 ثانية إذا لم يتم توفيرها). يتم التعبير عن الوقت بالثواني، بالنسبة إلى نهاية العنصر الذي يتم تشغيله حاليًا . القيم الموجبة فقط هي الصالحة. على سبيل المثال، إذا كانت القيمة 10 ثوانٍ، سيتم تحميل هذا العنصر مسبقًا قبل 10 ثوانٍ من انتهاء العنصر السابق. إذا كان وقت التحميل المُسبق أعلى من الوقت المتبقي على العنصر الحالي، سيتمّ تنفيذ التحميل المُسبَق في أقرب وقت ممكن. وبالتالي، إذا تم تحديد قيمة كبيرة جدًا من التحميل المسبق في عنصر القائمة التجريبية، يمكن أن يحقق أحد هذه القيمة تأثير كل مرة نشغل فيها العنصر الحالي، وعندما نحمّل العنصر التالي مسبقًا. ومع ذلك، نترك الإعداد واختيار ذلك للمطور، حيث يمكن لهذه القيمة أن تؤثر في معدل نقل البيانات وأداء البث للعنصر قيد التشغيل الحالي.
تتوافق ميزة "التحميل المُسبق" مع البث المباشر وفق بروتوكول HTTP (HLS) وDASH والبث السلس تلقائيًا.
ولن يتم تحميل ملفات الفيديو والملفات الصوتية العادية بتنسيق MP4 مسبقًا، مثل ملفات MP3، لأنّ أجهزة البث تتوافق مع عنصر وسائط واحد فقط، ولا يمكن استخدامها للتحميل المُسبق عندما يكون أحد عناصر المحتوى الحالي لا يزال قيد التشغيل.
الرسائل المخصّصة
تبادل الرسائل هو طريقة التفاعل الرئيسية لتطبيقات "جهاز استقبال الويب".
يُصدر المُرسِل الرسائل إلى مستلِم الويب باستخدام واجهات برمجة تطبيقات المُرسِل في النظام الأساسي الذي يعمل به المُرسِل (Android أو iOS أو الويب). يحتوي كائن الحدث (وهو مظهر الرسالة) الذي يتم تمريره إلى أدوات معالجة الأحداث على عنصر بيانات (event.data
) حيث تأخذ البيانات خصائص نوع الحدث المحدّد.
قد يختار تطبيق "جهاز استقبال الويب" الاستماع إلى الرسائل في مساحة اسم محددة. ونتيجةً لذلك، يُقال إنّ تطبيق Web المستلِم يتوافق مع بروتوكول مساحة الاسم هذا. إذًا، يعود الأمر إلى أي مرسلين متصلين يرغبون في التواصل معهم بشأن مساحة الاسم هذه لاستخدام البروتوكول المناسب.
يتم تحديد جميع مساحات الاسم من خلال سلسلة ويجب أن تبدأ بـ "urn:x-cast:
"
متبوعة بأي سلسلة. على سبيل المثال،
"urn:x-cast:com.example.cast.mynamespace
".
إليك مقتطف رمز لـ "مستلم الويب" للاستماع إلى رسائل مخصصة من المرسلين المتصلين:
const context = cast.framework.CastReceiverContext.getInstance();
const CUSTOM_CHANNEL = 'urn:x-cast:com.example.cast.mynamespace';
context.addCustomMessageListener(CUSTOM_CHANNEL, function(customEvent) {
// handle customEvent.
});
context.start();
وبالمثل، يمكن لتطبيقات جهاز استقبال الويب إبقاء المرسِلين على اطلاع بحالة
جهاز استقبال الويب من خلال إرسال رسائل إلى المرسلين المتصلين. يمكن لتطبيق Web
Recipientr إرسال الرسائل باستخدام
sendCustomMessage(namespace, senderId, message)
على
CastReceiverContext
.
يمكن لمستلم الويب إرسال رسائل إلى مرسل فردي، إما ردًا على رسالة تم استلامها أو بسبب تغيير في حالة التطبيق. بالإضافة إلى الرسائل من نقطة إلى نقطة (بحد أقصى 64 كيلوبايت)، يمكن لأداة استقبال الويب أيضًا بث رسائل إلى جميع المرسلين المتصلين.
البث للأجهزة الصوتية
راجِع دليل Google Cast للأجهزة الصوتية للحصول على دعم بشأن تشغيل الصوت فقط.
Android TV
يناقش هذا القسم كيفية استخدام جهاز استقبال الويب من Google للبيانات التي يتم إدخالها كتشغيل، وكيفية توافق Android TV.
دمج التطبيق مع جهاز التحكم عن بُعد
يعمل جهاز استقبال الويب من Google الذي يعمل على جهاز Android TV على ترجمة الإدخال من إدخالات التحكّم بالجهاز (أي جهاز التحكّم عن بُعد المحمول باليد) في صورة رسائل تشغيل الوسائط المحدّدة لمساحة الاسم urn:x-cast:com.google.cast.media
، كما هو موضّح في رسائل تشغيل الوسائط. يجب
أن يتيح التطبيق استخدام هذه الرسائل للتحكّم في
تشغيل وسائط التطبيق، وذلك للسماح بالتحكّم الأساسي في التشغيل من إدخالات عناصر التحكّم
في Android TV.
إرشادات التوافق مع Android TV
إليك بعض الاقتراحات والمشاكل الشائعة التي يجب تفاديها لضمان توافق التطبيق مع Android TV:
- يُرجى الانتباه إلى أنّ سلسلة وكيل المستخدم تحتوي على كلّ من "Android" و "CrKey"، لأن بعض المواقع الإلكترونية قد تُعيد توجيه المستخدمين إلى موقع إلكتروني متوافق مع الأجهزة الجوّالة فقط لأنّها تكتشف تصنيف "Android". لا تفترض أنّ "Android" في سلسلة وكيل المستخدم يشير دائمًا إلى مستخدِم الجوّال.
- قد تستخدم حزمة وسائط Android ملف GZIP الشفاف لاسترجاع البيانات. تأكَّد من أنّ بيانات الوسائط يمكنها الردّ على
Accept-Encoding: gzip
. - يمكن بدء أحداث وسائط HTML5 على Android TV في توقيتات مختلفة عن توقيت Chromecast، وقد يكشف ذلك عن مشاكل كانت مخفية على Chromecast.
- عند تعديل الوسائط، استخدِم الأحداث ذات الصلة بالوسائط التي يتم تنشيطها من خلال عناصر
<audio>/<video>
، مثلtimeupdate
وpause
وwaiting
. تجنَّب استخدام أحداث ذات صلة بالشبكات مثلprogress
وsuspend
وstalled
، لأنّها تعتمد عادةً على المنصة. يمكنك الاطّلاع على أحداث الوسائط للحصول على مزيد من المعلومات حول التعامل مع أحداث الوسائط في جهاز الاستقبال. - عند ضبط شهادات HTTPS للموقع الإلكتروني للمستلِم، يُرجى التأكّد من تضمين شهادات CA الوسيطة. راجِع صفحة اختبار طبقة المقابس الآمنة (SSL) في Qualsys للتأكّد مما يلي: إذا كان مسار الشهادة الموثوق بها لموقعك الإلكتروني يتضمّن شهادة CA تحمل التصنيف "تنزيل إضافي"، قد لا يتم تحميلها على الأنظمة الأساسية المستندة إلى Android.
- وعلى الرغم من أنّ جهاز Chromecast يعرض صفحة جهاز الاستقبال على مستوى رسومات بدقة 720p، قد تعرض الأنظمة الأساسية الأخرى للبثّ، بما في ذلك Android TV، الصفحة بدقة تصل إلى 1080p. تأكد من ضبط حجم صفحة المتلقي بشكل مرن بدرجات دقة مختلفة.