فواصل الإعلانات
تنظيم صفحاتك في مجموعات
يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.
توفّر حزمة تطوير البرامج (SDK) لأجهزة استقبال Android TV ميزة التوافق الأصلي مع الفواصل الإعلانية والإعلانات المصاحبة
ضمن بث وسائط معيّن.
اطّلِع على نظرة عامة على الفواصل الإعلانية لأجهزة استلام الويب
لمزيد من المعلومات حول آلية عمل الفواصل الإعلانية.
التعامل مع عدد الإعلانات باستخدام الفواصل الإعلانية
في تطبيق Android TV، يتم تضمين الفواصل في
MediaLoadRequestData
.
يمكن معالجة طلبات التحميل بشكلٍ طبيعي، ويمكن استرجاع ملفّات AdBreakClipInfo
وAdBreakInfo
من MediaInfo
:
class MyMediaLoadCommandCallback : MediaLoadCommandCallback() {
override fun onLoad( senderId: String?, loadRequestData: MediaLoadRequestData
): Task {
return Tasks.call {
// Resolve the entity into your data structure and load media.
val mediaInfo = loadRequestData.mediaInfo
...
myPrepareAdBreaks(mediaInfo.adBreakClips, mediaInfo.adBreaks)
// Update media metadata and state (this clears all previous status
// overrides).
castReceiverContext.getMediaStatusModifier()
.setDataFromLoad(mediaInfo) // Ad breaks are set on the modifier.
castReceiverContext.getMediaManager().broadcastMediaStatus()
// Return the resolved MediaLoadRequestData to indicate load success.
return loadRequestData
}
}
}
public class MyMediaLoadCommandCallback extends MediaLoadCommandCallback {
@Override
public Task onLoad(String senderId, MediaLoadRequestData loadRequestData) {
return Tasks.call(() -> {
// Resolve the entity into your data structure and load media.
MediaInfo mediaInfo = loadRequestData.getMediaInfo();
...
myPrepareAdBreaks(mediaInfo.getAdBreakClips(), mediaInfo.getAdBreaks());
// Update media metadata and state (this clears all previous status
// overrides).
castReceiverContext.getMediaStatusModifier()
.setDataFromLoad(mediaInfo); // Ad breaks are set on the modifier.
castReceiverContext.getMediaManager().broadcastMediaStatus();
// Return the resolved MediaLoadRequestData to indicate load success.
return loadRequestData;
});
}
}
تعديل الفواصل الإعلانية
عندما يبدأ تشغيل الإعلانات، عدِّل القيمة في العنصر
AdBreakStatus
على العنصر
MediaStatusModifier
لإعلام التطبيق بأنّه بدأ تشغيل الإعلانات:
val breakStatus = AdBreakStatus.Builder()
.setBreakId("b1")
.setBreakClipId("bc1")
.setCurrentBreakClipTimeInMs(breakClipProgress)
.setCurrentBreakTimeInMs(breakProgress)
.setWhenSkippableInMs(5000) // Set this field so that the ad break clip is skippable
.build()
castReceiverContext.getMediaStatusModifier()
.setAdBreakStatus(breakStatus)
AdBreakStatus breakStatus =
new AdBreakStatus.Builder()
.setBreakId("b1")
.setBreakClipId("bc1")
.setCurrentBreakClipTimeInMs(breakClipProgress)
.setCurrentBreakTimeInMs(breakProgress)
.setWhenSkippableInMs(5000) // Set this field so that the ad break clip is skippable
.build();
castReceiverContext.getMediaStatusModifier()
.setAdBreakStatus(breakStatus);
يمكنك أيضًا تعديل الفواصل الإعلانية ديناميكيًا بعد تحميل عنصر:
var breakClip1: AdBreakClipInfo = ...
var breakClip2: AdBreakClipInfo = ...
var breakClip3: AdBreakClipInfo = ...
var break1: AdBreakInfo = ...
var break2: AdBreakInfo = ...
mediaManager.getMediaStatusModifier().getMediaInfoModifier()
.setAdBreakClips({breakClip1, breakClip2, breakClip3})
.setAdBreaks({break1, break2})
AdBreakClipInfo breakClip1 = ...
AdBreakClipInfo breakClip2 = ...
AdBreakClipInfo breakClip3 = ...
AdBreakInfo break1 = ...
AdBreakInfo break2 = ...
mediaManager.getMediaStatusModifier().getMediaInfoModifier()
.setAdBreakClips({breakClip1, breakClip2, breakClip3})
.setAdBreaks({break1, break2});
تفعيل ميزة "تخطّي الإعلانات" ومعالجتها
عند تشغيل فاصل إعلاني، سيعرض المرسِلون زرًا لتخطّي مقطع الفاصل الإعلاني الحالي إذا كان قابلاً للتخطّي. لتفعيل إمكانية تخطّي المستخدِم مقطع فاصل إعلاني، استخدِم الرمز
MediaStatusModifier
لإضافة رمز الوسائط
COMMAND_SKIP_AD
:
mMediaManager.getMediaStatusModifier().setMediaCommandSupported(MediaStatus.COMMAND_SKIP_AD, true)
mMediaManager.getMediaStatusModifier().setMediaCommandSupported(MediaStatus.COMMAND_SKIP_AD, true);
لمعالجة الأمر SKIP_AD
، نفِّذ دالة callback
onSkipAd
في
MediaCommandCallback
:
class MyMediaCommandCallback : MediaCommandCallback() {
override fun onSkipAd(requestData: RequestData?): Task<Void?> {
// Skip your ad
...
return Tasks.forResult<Any?>(null)
}
}
val mediaManager = CastReceiverContext.getInstance().mediaManager
mediaManager.setMediaCommandCallback(MyMediaCommandCallback())
public class MyMediaCommandCallback extends MediaCommandCallback {
@Override
public Task onSkipAd(RequestData requestData) {
// Skip your ad
...
return Tasks.forResult(null);
}
}
MediaManager mediaManager =
CastReceiverContext.getInstance().getMediaManager();
mediaManager.setMediaCommandCallback(new MyMediaCommandCallback());
التجميع من جهة العميل
التجميع من جهة العميل:
يعني ذلك عدم تضمين الإعلانات في البث. بالنسبة إلى Cast Connect، بالإضافة إلى
تعديل
AdBreakStatus
على
MediaStatusModifier
، عليك ضبط سرعة التشغيل على 0 على
PlaybackStateCompat
لكي يعرف المرسلون أنّه يجب تجميد مستوى تقدّم المخطط الزمني للمحتوى.
// Playback speed should be 0 if content is not playing.
if (adIsPlaying) {
playbackSpeed = 0.0f
}
val stateBuilder = PlaybackStateCompat.Builder()
.setActions(AVAILABLE_MEDIA_ACTIONS)
stateBuilder.setState(playbackStateCompat, position, playbackSpeed)
mediaSession.setPlaybackState(stateBuilder.build())
// Playback speed should be 0 if content is not playing.
if (adIsPlaying) {
playbackSpeed = 0.0f;
}
PlaybackStateCompat.Builder stateBuilder = new PlaybackStateCompat.Builder()
.setActions(AVAILABLE_MEDIA_ACTIONS);
stateBuilder.setState(playbackStateCompat, position, playbackSpeed);
mediaSession.setPlaybackState(stateBuilder.build());
بعد انتهاء عرض الإعلان، من المفترض أن تستأنف سرعة التشغيل السابقة.
التجميع من جهة الخادم
بالنسبة إلى
الدمج من جهة الخادم،
يتم تضمين الإعلانات بحيث يُفترض أن يقدّم الخادم بثًا واحدًا يحتوي على المحتوى والإعلانات معًا. في هذه الحالة، يمكن مواصلة تشغيل الفيديو بشكلٍ طبيعي لأنّ المخطط الزمني يتضمّن مدة الإعلان بالإضافة إلى المحتوى.
إنّ محتوى هذه الصفحة مرخّص بموجب ترخيص Creative Commons Attribution 4.0 ما لم يُنصّ على خلاف ذلك، ونماذج الرموز مرخّصة بموجب ترخيص Apache 2.0. للاطّلاع على التفاصيل، يُرجى مراجعة سياسات موقع Google Developers. إنّ Java هي علامة تجارية مسجَّلة لشركة Oracle و/أو شركائها التابعين.
تاريخ التعديل الأخير: 2025-08-31 (حسب التوقيت العالمي المتفَّق عليه)
[null,null,["تاريخ التعديل الأخير: 2025-08-31 (حسب التوقيت العالمي المتفَّق عليه)"],[[["\u003cp\u003eThe Android TV Receiver SDK natively supports ad breaks and companion ads, allowing developers to integrate ads into their media streams.\u003c/p\u003e\n"],["\u003cp\u003eDevelopers can handle ad breaks by including them in \u003ccode\u003eMediaLoadRequestData\u003c/code\u003e and retrieving information about them from \u003ccode\u003eMediaInfo\u003c/code\u003e.\u003c/p\u003e\n"],["\u003cp\u003eWhen ads start playing, developers need to update the \u003ccode\u003eAdBreakStatus\u003c/code\u003e to inform the sender app and enable ad skipping by setting \u003ccode\u003eCOMMAND_SKIP_AD\u003c/code\u003e as supported.\u003c/p\u003e\n"],["\u003cp\u003eFor client-side stitching where ads are not embedded, developers must freeze the content timeline progress by setting the playback speed to 0 during ad playback.\u003c/p\u003e\n"],["\u003cp\u003eServer-side stitching embeds ads within the stream, allowing playback to progress normally as the timeline includes ad duration.\u003c/p\u003e\n"]]],["The Android TV Receiver SDK supports ad breaks and companion ads. During media loading, `AdBreakClipInfo` and `AdBreakInfo` are retrievable from `MediaInfo`. When ads begin, `AdBreakStatus` updates are broadcast via `MediaStatusModifier`. Ad breaks can be dynamically modified with `setAdBreakClips` and `setAdBreaks`. To enable ad skipping, set the `COMMAND_SKIP_AD` media command. For client-side ad stitching, playback speed must be set to 0 when ads play, resuming normal speed afterward. For server-side stitching, playback progresses normally.\n"],null,["# Ad Breaks\n\nThe Android TV Receiver SDK features native support for Ad Breaks and companion\nads within a given media stream.\n\nSee the [Web Receiver Ad Breaks Overview](/cast/docs/web_receiver/ad_breaks)\nfor more information on how Ad Breaks work.\n\nHandling load with ad breaks\n----------------------------\n\nOn your Android TV app, the breaks are included in\n[`MediaLoadRequestData`](/android/reference/com/google/android/gms/cast/MediaLoadRequestData).\nLoad requests can be processed normally and the\n[`AdBreakClipInfo`](/android/reference/com/google/android/gms/cast/AdBreakClipInfo)s\nand\n[`AdBreakInfo`](/android/reference/com/google/android/gms/cast/AdBreakInfo)s\ncan be retrieved from the\n[`MediaInfo`](/android/reference/com/google/android/gms/cast/MediaInfo):\nKotlin \n\n```kotlin\nclass MyMediaLoadCommandCallback : MediaLoadCommandCallback() {\n override fun onLoad( senderId: String?, loadRequestData: MediaLoadRequestData\n ): Task {\n return Tasks.call {\n // Resolve the entity into your data structure and load media.\n val mediaInfo = loadRequestData.mediaInfo\n ...\n myPrepareAdBreaks(mediaInfo.adBreakClips, mediaInfo.adBreaks)\n // Update media metadata and state (this clears all previous status\n // overrides).\n castReceiverContext.getMediaStatusModifier()\n .setDataFromLoad(mediaInfo) // Ad breaks are set on the modifier.\n castReceiverContext.getMediaManager().broadcastMediaStatus()\n // Return the resolved MediaLoadRequestData to indicate load success.\n return loadRequestData\n }\n }\n}\n```\nJava \n\n```gdscript\npublic class MyMediaLoadCommandCallback extends MediaLoadCommandCallback {\n @Override\n public Task onLoad(String senderId, MediaLoadRequestData loadRequestData) {\n return Tasks.call(() -\u003e {\n // Resolve the entity into your data structure and load media.\n MediaInfo mediaInfo = loadRequestData.getMediaInfo();\n ...\n myPrepareAdBreaks(mediaInfo.getAdBreakClips(), mediaInfo.getAdBreaks());\n // Update media metadata and state (this clears all previous status\n // overrides).\n castReceiverContext.getMediaStatusModifier()\n .setDataFromLoad(mediaInfo); // Ad breaks are set on the modifier.\n castReceiverContext.getMediaManager().broadcastMediaStatus();\n // Return the resolved MediaLoadRequestData to indicate load success.\n return loadRequestData;\n });\n }\n}\n```\n\nUpdating ad breaks\n------------------\n\nWhen ads start playing, update the\n[`AdBreakStatus`](/android/reference/com/google/android/gms/cast/AdBreakStatus)\non the\n[`MediaStatusModifier`](/android/reference/com/google/android/gms/cast/tv/media/MediaStatusModifier)\nto broadcast that your app has started playing ads:\nKotlin \n\n```kotlin\nval breakStatus = AdBreakStatus.Builder()\n .setBreakId(\"b1\")\n .setBreakClipId(\"bc1\")\n .setCurrentBreakClipTimeInMs(breakClipProgress)\n .setCurrentBreakTimeInMs(breakProgress)\n .setWhenSkippableInMs(5000) // Set this field so that the ad break clip is skippable\n .build()\n\ncastReceiverContext.getMediaStatusModifier()\n .setAdBreakStatus(breakStatus)\n```\nJava \n\n```java\nAdBreakStatus breakStatus =\n new AdBreakStatus.Builder()\n .setBreakId(\"b1\")\n .setBreakClipId(\"bc1\")\n .setCurrentBreakClipTimeInMs(breakClipProgress)\n .setCurrentBreakTimeInMs(breakProgress)\n .setWhenSkippableInMs(5000) // Set this field so that the ad break clip is skippable\n .build();\n\ncastReceiverContext.getMediaStatusModifier()\n .setAdBreakStatus(breakStatus);\n```\n\nYou can also dynamically modify the ad breaks after an item is loaded:\nKotlin \n\n```kotlin\nvar breakClip1: AdBreakClipInfo = ...\nvar breakClip2: AdBreakClipInfo = ...\nvar breakClip3: AdBreakClipInfo = ...\n\nvar break1: AdBreakInfo = ...\nvar break2: AdBreakInfo = ...\n\nmediaManager.getMediaStatusModifier().getMediaInfoModifier()\n .setAdBreakClips({breakClip1, breakClip2, breakClip3})\n .setAdBreaks({break1, break2})\n```\nJava \n\n```text\nAdBreakClipInfo breakClip1 = ...\nAdBreakClipInfo breakClip2 = ...\nAdBreakClipInfo breakClip3 = ...\n\nAdBreakInfo break1 = ...\nAdBreakInfo break2 = ...\n\nmediaManager.getMediaStatusModifier().getMediaInfoModifier()\n .setAdBreakClips({breakClip1, breakClip2, breakClip3})\n .setAdBreaks({break1, break2});\n```\n\nEnable and handle ad skipping\n-----------------------------\n\nWhen an ad break is playing, the senders will show a button to skip the current\nad break clip if it is skippable. To enable the ability for a user to skip an ad\nbreak clip, use the\n[`MediaStatusModifier`](/android/reference/com/google/android/gms/cast/tv/media/MediaStatusModifier)\nto add the\n[`COMMAND_SKIP_AD`](/android/reference/com/google/android/gms/cast/MediaStatus#public-static-final-long-command_skip_ad)\nmedia command:\nKotlin \n\n```kotlin\nmMediaManager.getMediaStatusModifier().setMediaCommandSupported(MediaStatus.COMMAND_SKIP_AD, true)\n```\nJava \n\n```scdoc\nmMediaManager.getMediaStatusModifier().setMediaCommandSupported(MediaStatus.COMMAND_SKIP_AD, true);\n```\n\nTo handle the `SKIP_AD` command, implement the\n[`onSkipAd`](/android/reference/com/google/android/gms/cast/tv/media/MediaCommandCallback#onSkipAd(java.lang.String,%20com.google.android.gms.cast.RequestData))\ncallback in your\n[`MediaCommandCallback`](/android/reference/com/google/android/gms/cast/tv/media/MediaCommandCallback)s:\nKotlin \n\n```kotlin\nclass MyMediaCommandCallback : MediaCommandCallback() {\n override fun onSkipAd(requestData: RequestData?): Task\u003cVoid?\u003e {\n // Skip your ad\n ...\n return Tasks.forResult\u003cAny?\u003e(null)\n }\n}\n\nval mediaManager = CastReceiverContext.getInstance().mediaManager\nmediaManager.setMediaCommandCallback(MyMediaCommandCallback())\n```\nJava \n\n```gdscript\npublic class MyMediaCommandCallback extends MediaCommandCallback {\n @Override\n public Task onSkipAd(RequestData requestData) {\n // Skip your ad\n ...\n return Tasks.forResult(null);\n }\n}\n\nMediaManager mediaManager =\n CastReceiverContext.getInstance().getMediaManager();\nmediaManager.setMediaCommandCallback(new MyMediaCommandCallback());\n```\n\nClient-side stitching\n---------------------\n\n[Client-side stitching](/cast/docs/caf_receiver/ad_breaks#client-side_ad_stitching)\nis where ads are not embedded in the stream. For Cast Connect, in addition to\nupdating the\n[`AdBreakStatus`](/android/reference/com/google/android/gms/cast/AdBreakStatus)\non the\n[`MediaStatusModifier`](/android/reference/com/google/android/gms/cast/tv/media/MediaStatusModifier)\nyou mustset the playback speed to 0 on the\n[`PlaybackStateCompat`](https://developer.android.com/reference/kotlin/android/support/v4/media/session/PlaybackStateCompat.Builder)\nso the senders know to freeze the content timeline progress.\nKotlin \n\n```kotlin\n// Playback speed should be 0 if content is not playing.\nif (adIsPlaying) {\n playbackSpeed = 0.0f\n}\nval stateBuilder = PlaybackStateCompat.Builder()\n .setActions(AVAILABLE_MEDIA_ACTIONS)\nstateBuilder.setState(playbackStateCompat, position, playbackSpeed)\nmediaSession.setPlaybackState(stateBuilder.build())\n```\nJava \n\n```scilab\n// Playback speed should be 0 if content is not playing.\nif (adIsPlaying) {\n playbackSpeed = 0.0f;\n}\nPlaybackStateCompat.Builder stateBuilder = new PlaybackStateCompat.Builder()\n .setActions(AVAILABLE_MEDIA_ACTIONS);\nstateBuilder.setState(playbackStateCompat, position, playbackSpeed);\nmediaSession.setPlaybackState(stateBuilder.build());\n```\n\nOnce the ad finishes, you should resume the previous playback speed.\n\nServer-side stitching\n---------------------\n\nFor\n[server-side stitching](/cast/docs/caf_receiver/ad_breaks#server-side_ad_stitching),\nthe ads are embedded so the server is expected to provide a single stream that\ncontains both the content and ads. In this case, playback can continue\nprogressing normally as the timeline contains the duration of the ad in addition\nto the content."]]