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