ช่วงพักโฆษณา
Android Sender SDK รองรับช่วงพักโฆษณาและโฆษณาที่แสดงร่วมภายในสตรีมสื่อที่ระบุ
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีการทำงานของช่วงพักโฆษณาได้ที่ภาพรวมช่วงพักโฆษณาใน Webรอรับ
แม้ว่าคุณจะระบุช่วงพักได้ทั้งฝั่งผู้ส่งและผู้รับ แต่เราขอแนะนำให้ระบุช่วงพักโฆษณาในเว็บรีซีฟเวอร์และตัวรับสัญญาณ Android TV เพื่อให้ทำงานได้เหมือนกันในทุกแพลตฟอร์ม
ใน Android ให้ระบุช่วงพักโฆษณาในคำสั่งโหลดโดยใช้ 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
ของตัวเอง คุณจะต้องเพิ่มไฟล์ดังกล่าวลงในไฟล์ Manifest และตั้งชื่อไฟล์ใน 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
องค์ประกอบต่างๆ ของเฟรมเวิร์ก (ได้แก่ กล่องโต้ตอบแคสต์ มินิคอนโทรลเลอร์ และ UIMediaController หากมีการกำหนดค่าไว้) จะแสดงอาร์ตเวิร์กสำหรับสื่อที่กำลังแคสต์อยู่ ปกติแล้ว URL ของอาร์ตเวิร์กรูปภาพจะรวมอยู่ใน MediaMetadata
สำหรับสื่อ แต่แอปของผู้ส่งอาจมีแหล่งที่มาสำรองสำหรับ URL ดังกล่าว
คลาส ImagePicker
กำหนดวิธีการเลือกรูปภาพที่เหมาะสมจากรายการรูปภาพใน MediaMetadata
โดยอิงตามการใช้รูปภาพ เช่น ภาพปกการแจ้งเตือนหรือพื้นหลังแบบเต็มหน้าจอ การใช้งาน ImagePicker
เริ่มต้นจะเลือกรูปภาพแรกเสมอ หรือแสดงผลค่าว่างหากไม่มีรูปภาพที่ใช้ได้ใน MediaMetadata
แอปของคุณสามารถคลาสย่อย ImagePicker
และลบล้างเมธอด onPickImage(MediaMetadata, ImageHints)
เพื่อระบุการใช้งานทางเลือก จากนั้นเลือกคลาสย่อยนั้นด้วยเมธอด setImagePicker
ของ CastMediaOptions.Builder
ImageHints
ให้คำแนะนำแก่ ImagePicker
เกี่ยวกับประเภทและขนาดของรูปภาพที่จะเลือกให้แสดงใน UI
การปรับแต่งกล่องโต้ตอบการแคสต์
การจัดการวงจรเซสชัน
SessionManager
เป็นศูนย์กลางสำหรับการจัดการวงจรเซสชัน SessionManager
จะฟัง
การเปลี่ยนแปลงสถานะการเลือกเส้นทางของ Android
MediaRouter
เพื่อเริ่มต้น เล่นต่อ และจบเซสชัน เมื่อเลือกเส้นทางแล้ว SessionManager
จะสร้างออบเจ็กต์ Session
และพยายามเริ่มต้นหรือกลับมาทำงานอีกครั้ง เมื่อยกเลิกการเลือกเส้นทางแล้ว SessionManager
จะสิ้นสุดเซสชันปัจจุบัน
ดังนั้นเพื่อให้แน่ใจว่า SessionManager
จัดการวงจรเซสชันได้อย่างถูกต้อง คุณต้องตรวจสอบดังนี้
- ในกล่องโต้ตอบตัวเลือกเส้นทาง
ให้เรียกใช้
MediaRouter.selectRoute(MediaRouter.RouteInfo)
เมื่อผู้ใช้เลือกอุปกรณ์ - ในกล่องโต้ตอบตัวควบคุมเส้นทาง (ในสถานะที่เชื่อมต่อหรือสถานะการแคสต์) ให้โทร
MediaRouter.unselect(int)
เมื่อผู้ใช้หยุดแคสต์
คุณอาจต้องดำเนินการเพิ่มเติมดังต่อไปนี้ โดยขึ้นอยู่กับวิธีสร้างกล่องโต้ตอบการแคสต์
- หากคุณสร้างกล่องโต้ตอบแคสต์โดยใช้
MediaRouteChooserDialog
และMediaRouteControllerDialog
กล่องโต้ตอบเหล่านี้จะอัปเดตการเลือกเส้นทางในMediaRouter
โดยอัตโนมัติ คุณจึงไม่ต้องดำเนินการใดๆ - หากคุณตั้งค่าปุ่ม "แคสต์" โดยใช้
CastButtonFactory.setUpMediaRouteButton(Context, Menu, int)
หรือCastButtonFactory.setUpMediaRouteButton(Context, MediaRouteButton)
กล่องโต้ตอบจะสร้างขึ้นโดยใช้MediaRouteChooserDialog
และMediaRouteControllerDialog
จริงๆ คุณจึงไม่ต้องดำเนินการใดๆ เพิ่มเติม - สำหรับกรณีอื่นๆ คุณจะสร้างกล่องโต้ตอบการแคสต์ที่กำหนดเอง คุณจึงต้องทำตามวิธีการข้างต้นเพื่ออัปเดตสถานะการเลือกเส้นทางใน
MediaRouter
สถานะอุปกรณ์เป็นศูนย์
หากคุณสร้างกล่องโต้ตอบการแคสต์แบบกำหนดเอง MediaRouteChooserDialog
ที่กำหนดเองควรจัดการกรณีที่พบอุปกรณ์ 0 เครื่องได้อย่างเหมาะสม กล่องโต้ตอบควรมีสัญญาณบอกสถานะที่ให้ผู้ใช้ทราบอย่างชัดเจนเมื่อแอปของคุณกำลังพยายามค้นหาอุปกรณ์ และเมื่อไม่มีการพยายามค้นหาอุปกรณ์อีกต่อไป
หากคุณใช้ MediaRouteChooserDialog
เริ่มต้น ระบบจะจัดการสถานะอุปกรณ์เป็น 0 แล้ว
ขั้นตอนถัดไป
ส่วนนี้จะสรุปคุณลักษณะที่คุณสามารถเพิ่มลงในแอป Android Sender ของคุณ ตอนนี้คุณสามารถสร้างแอปผู้ส่งสำหรับแพลตฟอร์มอื่น (iOS หรือเว็บ) หรือสร้างแอปเว็บรีซีฟเวอร์ได้แล้ว