إضافة ميزات أساسية إلى مستقبِل الويب المخصّص

تحتوي هذه الصفحة على مقتطفات رمز وأوصاف للميزات التي تُتاح لتطبيق مستقبِل الويب المخصص.

  1. عنصر cast-media-player يمثّل واجهة مستخدم مشغّل مضمَّنة ومتوفّرة في مستقبِل الويب
  2. نمط مخصّص يشبه CSS للعنصر cast-media-player لتصميم نمط مختلف لواجهة المستخدم، مثل background-image وsplash-image font-family.
  3. عنصر نص برمجي لتحميل إطار عمل مستقبِل الويب:
  4. رمز JavaScript لاعتراض الرسائل ومعالجة الأحداث.
  5. قائمة انتظار التشغيل التلقائي.
  6. خيارات لضبط التشغيل
  7. خيارات ضبط سياق مستقبِل الويب
  8. خيارات ضبط الأوامر المتوافقة مع تطبيق Web Receiver.
  9. استدعاء JavaScript لبدء تطبيق مستقبِل الويب.

إعدادات التطبيق وخياراته

ويُعد CastReceiverContext أعلى فئة معروضة لمطوّر البرامج، كما أنّه يدير تحميل المكتبات الأساسية ويعالج عملية إعداد حزمة تطوير البرامج (SDK) للويب.

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

const context = cast.framework.CastReceiverContext.getInstance();
const options = new cast.framework.CastReceiverOptions();
options.maxInactivity = 3600; //Development only
context.start(options);

في المقابل، يُفضَّل عدم ضبط تطبيق maxInactivity المنشور على الويب، ولكن يعتمد بدلاً من ذلك على القيمة التلقائية. يُرجى العِلم أنّه لا يتم ضبط خيارات المستلِم على الويب سوى مرة واحدة في التطبيق.

الإعدادات الأخرى هي cast.framework.PlaybackConfig. ويمكن إعداد ما يلي:

const playbackConfig = new cast.framework.PlaybackConfig();
playbackConfig.manifestRequestHandler = requestInfo => {
  requestInfo.withCredentials = true;
};
context.start({playbackConfig: playbackConfig});

تؤثر عملية الضبط هذه في كل عملية تشغيل للمحتوى ويوفّر بشكل أساسي سلوك إلغاء. للحصول على قائمة بالسلوكيات التي يمكن لمطوّري البرامج تجاوزها، يُرجى الاطّلاع على تعريف cast.framework.PlaybackConfig. لتغيير الإعدادات بين المحتوىَين، يمكن استخدام PlayerManager للحصول على playbackConfig الحالي، أو تعديل الاستثناء أو إضافته، وإعادة ضبط playbackConfig على النحو التالي:

const playerManager =
    cast.framework.CastReceiverContext.getInstance().getPlayerManager();
const playbackConfig = (Object.assign(
            new cast.framework.PlaybackConfig(), playerManager.getPlaybackConfig()));
playbackConfig.autoResumeNumberOfSegments = 1;
playerManager.setPlaybackConfig(playbackConfig);

يُرجى العِلم أنّه إذا لم يتم إلغاء السمة PlaybackConfig، ستعرض getPlaybackConfig() عنصرًا فارغًا. وأي خاصية على PlaybackConfig that هي undefined ستستخدم القيم التلقائية.

أداة معالجة الأحداث

تتيح حزمة SDK لـ "مستلِم الويب" تطبيق Web Receiver التعامل مع أحداث المشغِّل. ويأخذ المستخدم الذي يستمع إلى الحدث المَعلمة معلَمة cast.framework.events.EventType (أو مصفوفة من هذه المعلَمات) تحدِّد الأحداث التي يجب أن تؤدي إلى بدء أداة الاستماع. يمكن العثور على المصفوفات التي تم ضبطها مسبقًا للسمة cast.framework.events.EventType، والتي تكون مفيدة لتصحيح الأخطاء في cast.framework.events.category. توفر معلّمة الحدث معلومات إضافية عن الحدث.

على سبيل المثال، إذا كنت تريد معرفة الوقت الذي يتم فيه بث تغيير 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. وتوفّر حزمة تطوير البرامج (SDK) الخاصة بتكنولوجيا Google Cast واجهات برمجة تطبيقات متعدّدة للسماح لتطبيق "استقبال الويب" بالتعامل مع هذه التفاعلات وتعديل واجهة مستخدم التطبيق من خلال حالات إجراءات المستخدم وإرسال التغييرات بشكل اختياري لتحديث أي خدمات خلفية.

طلبات الوسائط المتوافقة

يتم تفعيل حالات عناصر تحكّم واجهة المستخدم من خلال MediaStatus.supportedMediaCommands لوحدات التحكّم الموسّعة لمرسِلي iOS وAndroid، وعناصر التحكّم عن بُعد التي تعمل على الأجهزة التي تعمل باللمس، وتطبيقات الاستقبال على أجهزة Android TV. عند تفعيل خاصتَي Command بشكلٍ خاص في الموقع، يتم تفعيل الأزرار المرتبطة بهذا الإجراء. وإذا لم يتم ضبط القيمة، سيتم إيقاف الزر. يمكن تغيير هذه القيم في مستقبِل الويب عن طريق:

  1. استخدام PlayerManager.setSupportedMediaCommands لتحديد Commands المحدّد
  2. إضافة أمر جديد باستخدام addSupportedMediaCommands
  3. إزالة طلب حالي باستخدام removeSupportedMediaCommands:
playerManager.setSupportedMediaCommands(cast.framework.messages.Command.SEEK |
  cast.framework.messages.Command.PAUSE);

عندما يجهّز المستلِم MediaStatus المعدّل، سيتضمّن التغييرات في السمة supportedMediaCommands. عند بث الحالة، ستعمل تطبيقات المُرسِلين المتصلين على تحديث الأزرار في واجهة المستخدم وفقًا لذلك.

للحصول على مزيد من المعلومات عن أوامر الوسائط المتوافقة وأجهزة اللمس، يُرجى الاطّلاع على الدليل Accessing UI controls.

إدارة حالات إجراءات المستخدمين

وعندما يتفاعل المستخدمون مع واجهة المستخدم أو يرسلون طلبات صوتية، يمكنهم التحكّم في تشغيل المحتوى والخصائص ذات الصلة بالعنصر الذي يتم تشغيله. وتعالج حزمة تطوير البرامج (SDK) تلقائيًا الطلبات التي تتحكّم في عملية التشغيل. بالنسبة إلى الطلبات التي تعمل على تعديل سمات العنصر الحالي الذي يتم تشغيله، مثل أمر LIKE، يجب معالجة التطبيق المُستلِم لها. وتوفّر حزمة تطوير البرامج (SDK) سلسلة من واجهات برمجة التطبيقات لمعالجة هذه الأنواع من الطلبات. لدعم هذه الطلبات، يجب تنفيذ ما يلي:

  • اعتراض USER_ACTION رسالة وتحديد الإجراء المطلوب.
  • يجب تعديل MediaInformation UserActionState لتحديث واجهة المستخدم.

يعترض المقتطف أدناه رسالة 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;
}

الطلبات الصوتية

تتوفّر حاليًا أوامر الوسائط التالية في حزمة تطوير البرامج (SDK) الخاصة بالمستلمين على الويب للأجهزة المزوّدة بخدمة "مساعد Google". ويمكن العثور على عمليات التنفيذ التلقائية لهذه الأوامر في cast.framework.PlayerManager.

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

طلبات الوسائط المتوافقة مع الصوت

لمنع توجيه طلب صوتي من تشغيل أمر وسائط على جهاز مزوّد بخدمة "مساعد Google"، يجب أولاً إعداد أوامر الوسائط المتوافقة التي تخطط لإتاحة استخدامها. وعليك بعد ذلك تنفيذ هذه الأوامر من خلال تفعيل السمة CastReceiverOptions.enforceSupportedCommands. سيتم تغيير واجهة المستخدم لمُرسِلي حزمة تطوير البرامج (SDK) الخاصة بتكنولوجيا Google Cast والأجهزة التي تعمل باللمس لتعكس هذه الإعدادات. في حال لم يتم تفعيل العلامة، سيتم تنفيذ الأوامر الصوتية الواردة.

على سبيل المثال، إذا سمحت لـ 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;
  });

إنشاء خلفية نشاط الصوت

إذا كانت منصّة البث في الخلفية تعمل على تشغيل صوت تطبيقك بسبب نشاط "مساعد Google"، مثل الاستماع إلى كلام المستخدم أو التحدّث مرة أخرى، يتم إرسال رسالة FocusState NOT_IN_FOCUS إلى تطبيق مستقبِل الويب عند بدء النشاط. يتم إرسال رسالة أخرى مع 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 أو الشاشات الذكية. يتوقّف تشغيل الوسائط على أحد الأجهزة (المصدر) ويستمر التشغيل على جهاز آخر (الوجهة). يمكن استخدام جهاز بث يتضمّن أحدث البرامج الثابتة كمصادر أو وجهات أثناء نقل البث.

إنّ تدفق الأحداث لنقل البث هو:

  1. على الجهاز المصدر:
    1. الوسائط تتوقف عن التشغيل.
    2. يتلقى تطبيق Web Receiver أمرًا لحفظ حالة الوسائط الحالية.
    3. تم إيقاف تطبيق Web Receiver.
  2. على جهاز الوجهة:
    1. تم تحميل تطبيق Web Receiver.
    2. يتلقى تطبيق Web Receiver أمرًا لاستعادة حالة الوسائط المحفوظة.
    3. يتم استئناف تشغيل الوسائط.

نذكر من عناصر حالة الوسائط ما يلي:

  • موضع محدّد أو طابع زمني محدّد للأغنية أو الفيديو أو عنصر الوسائط
  • أن يتم وضعها في قائمة انتظار أوسع (مثل قائمة تشغيل أو راديو لفنّان)
  • المستخدم الذي تمت المصادقة عليه.
  • حالة التشغيل (على سبيل المثال، التشغيل أو الإيقاف المؤقت)

جارٍ تفعيل ميزة نقل بيانات البث

لتنفيذ عملية نقل البث في جهاز استقبال الويب:

  1. تعديل supportedMediaCommands باستخدام الأمر STREAM_TRANSFER:
    playerManager.addSupportedMediaCommands(
    cast.framework.messages.Command.STREAM_TRANSFER, true);
  2. ويمكنك بشكل اختياري إلغاء أدوات اعتراض رسائل SESSION_STATE وRESUME_SESSION كما هو موضّح في الحفاظ على حالة الجلسة. لا يمكنك تجاوز ذلك إلا إذا كانت هناك حاجة إلى تخزين البيانات المخصّصة كجزء من لقطة الجلسة. بخلاف ذلك، ستوفّر طريقة التنفيذ التلقائية للاحتفاظ بحافظات الجلسات إمكانية نقل البيانات.

الحفاظ على حالة الجلسة

توفّر حزمة تطوير البرامج لـ "مقدِّم خدمات الويب" طريقة تنفيذ تلقائية لتطبيقات مستلِم الويب للحفاظ على حالات الجلسات من خلال أخذ نبذة عن حالة الوسائط الحالية وتحويل الحالة إلى طلب تحميل واستئناف الجلسة بطلب التحميل.

يمكن إلغاء طلب التحميل الذي ينشئه مستقبِل الويب في أداة اعتراض الرسائل باستخدام 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 ثوانٍ قبل انتهاء العنصر السابق. إذا كان وقت التحميل المسبق أعلى من الوقت المتبقي على العنصر الحالي، سيتم إجراء التحميل المُسبق في أقرب وقت ممكن. لذلك، في حال تحديد قيمة كبيرة جدًا للتحميل المُسبق على قائمة الانتظار، يمكن أن يحقق أحد النتائج تأثيرًا عندما نشغّل العنصر الحالي ونحمّل العنصر التالي مسبقًا. ومع ذلك، نترك إعداد هذا الخيار ونختاره لمطوّر البرامج حيث يمكن أن تؤثر هذه القيمة في معدل نقل البيانات وأداء البث للعنصر الحالي الذي يتم تشغيله.

تعمل ميزة التحميل المُسبق مع HLS وDASH وبث المحتوى بسلاسة.

لن يتم تحميل ملفات الفيديو والملفات الصوتية بتنسيق MP4 العادي مثل MP3 مسبقًا لأن أجهزة البث تتوافق مع عنصر وسائط واحد فقط ولا يمكن استخدامه للتحميل المُسبق أثناء تشغيل عنصر محتوى حالي.

رسائل مخصصة

تبادل الرسائل هو طريقة التفاعل الأساسية لتطبيقات مستقبِل الويب.

يُصدِر المُرسِل الرسائل إلى مستقبِل الويب باستخدام واجهات برمجة تطبيقات المُرسِل للمنصة التي يعمل عليها المُرسِل (Android وiOS والويب). يحتوي كائن الحدث (وهو بيان الرسالة التي يتم تمريرها إلى مستمعي الحدث) على عنصر بيانات (event.data) حيث تأخذ البيانات البيانات في خصائص نوع الحدث المحدّد.

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

يتم تحديد جميع مساحات الاسم عن طريق سلسلة ويجب أن تبدأ بـ "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();

وبالمثل، يمكن لتطبيقات مستقبِل الويب إبقاء المُرسِلين على علم بحالة حالة مستلِم الويب عن طريق إرسال رسائل إلى مُرسِلين متصلين. يمكن لتطبيق مستقبِل الويب إرسال رسائل باستخدام sendCustomMessage(namespace, senderId, message) على CastReceiverContext. يمكن لمستلم الويب إرسال رسائل إلى مُرسِل فردي إما استجابةً لرسالة مُستلَمة أو بسبب تغيير في حالة الطلب. بالإضافة إلى المراسلة من نقطة إلى أخرى مع حد أقصى يبلغ 64 كيلوبايت)، قد يبث أيضًا مستقبِل الويب الرسائل إلى كل المُرسِلين المتصلين.

البث لأجهزة الصوت

يمكنك الاطّلاع على دليل Google Cast للأجهزة الصوتية للحصول على الدعم بشأن تشغيل الصوت فقط.

Android TV

يعرض هذا القسم كيفية استقبال Google Web Receiver للمدخلات كعمليات تشغيل وتوافق مع 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. تأكّد من أن صفحة المستلِم قابلة للتوسّع بشكلٍ سلس بدرجات دقة مختلفة.