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

تنظيم صفحاتك في مجموعات يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.

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

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

تهيئة التطبيق والخيارات

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

حدث خطأ أثناء المعالجة

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

أوامر الوسائط المتوافقة

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

تشغيل في الخلفية من النشاط الصوتي

إذا كان النظام الأساسي للإرسال يعمل في الخلفية على صوت تطبيقك بسبب نشاط "مساعد 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. يتلقى تطبيق مستلم الويب أمرًا لحفظ حالة الوسائط الحالية.
    3. تم إيقاف تشغيل تطبيق استقبال الويب.
  2. على الجهاز الوجهة:
    1. تم تحميل تطبيق مستقبل الويب.
    2. يتلقّى تطبيق "مستقبل الويب" أمرًا باستعادة حالة الوسائط المحفوظة.
    3. يتم استئناف تشغيل الوسائط.

تتضمن عناصر حالة الوسائط ما يلي:

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

تفعيل نقل البث

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

  1. تعديل supportedMediaCommands باستخدام الأمر STREAM_TRANSFER:
    playerManager.addSupportedMediaCommands(
    cast.framework.messages.Command.STREAM_TRANSFER, true);
  2. يمكنك اختياريًا تجاوز أدوات اعتراض الرسائل 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) حيث تأخذ البيانات خصائص النوع المحدّد من الأحداث.

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

يتم تحديد جميع مساحات الأسماء بسلسلة ويجب أن تبدأ بـ "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 للإدخالات كتشغيل، والتوافق مع 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 الوسيطة. راجع صفحة اختبار طبقة المقابس الآمنة في Quasys للتحقق: إذا كان مسار الشهادة الموثوق به لموقعك يتضمن شهادة CA تسمى "تنزيل إضافي"، فقد لا يتم تحميله على أنظمة أساسية مستندة إلى Android.
  • على الرغم من أن Chromecast يعرض صفحة جهاز الاستقبال بمستوى دقة 720 بكسل، فإن منصات الإرسال الأخرى بما في ذلك Android TV قد تعرض الصفحة بدقة تصل إلى 1080 بكسل. تأكد من أنه يتم تدرّج صفحة المتلقي بدقة ودقة مختلفة.