وقفههای تبلیغاتی
کیت توسعه نرمافزاری فرستنده اندروید (Android Sender SDK) از نمایش تبلیغات لحظهای (Ad Breaks) و تبلیغات همراه در یک جریان رسانهای مشخص پشتیبانی میکند.
برای اطلاعات بیشتر در مورد نحوه عملکرد Ad Breakها، به مرور کلی Ad Breakهای گیرنده وب مراجعه کنید.
اگرچه میتوان وقفهها را هم در فرستنده و هم در گیرنده مشخص کرد، توصیه میشود که این وقفهها در گیرنده وب و گیرنده تلویزیون اندروید نیز مشخص شوند تا رفتار ثابتی در پلتفرمهای مختلف حفظ شود.
در اندروید، با استفاده از AdBreakClipInfo و AdBreakInfo وقفههای تبلیغاتی را در یک دستور بارگذاری مشخص کنید:
val breakClip1: AdBreakClipInfo = AdBreakClipInfo.Builder("bc0") .setTitle("Clip title") .setPosterUrl("https://www.some.url") .setDuration(60000) .setWhenSkippableInMs(5000) // Set this field so that the ad is skippable .build() val breakClip2: AdBreakClipInfo = … val breakClip3: AdBreakClipInfo = … val break1: AdBreakClipInfo = AdBreakInfo.Builder(/* playbackPositionInMs= */ 10000) .setId("b0") .setBreakClipIds({"bc0","bc1","bc2"}) … .build() val mediaInfo: MediaInfo = MediaInfo.Builder() … .setAdBreaks({break1}) .setAdBreakClips({breakClip1, breakClip2, breakClip3}) .build() val mediaLoadRequestData: MediaLoadRequestData = MediaInfo.Builder() … .setMediaInfo(mediaInfo) .build() remoteMediaClient.load(mediaLoadRequestData)
AdBreakClipInfo breakClip1 = new AdBreakClipInfo.Builder("bc0") .setTitle("Clip title") .setPosterUrl("https://www.some.url") .setDuration(60000) .setWhenSkippableInMs(5000) // Set this field so that the ad is skippable .build(); AdBreakClipInfo breakClip2 = … AdBreakClipInfo breakClip3 = … AdBreakInfo break1 = new AdBreakInfo.Builder(/* playbackPositionInMs= */ 10000) .setId("b0") .setBreakClipIds({"bc0","bc1","bc2"}) … .build(); MediaInfo mediaInfo = new MediaInfo.Builder() … .setAdBreaks({break1}) .setAdBreakClips({breakClip1, breakClip2, breakClip3}) .build(); MediaLoadRequestData mediaLoadRequestData = new MediaInfo.Builder() … .setMediaInfo(mediaInfo) .build(); remoteMediaClient.load(mediaLoadRequestData);
افزودن اقدامات سفارشی
یک برنامه فرستنده میتواند MediaIntentReceiver برای مدیریت اقدامات سفارشی یا لغو رفتار آن، توسعه دهد. اگر MediaIntentReceiver خود را پیادهسازی کردهاید، باید آن را به مانیفست اضافه کنید و همچنین نام آن را در CastMediaOptions تنظیم کنید. این مثال اقدامات سفارشی را ارائه میدهد که پخش رسانه از راه دور، فشار دادن دکمه رسانه و سایر انواع اقدامات را لغو میکند.
// In AndroidManifest.xml
<receiver android:name="com.example.MyMediaIntentReceiver" />
// In your OptionsProvider var mediaOptions = CastMediaOptions.Builder() .setMediaIntentReceiverClassName(MyMediaIntentReceiver::class.java.name) .build() // Implementation of MyMediaIntentReceiver internal class MyMediaIntentReceiver : MediaIntentReceiver() { override fun onReceiveActionTogglePlayback(currentSession: Session) { } override fun onReceiveActionMediaButton(currentSession: Session, intent: Intent) { } override fun onReceiveOtherAction(context: Context?, action: String, intent: Intent) { } }
// In your OptionsProvider CastMediaOptions mediaOptions = new CastMediaOptions.Builder() .setMediaIntentReceiverClassName(MyMediaIntentReceiver.class.getName()) .build(); // Implementation of MyMediaIntentReceiver class MyMediaIntentReceiver extends MediaIntentReceiver { @Override protected void onReceiveActionTogglePlayback(Session currentSession) { } @Override protected void onReceiveActionMediaButton(Session currentSession, Intent intent) { } @Override protected void onReceiveOtherAction(Context context, String action, Intent intent) { } }
اضافه کردن کانال سفارشی
برای اینکه برنامه فرستنده بتواند با برنامه گیرنده ارتباط برقرار کند، برنامه شما باید یک کانال سفارشی ایجاد کند. فرستنده میتواند از کانال سفارشی برای ارسال پیامهای رشتهای به گیرنده استفاده کند. هر کانال سفارشی توسط یک فضای نام منحصر به فرد تعریف میشود و باید با پیشوند urn:x-cast: شروع شود، به عنوان مثال، urn:x-cast:com.example.custom . میتوان چندین کانال سفارشی داشت که هر کدام یک فضای نام منحصر به فرد داشته باشند. برنامه گیرنده همچنین میتواند با استفاده از همان فضای نام، پیامها را ارسال و دریافت کند .
کانال سفارشی با رابط Cast.MessageReceivedCallback پیادهسازی شده است:
class HelloWorldChannel : MessageReceivedCallback { val namespace: String get() = "urn:x-cast:com.example.custom" override fun onMessageReceived(castDevice: CastDevice, namespace: String, message: String) { Log.d(TAG, "onMessageReceived: $message") } }
class HelloWorldChannel implements Cast.MessageReceivedCallback { public String getNamespace() { return "urn:x-cast:com.example.custom"; } @Override public void onMessageReceived(CastDevice castDevice, String namespace, String message) { Log.d(TAG, "onMessageReceived: " + message); } }
پس از اتصال برنامه فرستنده به برنامه گیرنده، میتوان کانال سفارشی را با استفاده از متد setMessageReceivedCallbacks ایجاد کرد:
try { mCastSession.setMessageReceivedCallbacks( mHelloWorldChannel.namespace, mHelloWorldChannel) } catch (e: IOException) { Log.e(TAG, "Exception while creating channel", e) }
try { mCastSession.setMessageReceivedCallbacks( mHelloWorldChannel.getNamespace(), mHelloWorldChannel); } catch (IOException e) { Log.e(TAG, "Exception while creating channel", e); }
پس از ایجاد کانال سفارشی، فرستنده میتواند از متد sendMessage برای ارسال پیامهای رشتهای به گیرنده از طریق آن کانال استفاده کند:
private fun sendMessage(message: String) { if (mHelloWorldChannel != null) { try { mCastSession.sendMessage(mHelloWorldChannel.namespace, message) .setResultCallback { status -> if (!status.isSuccess) { Log.e(TAG, "Sending message failed") } } } catch (e: Exception) { Log.e(TAG, "Exception while sending message", e) } } }
private void sendMessage(String message) { if (mHelloWorldChannel != null) { try { mCastSession.sendMessage(mHelloWorldChannel.getNamespace(), message) .setResultCallback( status -> { if (!status.isSuccess()) { Log.e(TAG, "Sending message failed"); } }); } catch (Exception e) { Log.e(TAG, "Exception while sending message", e); } } }
پشتیبانی از پخش خودکار
به بخش پخش خودکار و صفبندی APIها مراجعه کنید.
انتخاب تصویر را برای ابزارکهای UX لغو کنید
اجزای مختلف این چارچوب (یعنی کادر محاورهای Cast، مینی کنترلر و UIMediaController، در صورت پیکربندی) طرح گرافیکی مربوط به رسانهی در حال پخش فعلی را نمایش میدهند. URLهای مربوط به طرح گرافیکی تصویر معمولاً در MediaMetadata مربوط به رسانه گنجانده شدهاند، اما برنامهی فرستنده ممکن است منبع جایگزینی برای URLها داشته باشد.
کلاس ImagePicker ابزاری برای انتخاب یک تصویر مناسب از لیست تصاویر موجود در MediaMetadata ، بر اساس کاربرد تصویر، به عنوان مثال، تصویر کوچک اعلان یا پسزمینه تمام صفحه، تعریف میکند. پیادهسازی پیشفرض ImagePicker همیشه اولین تصویر را انتخاب میکند، یا اگر تصویری در MediaMetadata موجود نباشد، مقدار null را برمیگرداند. برنامه شما میتواند ImagePicker زیرکلاس کند و متد onPickImage(MediaMetadata, ImageHints) را برای ارائه یک پیادهسازی جایگزین، بازنویسی کند و سپس آن زیرکلاس را با متد setImagePicker از CastMediaOptions.Builder انتخاب کند. ImageHints نکاتی را در مورد نوع و اندازه تصویری که قرار است برای نمایش در رابط کاربری انتخاب شود، به ImagePicker ارائه میدهد.
سفارشیسازی پنجرههای محاورهای Cast
مدیریت چرخه حیات جلسه
SessionManager مکان مرکزی برای مدیریت چرخه حیات session است. SessionManager به تغییرات وضعیت انتخاب مسیر Android MediaRouter برای شروع، از سرگیری و پایان sessionها گوش میدهد. هنگامی که یک route انتخاب میشود، SessionManager یک شیء Session ایجاد میکند و سعی میکند آن را شروع یا از سر بگیرد. هنگامی که یک route انتخاب نشده باشد، SessionManager session فعلی را پایان میدهد.
بنابراین، برای اطمینان از اینکه SessionManager چرخه حیات session را به درستی مدیریت میکند، باید مطمئن شوید که:
- در پنجرهی انتخاب مسیر ، وقتی کاربر دستگاهی را انتخاب میکند
MediaRouter.selectRoute(MediaRouter.RouteInfo)را فراخوانی کنید. - در کادر محاورهای کنترلر مسیر (چه در حالت متصل و چه در حالت تبدیل مسیر )، وقتی کاربر تبدیل مسیر را متوقف کرد، تابع
MediaRouter.unselect(int)را فراخوانی کنید.
بسته به نحوه ایجاد پنجرههای محاورهای Cast، ممکن است لازم باشد اقدامات دیگری نیز انجام شود:
- اگر با استفاده از
MediaRouteChooserDialogوMediaRouteControllerDialogدیالوگهای Cast ایجاد کنید، این دیالوگها انتخاب مسیر را درMediaRouterبه طور خودکار بهروزرسانی میکنند، بنابراین نیازی به انجام کاری نیست. - اگر دکمهی ارسال خود را با استفاده از
CastButtonFactory.setUpMediaRouteButton(Context, Menu, int)یاCastButtonFactory.setUpMediaRouteButton(Context, MediaRouteButton)تنظیم کنید، در واقع دیالوگها با استفاده ازMediaRouteChooserDialogوMediaRouteControllerDialogایجاد میشوند، بنابراین نیازی به انجام کاری نیست. - برای موارد دیگر، شما دیالوگهای Cast سفارشی ایجاد خواهید کرد، بنابراین باید دستورالعملهای بالا را برای بهروزرسانی وضعیت انتخاب مسیر در
MediaRouterدنبال کنید.
حالت صفر دستگاه
اگر دیالوگهای Cast سفارشی ایجاد میکنید، MediaRouteChooserDialog سفارشی شما باید به درستی حالت عدم یافتن دستگاهها را مدیریت کند. این دیالوگ باید دارای نشانگرهایی باشد که به کاربران شما نشان دهد چه زمانی برنامه شما هنوز در تلاش برای یافتن دستگاهها است و چه زمانی تلاش برای یافتن دیگر فعال نیست.
اگر از MediaRouteChooserDialog پیشفرض استفاده میکنید، وضعیت دستگاههای صفر از قبل مدیریت میشود.
مراحل بعدی
این پایان ویژگیهایی است که میتوانید به برنامه فرستنده اندروید خود اضافه کنید. اکنون میتوانید یک برنامه فرستنده برای پلتفرم دیگری ( iOS یا وب ) بسازید، یا یک برنامه گیرنده وب بسازید.