1. ภาพรวม
Codelab นี้จะสอนวิธีแก้ไขแอปวิดีโอ Android ที่มีอยู่เพื่อแคสต์เนื้อหาในอุปกรณ์ที่พร้อมใช้งาน Google Cast
Google Cast คืออะไร
Google Cast ช่วยให้ผู้ใช้แคสต์เนื้อหาจากอุปกรณ์เคลื่อนที่ไปยังทีวีได้ ผู้ใช้สามารถใช้อุปกรณ์เคลื่อนที่เป็นรีโมตคอนโทรลสําหรับการเล่นสื่อบนทีวีได้
Google Cast SDK ช่วยให้คุณขยายแอปเพื่อควบคุมทีวีหรือระบบเสียง Cast SDK ช่วยให้คุณเพิ่มคอมโพเนนต์ UI ที่จําเป็นได้ตามรายการตรวจสอบการออกแบบ Google Cast
รายการตรวจสอบการออกแบบ Google Cast มีไว้เพื่อช่วยให้ผู้ใช้ได้รับประสบการณ์การแคสต์ที่ใช้งานง่ายและคาดการณ์ได้ในทุกแพลตฟอร์มที่รองรับ
สิ่งที่เรากําลังสร้าง
เมื่อใช้ Codelab เสร็จสิ้น คุณจะมีแอปวิดีโอ Android ซึ่งจะแคสต์วิดีโอไปยังอุปกรณ์ที่พร้อมใช้งาน Google Cast ได้
สิ่งที่คุณจะได้เรียนรู้
- วิธีเพิ่ม Google Cast SDK ลงในแอปวิดีโอตัวอย่าง
- วิธีเพิ่มปุ่ม "แคสต์" เพื่อเลือกอุปกรณ์ Google Cast
- วิธีเชื่อมต่อกับอุปกรณ์แคสต์และเปิดตัวรับสื่อ
- วิธีแคสต์วิดีโอ
- วิธีเพิ่มตัวควบคุมแคสต์ขนาดเล็กลงในแอป
- วิธีรองรับการแจ้งเตือนสื่อและการควบคุมหน้าจอล็อก
- วิธีเพิ่มตัวควบคุมแบบขยาย
- วิธีใส่การวางซ้อนที่แนะนํา
- วิธีปรับแต่งวิดเจ็ตแคสต์
- วิธีผสานรวมกับ Cast Connect
สิ่งที่ต้องมี
- Android SDK เวอร์ชันล่าสุด
- Android Studio เวอร์ชัน 3.2 ขึ้นไป
- อุปกรณ์เคลื่อนที่เครื่องหนึ่งที่ใช้ Android 4.1 Jelly Bean (API ระดับ 16)
- สายข้อมูล USB เพื่อเชื่อมต่ออุปกรณ์เคลื่อนที่กับคอมพิวเตอร์ที่กําลังพัฒนา
- อุปกรณ์ Google Cast เช่น Chromecast หรือ Android TV ที่กําหนดค่าด้วยการเข้าถึงอินเทอร์เน็ต
- ทีวีหรือจอภาพที่มีอินพุต HDMI
- ต้องมี Chromecast ที่มี Google TV เพื่อทดสอบการผสานรวม Cast Connect แต่ไม่บังคับสําหรับ Codelab ที่เหลือ หากไม่มี โปรดข้ามขั้นตอนเพิ่มการรองรับ Cast Connect ไปที่ด้านล่างของบทแนะนํานี้
ประสบการณ์การใช้งาน
- คุณจะต้องมีความรู้เกี่ยวกับการพัฒนา Kotlin และ Android ก่อนหน้านี้
- และคุณก็ต้องมีความรู้เกี่ยวกับการดูทีวีด้วยนะ :)
คุณจะใช้บทแนะนํานี้อย่างไร
คุณจะให้คะแนนประสบการณ์ในการสร้างแอป Android เท่าไร
คุณจะให้คะแนนประสบการณ์ในการรับชมทีวีอย่างไร
2. รับโค้ดตัวอย่าง
คุณสามารถดาวน์โหลดโค้ดตัวอย่างทั้งหมดลงในคอมพิวเตอร์...
และแตกไฟล์ ZIP ที่ดาวน์โหลด
3. เรียกใช้แอปตัวอย่าง
ก่อนอื่น เรามาดูว่าแอปตัวอย่างที่สมบูรณ์มีลักษณะอย่างไร แอปเป็นโปรแกรมเล่นวิดีโอพื้นฐาน ผู้ใช้สามารถเลือกวิดีโอจากรายการและเล่นวิดีโอในเครื่องหรือแคสต์ไปยังอุปกรณ์ Google Cast ได้
เมื่อดาวน์โหลดโค้ดแล้ว วิธีการต่อไปนี้อธิบายวิธีเปิดและเรียกใช้แอปตัวอย่างที่สมบูรณ์ใน Android Studio
เลือกนําเข้าโปรเจ็กต์ในหน้าจอต้อนรับ หรือตัวเลือกเมนูไฟล์ > ใหม่ > นําเข้าโปรเจ็กต์...
เลือกไดเรกทอรี app-done
จากโฟลเดอร์โค้ดตัวอย่าง แล้วคลิก "ตกลง"
คลิกไฟล์ > ซิงค์โปรเจ็กต์กับ Gradle Files
เปิดใช้การแก้ไขข้อบกพร่อง USB บนอุปกรณ์ Android - ระบบจะซ่อนหน้าจอตัวเลือกสําหรับนักพัฒนาซอฟต์แวร์โดยค่าเริ่มต้นใน Android 4.2 ขึ้นไป หากต้องการให้มองเห็นได้ ให้ไปที่การตั้งค่า > เกี่ยวกับโทรศัพท์ แล้วแตะหมายเลขบิลด์ 7 ครั้ง กลับไปที่หน้าจอก่อนหน้า ไปที่ระบบ > ขั้นสูง แล้วแตะตัวเลือกสําหรับนักพัฒนาแอปใกล้กับด้านล่าง แล้วแตะการแก้ไขข้อบกพร่อง USB เพื่อเปิด
เสียบปลั๊กอุปกรณ์ Android แล้วคลิกปุ่ม Run ใน Android Studio คุณจะเห็นแอปวิดีโอชื่อแคสต์วิดีโอปรากฏขึ้นหลังจากผ่านไป 2-3 วินาที
คลิกปุ่ม "แคสต์" ในแอปวิดีโอ แล้วเลือกอุปกรณ์ Google Cast
เลือกวิดีโอแล้วคลิกปุ่มเล่น
วิดีโอจะเริ่มเล่นในอุปกรณ์ Google Cast
ตัวควบคุมแบบขยายจะปรากฏขึ้น คุณสามารถใช้ปุ่มเล่น/หยุดชั่วคราวเพื่อควบคุมการเล่นได้
กลับไปที่รายการวิดีโอ
ตอนนี้ตัวควบคุมขนาดเล็กจะแสดงอยู่ที่ด้านล่างของหน้าจอ
คลิกปุ่มหยุดชั่วคราวในตัวควบคุมขนาดเล็กเพื่อหยุดวิดีโอในอุปกรณ์รับชั่วคราว คลิกปุ่มเล่นในตัวควบคุมขนาดเล็กเพื่อเปิดวิดีโอต่อ
คลิกปุ่มหน้าแรกของอุปกรณ์เคลื่อนที่ ดึงการแจ้งเตือนลงและคุณจะเห็นการแจ้งเตือนสําหรับเซสชันการแคสต์
ล็อกโทรศัพท์และเมื่อคุณปลดล็อก คุณควรเห็นการแจ้งเตือนในหน้าจอล็อกเพื่อควบคุมการเล่นสื่อหรือหยุดแคสต์
กลับไปที่แอปวิดีโอแล้วคลิกปุ่ม "แคสต์" เพื่อหยุดแคสต์ในอุปกรณ์ Google Cast
คำถามที่พบบ่อย
4. เตรียมโปรเจ็กต์เริ่มต้น
เราต้องเพิ่มการรองรับ Google Cast ในแอปเริ่มต้นที่คุณดาวน์โหลด คําศัพท์ของ Google Cast ต่อไปนี้เราจะใช้ใน Codelab นี้
- แอปผู้ส่งทํางานในอุปกรณ์เคลื่อนที่หรือแล็ปท็อป
- แอปตัวรับทํางานในอุปกรณ์ Google Cast
ตอนนี้คุณพร้อมแล้วที่จะต่อยอดโปรเจ็กต์เริ่มต้นโดยใช้ Android Studio โดยทําดังนี้
- เลือกไดเรกทอรี
app-start
จากการดาวน์โหลดโค้ดตัวอย่าง (เลือกนําเข้าโปรเจ็กต์ในหน้าจอต้อนรับ หรือตัวเลือกเมนูไฟล์ > ใหม่ > นําเข้าโปรเจ็กต์...) - คลิกปุ่ม
ซิงค์โปรเจ็กต์กับ Gradle Files
- คลิกปุ่ม
เรียกใช้เพื่อเรียกใช้แอปและสํารวจ UI
การออกแบบแอป
แอปดึงข้อมูลรายการวิดีโอจากเว็บเซิร์ฟเวอร์ระยะไกลและให้รายการสําหรับผู้ใช้เรียกดู ผู้ใช้สามารถเลือกวิดีโอเพื่อดูรายละเอียดหรือเล่นวิดีโอในเครื่องได้
แอปประกอบด้วยกิจกรรมหลัก 2 อย่าง ได้แก่ VideoBrowserActivity
และ LocalPlayerActivity
หากต้องการผสานรวมฟังก์ชันการทํางานของ Google Cast กิจกรรมต้องรับค่าจาก AppCompatActivity
หรือ FragmentActivity
ระดับบน ข้อจํากัดนี้มีผลเนื่องจากเราต้องเพิ่ม MediaRouteButton
(ที่ระบุไว้ในไลบรารีการสนับสนุนของ MediaRouter) เป็น MediaRouteActionProvider
และจะใช้งานได้ก็ต่อเมื่อกิจกรรมรับค่าจากคลาสที่กล่าวถึงข้างต้นเท่านั้น ไลบรารีการสนับสนุนของ MediaRouter จะขึ้นอยู่กับไลบรารีการสนับสนุน AppCompat ซึ่งมีคลาสที่จําเป็น
กิจกรรมเบราว์เซอร์วิดีโอ
กิจกรรมนี้มี Fragment
(VideoBrowserFragment
) รายการนี้ได้รับการสนับสนุนจาก ArrayAdapter
(VideoListAdapter
) รายการวิดีโอและข้อมูลเมตาที่เกี่ยวข้องจะโฮสต์บนเซิร์ฟเวอร์ระยะไกลเป็นไฟล์ JSON AsyncTaskLoader
(VideoItemLoader
) จะดึงข้อมูล JSON นี้ และประมวลผลเพื่อสร้างรายการออบเจ็กต์ MediaItem
ออบเจ็กต์ MediaItem
สร้างโมเดลวิดีโอและข้อมูลเมตาที่เกี่ยวข้อง เช่น ชื่อ คําอธิบาย URL ของสตรีม, URL ของรูปภาพที่รองรับ และแทร็กข้อความที่เกี่ยวข้อง (สําหรับคําบรรยาย) หากมี ระบบจะส่งออบเจ็กต์ MediaItem
ระหว่างกิจกรรม ดังนั้น MediaItem
จะมีเมธอดยูทิลิตีในการแปลงเป็น Bundle
และในทางกลับกันด้วย
เมื่อตัวโหลดสร้างรายการ MediaItems
ทรัพยากรจะส่งรายการนี้ไปยัง VideoListAdapter
จากนั้นจะแสดงรายการ MediaItems
ใน VideoBrowserFragment
ผู้ใช้มีรายการภาพขนาดย่อพร้อมคําอธิบายสั้นๆ สําหรับวิดีโอแต่ละรายการ เมื่อมีการเลือกรายการ ระบบจะแปลง MediaItem
ที่เกี่ยวข้องเป็น Bundle
และส่งต่อไปยัง LocalPlayerActivity
กิจกรรมโปรแกรมเล่นในพื้นที่
กิจกรรมนี้แสดงข้อมูลเมตาเกี่ยวกับวิดีโอที่เฉพาะเจาะจงและอนุญาตให้ผู้ใช้เล่นวิดีโอในเครื่องได้
กิจกรรมนี้จะมีVideoView
ตัวควบคุมสื่อบางรายการ และพื้นที่ข้อความสําหรับแสดงคําอธิบายวิดีโอที่เลือก โปรแกรมเล่นครอบคลุมพื้นที่ด้านบนของหน้าจอ รวมถึงคําอธิบายวิดีโอด้านล่าง ผู้ใช้สามารถเล่น/หยุดชั่วคราวหรือค้นหาการเล่นวิดีโอในเครื่องได้
การอ้างอิง
เนื่องจากเราใช้ AppCompatActivity
คุณจึงต้องมีไลบรารีการสนับสนุน AppCompat เราใช้ไลบรารี Volley ในการจัดการรายการวิดีโอและการรับข้อมูลรูปภาพในแบบไม่พร้อมกัน
คำถามที่พบบ่อย
5. การเพิ่มปุ่ม "แคสต์"
แอปพลิเคชันที่พร้อมใช้งาน Cast จะแสดงปุ่ม "แคสต์" ในแต่ละกิจกรรม การคลิกปุ่มแคสต์จะแสดงรายการอุปกรณ์แคสต์ที่ผู้ใช้สามารถเลือกได้ หากผู้ใช้เล่นเนื้อหาภายในอุปกรณ์ของผู้ส่ง การเลือกอุปกรณ์แคสต์จะเริ่มต้นหรือเล่นต่อในอุปกรณ์แคสต์นั้น ผู้ใช้สามารถคลิกปุ่ม "แคสต์" และหยุดแคสต์แอปพลิเคชันไปยังอุปกรณ์แคสต์ได้ทุกเมื่อระหว่างเซสชันการแคสต์ ผู้ใช้ต้องสามารถเชื่อมต่อหรือยกเลิกการเชื่อมต่ออุปกรณ์แคสต์ขณะทํากิจกรรมใดๆ ของแอปพลิเคชันได้ ตามที่อธิบายไว้ในรายการตรวจสอบการออกแบบ Google Cast
การอ้างอิง
อัปเดตไฟล์ build.gradle ของแอปเพื่อรวมทรัพยากร Dependency ที่จําเป็นของไลบรารี ดังนี้
dependencies {
implementation 'androidx.appcompat:appcompat:1.5.0'
implementation 'androidx.mediarouter:mediarouter:1.3.1'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation 'com.google.android.gms:play-services-cast-framework:21.1.0'
implementation 'com.android.volley:volley:1.2.1'
implementation "androidx.core:core-ktx:1.8.0"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
}
ซิงค์โปรเจ็กต์เพื่อยืนยันการสร้างโปรเจ็กต์โดยไม่มีข้อผิดพลาด
การเริ่มต้น
เฟรมเวิร์ก "แคสต์" มีออบเจ็กต์ Singleton ทั่วโลกที่ชื่อว่า CastContext
ซึ่งจะประสานการโต้ตอบกับ Cast ทั้งหมด
คุณต้องใช้อินเทอร์เฟซ OptionsProvider
เพื่อระบุ CastOptions
ที่จําเป็นในการเริ่มต้น Singleton CastContext
ตัวเลือกที่สําคัญที่สุดคือรหัสแอปพลิเคชันตัวรับสัญญาณที่ใช้ในการกรองผลการค้นหาอุปกรณ์แคสต์และเปิดแอปพลิเคชันสําหรับผู้รับเมื่อเซสชันการแคสต์เริ่มต้น
เมื่อคุณพัฒนาแอปที่พร้อมใช้งาน Cast ของคุณเอง คุณจะต้องลงทะเบียนเป็นนักพัฒนาซอฟต์แวร์การแคสต์ แล้วรับรหัสแอปพลิเคชันสําหรับแอปของคุณ สําหรับ Codelab นี้ เราจะใช้รหัสแอปตัวอย่าง
เพิ่มไฟล์ CastOptionsProvider.kt
ใหม่ต่อไปนี้ไปยังแพ็กเกจ com.google.sample.cast.refplayer
ของโปรเจ็กต์
package com.google.sample.cast.refplayer
import android.content.Context
import com.google.android.gms.cast.framework.OptionsProvider
import com.google.android.gms.cast.framework.CastOptions
import com.google.android.gms.cast.framework.SessionProvider
class CastOptionsProvider : OptionsProvider {
override fun getCastOptions(context: Context): CastOptions {
return CastOptions.Builder()
.setReceiverApplicationId(context.getString(R.string.app_id))
.build()
}
override fun getAdditionalSessionProviders(context: Context): List<SessionProvider>? {
return null
}
}
ตอนนี้ประกาศ OptionsProvider
ภายในแท็ก "application
" ของไฟล์ AndroidManifest.xml
ของแอปดังนี้
<meta-data
android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
android:value="com.google.sample.cast.refplayer.CastOptionsProvider" />
โดยปกติแล้วเริ่มต้น CastContext
ในเมธอด VideoBrowserActivity
Create on
import com.google.android.gms.cast.framework.CastContext
private var mCastContext: CastContext? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.video_browser)
setupActionBar()
mCastContext = CastContext.getSharedInstance(this)
}
เพิ่มตรรกะการเริ่มต้นเดียวกันใน LocalPlayerActivity
ปุ่ม "แคสต์"
เมื่อ CastContext
เริ่มต้นแล้ว เราต้องเพิ่มปุ่ม "แคสต์" เพื่อให้ผู้ใช้เลือกอุปกรณ์แคสต์ได้ MediaRouteButton
จะใช้ปุ่ม "แคสต์" จากไลบรารีการสนับสนุน MediaRouter เช่นเดียวกับไอคอนการทํางานใดๆ ที่คุณเพิ่มลงในกิจกรรมได้ (โดยใช้ ActionBar
หรือ Toolbar
) คุณต้องเพิ่มรายการในเมนูที่เกี่ยวข้องก่อนลงในเมนู
แก้ไขไฟล์ res/menu/browse.xml
และเพิ่มรายการ MediaRouteActionProvider
ในเมนูก่อนรายการการตั้งค่า ดังนี้
<item
android:id="@+id/media_route_menu_item"
android:title="@string/media_route_menu_title"
app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"
app:showAsAction="always"/>
ลบล้างเมธอด onCreateOptionsMenu()
ของ VideoBrowserActivity
โดยใช้ CastButtonFactory
เพื่อเชื่อมต่อ MediaRouteButton
กับเฟรมเวิร์กแคสต์
import com.google.android.gms.cast.framework.CastButtonFactory
private var mediaRouteMenuItem: MenuItem? = null
override fun onCreateOptionsMenu(menu: Menu): Boolean {
super.onCreateOptionsMenu(menu)
menuInflater.inflate(R.menu.browse, menu)
mediaRouteMenuItem = CastButtonFactory.setUpMediaRouteButton(getApplicationContext(), menu,
R.id.media_route_menu_item)
return true
}
ลบล้าง onCreateOptionsMenu
ใน LocalPlayerActivity
ในลักษณะเดียวกัน
คลิกปุ่มเรียกใช้เพื่อเรียกใช้แอปบนอุปกรณ์เคลื่อนที่ คุณควรเห็นปุ่ม "แคสต์" ในแถบการดําเนินการของแอป และเมื่อคุณคลิกแล้ว ปุ่มดังกล่าวจะแสดงอุปกรณ์แคสต์ในเครือข่ายท้องถิ่นของคุณ
CastContext
จะจัดการการค้นพบอุปกรณ์โดยอัตโนมัติ เลือกอุปกรณ์แคสต์ แล้วแอปตัวรับตัวอย่างจะโหลดในอุปกรณ์แคสต์ คุณสามารถสลับระหว่างกิจกรรมการท่องเว็บและกิจกรรมในพื้นที่ของผู้เล่นกับสถานะปุ่ม "แคสต์" ที่ซิงค์ไว้ได้
เนื่องจากเรายังไม่ได้รองรับการรองรับการเล่นสื่อ คุณจึงยังเล่นวิดีโอในอุปกรณ์แคสต์ไม่ได้ คลิกปุ่มแคสต์เพื่อยกเลิกการเชื่อมต่อ
6. การแคสต์เนื้อหาวิดีโอ
เราจะขยายตัวอย่างแอปให้เล่นวิดีโอจากระยะไกลในอุปกรณ์แคสต์ด้วย เราต้องฟังเหตุการณ์ต่างๆ ที่สร้างโดยเฟรมเวิร์กแคสต์
การแคสต์สื่อ
ที่ระดับสูง หากต้องการเล่นสื่อในอุปกรณ์แคสต์ คุณต้องดําเนินการต่อไปนี้
- สร้างออบเจ็กต์
MediaInfo
ที่จําลองรายการสื่อ - เชื่อมต่ออุปกรณ์ Cast และเปิดแอปพลิเคชันตัวรับสัญญาณ
- โหลดออบเจ็กต์
MediaInfo
ลงในตัวรับและเล่นเนื้อหา - ติดตามสถานะสื่อ
- ส่งคําสั่งการเล่นไปยังผู้รับตามการโต้ตอบของผู้ใช้
เราได้ทําตามขั้นตอนที่ 2 ในส่วนก่อนหน้าแล้ว ขั้นตอนที่ 3 สามารถทําได้ง่ายๆ ด้วยเฟรมเวิร์กการแคสต์ ขั้นตอนที่ 1 ในการแมปออบเจ็กต์หนึ่งกับออบเจ็กต์อื่น MediaInfo
คือสิ่งที่เฟรมเวิร์ก Cast เข้าใจและ MediaItem
เป็นการรวมรายการแอปของเรากับสื่อ เราแมป MediaItem
กับ MediaInfo
ได้อย่างง่ายดาย
แอปตัวอย่าง LocalPlayerActivity
แยกความแตกต่างระหว่างการเล่นในเครื่องกับการเล่นจากระยะไกลอยู่แล้วโดยใช้ Enum นี้
private var mLocation: PlaybackLocation? = null
enum class PlaybackLocation {
LOCAL, REMOTE
}
enum class PlaybackState {
PLAYING, PAUSED, BUFFERING, IDLE
}
การทํา Codelab นี้ไม่ได้สําคัญสําหรับคุณในการทําความเข้าใจวิธีการทํางานของตรรกะของตัวอย่างโปรแกรมเล่นทั้งหมด โปรดทราบว่าคุณจะต้องแก้ไขโปรแกรมเล่นสื่อของแอปให้ทราบเกี่ยวกับตําแหน่งการเล่น 2 แห่งที่คล้ายกัน
ขณะนี้โปรแกรมเล่นในเครื่องจะอยู่ในสถานะการเล่นในเครื่องเสมอ เนื่องจากยังไม่รู้สถานะการแคสต์ เราจําเป็นต้องอัปเดต UI ตามการเปลี่ยนแปลงสถานะที่เกิดขึ้นในเฟรมเวิร์ก Cast เช่น หากเราเริ่มแคสต์ เราต้องหยุดการเล่นในเครื่องและปิดใช้การควบคุมบางอย่าง ในทํานองเดียวกัน หากเราหยุดแคสต์เมื่ออยู่ในกิจกรรมนี้ เราจําเป็นต้องเปลี่ยนไปใช้การเล่นในเครื่อง ในการจัดการว่าเราต้องฟังเหตุการณ์ต่างๆ ที่เฟรมเวิร์กแคสต์สร้างขึ้น
การจัดการเซสชันการแคสต์
สําหรับเฟรมเวิร์กการแคสต์ เซสชันแคสต์จะรวมขั้นตอนการเชื่อมต่ออุปกรณ์ การเปิดตัว (หรือการเข้าร่วม) การเชื่อมต่อกับแอปพลิเคชันตัวรับ และการเริ่มต้นแชแนลการควบคุมสื่อตามความเหมาะสม ช่องทางการควบคุมสื่อคือวิธีที่เฟรมเวิร์กแคสต์ส่งและรับข้อความจากโปรแกรมเล่นสื่อของผู้รับ
เซสชันการแคสต์จะเริ่มต้นโดยอัตโนมัติเมื่อผู้ใช้เลือกอุปกรณ์จากปุ่ม "แคสต์" และจะหยุดโดยอัตโนมัติเมื่อผู้ใช้ยกเลิกการเชื่อมต่อ Cast SDK จะจัดการการเชื่อมต่อเซสชันผู้รับอีกครั้งเนื่องจากปัญหาเครือข่ายโดยอัตโนมัติ
มาเพิ่ม SessionManagerListener
ใน LocalPlayerActivity
กันเถอะ
import com.google.android.gms.cast.framework.CastSession
import com.google.android.gms.cast.framework.SessionManagerListener
...
private var mSessionManagerListener: SessionManagerListener<CastSession>? = null
private var mCastSession: CastSession? = null
...
private fun setupCastListener() {
mSessionManagerListener = object : SessionManagerListener<CastSession> {
override fun onSessionEnded(session: CastSession, error: Int) {
onApplicationDisconnected()
}
override fun onSessionResumed(session: CastSession, wasSuspended: Boolean) {
onApplicationConnected(session)
}
override fun onSessionResumeFailed(session: CastSession, error: Int) {
onApplicationDisconnected()
}
override fun onSessionStarted(session: CastSession, sessionId: String) {
onApplicationConnected(session)
}
override fun onSessionStartFailed(session: CastSession, error: Int) {
onApplicationDisconnected()
}
override fun onSessionStarting(session: CastSession) {}
override fun onSessionEnding(session: CastSession) {}
override fun onSessionResuming(session: CastSession, sessionId: String) {}
override fun onSessionSuspended(session: CastSession, reason: Int) {}
private fun onApplicationConnected(castSession: CastSession) {
mCastSession = castSession
if (null != mSelectedMedia) {
if (mPlaybackState == PlaybackState.PLAYING) {
mVideoView!!.pause()
loadRemoteMedia(mSeekbar!!.progress, true)
return
} else {
mPlaybackState = PlaybackState.IDLE
updatePlaybackLocation(PlaybackLocation.REMOTE)
}
}
updatePlayButton(mPlaybackState)
invalidateOptionsMenu()
}
private fun onApplicationDisconnected() {
updatePlaybackLocation(PlaybackLocation.LOCAL)
mPlaybackState = PlaybackState.IDLE
mLocation = PlaybackLocation.LOCAL
updatePlayButton(mPlaybackState)
invalidateOptionsMenu()
}
}
}
ในกิจกรรม LocalPlayerActivity
เราสนใจรับการแจ้งเตือนเมื่อเชื่อมต่อหรือถูกตัดการเชื่อมต่อจากอุปกรณ์แคสต์ เพื่อที่จะสามารถสลับไปยังหรือจากโปรแกรมเล่นในเครื่อง โปรดทราบว่าการเชื่อมต่ออาจหยุดชะงักเพียงอินสแตนซ์ของแอปพลิเคชันที่ทํางานบนอุปกรณ์เคลื่อนที่เท่านั้น แต่ยังขัดขวางแอปพลิเคชันอื่น (หรือแอปอื่น) ที่ทํางานบนอุปกรณ์เคลื่อนที่อื่นๆ ด้วย
เข้าถึงเซสชันที่ใช้งานอยู่เป็น SessionManager.getCurrentSession()
ได้แล้ว ระบบจะสร้างเซสชันและถูกแยกย่อยโดยอัตโนมัติเพื่อตอบสนองต่อการโต้ตอบของผู้ใช้ที่มีต่อกล่องโต้ตอบการแคสต์
เราจําเป็นต้องลงทะเบียน Listener เซสชันและเริ่มต้นตัวแปรบางตัวซึ่งเราจะใช้ในกิจกรรม เปลี่ยนวิธีLocalPlayerActivity
ของ onCreate
เป็น
import com.google.android.gms.cast.framework.CastContext
...
private var mCastContext: CastContext? = null
...
override fun onCreate(savedInstanceState: Bundle?) {
...
mCastContext = CastContext.getSharedInstance(this)
mCastSession = mCastContext!!.sessionManager.currentCastSession
setupCastListener()
...
loadViews()
...
val bundle = intent.extras
if (bundle != null) {
....
if (shouldStartPlayback) {
....
} else {
if (mCastSession != null && mCastSession!!.isConnected()) {
updatePlaybackLocation(PlaybackLocation.REMOTE)
} else {
updatePlaybackLocation(PlaybackLocation.LOCAL)
}
mPlaybackState = PlaybackState.IDLE
updatePlayButton(mPlaybackState)
}
}
...
}
กําลังโหลดสื่อ
ใน Cast SDK RemoteMediaClient
มีชุด API ที่ใช้งานสะดวกสําหรับการจัดการการเล่นสื่อระยะไกลบนตัวรับ สําหรับ CastSession
ที่รองรับการเล่นสื่อ ระบบจะสร้างอินสแตนซ์ของ RemoteMediaClient
โดยอัตโนมัติโดย SDK คุณสามารถเข้าถึงได้โดยการเรียกเมธอด getRemoteMediaClient()
ในอินสแตนซ์ CastSession
เพิ่มวิธีการต่อไปนี้ใน LocalPlayerActivity
เพื่อโหลดวิดีโอที่เลือกอยู่ในปัจจุบันในเครื่องรับ
import com.google.android.gms.cast.framework.media.RemoteMediaClient
import com.google.android.gms.cast.MediaInfo
import com.google.android.gms.cast.MediaLoadOptions
import com.google.android.gms.cast.MediaMetadata
import com.google.android.gms.common.images.WebImage
import com.google.android.gms.cast.MediaLoadRequestData
private fun loadRemoteMedia(position: Int, autoPlay: Boolean) {
if (mCastSession == null) {
return
}
val remoteMediaClient = mCastSession!!.remoteMediaClient ?: return
remoteMediaClient.load( MediaLoadRequestData.Builder()
.setMediaInfo(buildMediaInfo())
.setAutoplay(autoPlay)
.setCurrentTime(position.toLong()).build())
}
private fun buildMediaInfo(): MediaInfo? {
val movieMetadata = MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE)
mSelectedMedia?.studio?.let { movieMetadata.putString(MediaMetadata.KEY_SUBTITLE, it) }
mSelectedMedia?.title?.let { movieMetadata.putString(MediaMetadata.KEY_TITLE, it) }
movieMetadata.addImage(WebImage(Uri.parse(mSelectedMedia!!.getImage(0))))
movieMetadata.addImage(WebImage(Uri.parse(mSelectedMedia!!.getImage(1))))
return mSelectedMedia!!.url?.let {
MediaInfo.Builder(it)
.setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
.setContentType("videos/mp4")
.setMetadata(movieMetadata)
.setStreamDuration((mSelectedMedia!!.duration * 1000).toLong())
.build()
}
}
อัปเดตเมธอดต่างๆ ที่มีอยู่เพื่อใช้ตรรกะของเซสชันแคสต์เพื่อรองรับการเล่นจากระยะไกล ดังนี้
private fun play(position: Int) {
startControllersTimer()
when (mLocation) {
PlaybackLocation.LOCAL -> {
mVideoView!!.seekTo(position)
mVideoView!!.start()
}
PlaybackLocation.REMOTE -> {
mPlaybackState = PlaybackState.BUFFERING
updatePlayButton(mPlaybackState)
//seek to a new position within the current media item's new position
//which is in milliseconds from the beginning of the stream
mCastSession!!.remoteMediaClient?.seek(position.toLong())
}
else -> {}
}
restartTrickplayTimer()
}
private fun togglePlayback() {
...
PlaybackState.IDLE -> when (mLocation) {
...
PlaybackLocation.REMOTE -> {
if (mCastSession != null && mCastSession!!.isConnected) {
loadRemoteMedia(mSeekbar!!.progress, true)
}
}
else -> {}
}
...
}
override fun onPause() {
...
mCastContext!!.sessionManager.removeSessionManagerListener(
mSessionManagerListener!!, CastSession::class.java)
}
override fun onResume() {
Log.d(TAG, "onResume() was called")
mCastContext!!.sessionManager.addSessionManagerListener(
mSessionManagerListener!!, CastSession::class.java)
if (mCastSession != null && mCastSession!!.isConnected) {
updatePlaybackLocation(PlaybackLocation.REMOTE)
} else {
updatePlaybackLocation(PlaybackLocation.LOCAL)
}
super.onResume()
}
สําหรับเมธอด updatePlayButton
ให้เปลี่ยนค่าของตัวแปร isConnected
ดังนี้
private fun updatePlayButton(state: PlaybackState?) {
...
val isConnected = (mCastSession != null
&& (mCastSession!!.isConnected || mCastSession!!.isConnecting))
...
}
ตอนนี้ ให้คลิกปุ่มเรียกใช้เพื่อเรียกใช้แอปบนอุปกรณ์เคลื่อนที่ของคุณ เชื่อมต่อกับอุปกรณ์แคสต์ของคุณและเริ่มเล่นวิดีโอ คุณควรเห็นวิดีโอกําลังเล่นบนตัวรับ
7. ตัวควบคุมขนาดเล็ก
รายการตรวจสอบการออกแบบการแคสต์กําหนดให้แอปแคสต์ทั้งหมดมีตัวควบคุมขนาดเล็กที่ปรากฏเมื่อผู้ใช้ออกจากหน้าเนื้อหาปัจจุบัน ตัวควบคุมขนาดเล็กเข้าถึงได้ทันทีและการช่วยเตือนที่มองเห็นได้สําหรับเซสชันการแคสต์ปัจจุบัน
Cast SDK แสดงมุมมองที่กําหนดเอง MiniControllerFragment
ซึ่งเพิ่มไปยังไฟล์เลย์เอาต์แอปของกิจกรรมที่คุณต้องการแสดงตัวควบคุมขนาดเล็ก
เพิ่มคําจํากัดความส่วนย่อยต่อไปนี้ที่ด้านล่างของ res/layout/player_activity.xml
และ res/layout/video_browser.xml
<fragment
android:id="@+id/castMiniController"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:visibility="gone"
class="com.google.android.gms.cast.framework.media.widget.MiniControllerFragment"/>
คลิกปุ่มเรียกใช้เพื่อเรียกใช้แอปและแคสต์วิดีโอ เมื่อการเล่นเริ่มเล่นบนตัวรับ คุณควรเห็นตัวควบคุมขนาดเล็กปรากฏที่ด้านล่างของกิจกรรมแต่ละอย่าง คุณสามารถควบคุมการเล่นจากระยะไกลโดยใช้ตัวควบคุมขนาดเล็กได้ หากคุณไปยังกิจกรรมการท่องเว็บและกิจกรรมของผู้เล่นในพื้นที่ สถานะตัวควบคุมขนาดเล็กควรซิงค์กับสถานะการเล่นสื่อของผู้รับ
8. การแจ้งเตือนและหน้าจอล็อก
รายการตรวจสอบการออกแบบ Google Cast กําหนดให้แอปผู้ส่งใช้ตัวควบคุมสื่อจากการแจ้งเตือนและหน้าจอล็อก
Cast SDK มี MediaNotificationService
เพื่อช่วยให้แอปผู้ส่งสร้างตัวควบคุมสื่อสําหรับการแจ้งเตือนและหน้าจอล็อก บริการจะผสานเข้ากับไฟล์ Manifest ของแอปโดยอัตโนมัติแบบค่อยเป็นค่อยไป
MediaNotificationService
จะทํางานในเบื้องหลังเมื่อผู้ส่งแคสต์ และจะแสดงการแจ้งเตือนที่มีภาพขนาดย่อและข้อมูลเมตาเกี่ยวกับรายการแคสต์ปัจจุบัน ปุ่มเล่น/หยุดชั่วคราว และปุ่มหยุด
สามารถเปิดใช้การควบคุมการแจ้งเตือนและหน้าจอล็อกด้วย CastOptions
เมื่อเริ่มต้น CastContext
การควบคุมสื่อสําหรับการแจ้งเตือนและหน้าจอล็อกจะเปิดอยู่โดยค่าเริ่มต้น ฟีเจอร์หน้าจอล็อกจะเปิดอยู่ตราบใดที่เปิดการแจ้งเตือนไว้
แก้ไข CastOptionsProvider
และเปลี่ยนการใช้งาน getCastOptions
ให้ตรงกับรหัสนี้
import com.google.android.gms.cast.framework.media.CastMediaOptions
import com.google.android.gms.cast.framework.media.NotificationOptions
override fun getCastOptions(context: Context): CastOptions {
val notificationOptions = NotificationOptions.Builder()
.setTargetActivityClassName(VideoBrowserActivity::class.java.name)
.build()
val mediaOptions = CastMediaOptions.Builder()
.setNotificationOptions(notificationOptions)
.build()
return CastOptions.Builder()
.setReceiverApplicationId(context.getString(R.string.app_id))
.setCastMediaOptions(mediaOptions)
.build()
}
คลิกปุ่มเรียกใช้เพื่อเรียกใช้แอปบนอุปกรณ์เคลื่อนที่ แคสต์วิดีโอและออกจากแอปตัวอย่าง ควรมีการแจ้งเตือนสําหรับวิดีโอที่กําลังเล่นอยู่ในผู้รับ ล็อกหน้าจอในอุปกรณ์เคลื่อนที่ ตอนนี้หน้าจอล็อกจะแสดงตัวควบคุมของการเล่นสื่อในอุปกรณ์แคสต์
9. การวางซ้อนที่แนะนํา
รายการตรวจสอบการออกแบบของ Google Cast กําหนดให้แอปผู้ส่งต้องแนะนําปุ่ม "แคสต์" ให้กับผู้ใช้ที่มีอยู่เพื่อแจ้งให้ทราบว่าแอปของผู้ส่งรองรับการแคสต์และยังช่วยให้ผู้ใช้เพิ่งเริ่มใช้ Google Cast ได้ด้วย
Cast SDK แสดงมุมมองที่กําหนดเอง IntroductoryOverlay
ที่ใช้ไฮไลต์ปุ่ม "แคสต์" ได้เมื่อแสดงให้ผู้ใช้เห็นเป็นครั้งแรก เพิ่มโค้ดต่อไปนี้ลงใน VideoBrowserActivity
import com.google.android.gms.cast.framework.IntroductoryOverlay
import android.os.Looper
private var mIntroductoryOverlay: IntroductoryOverlay? = null
private fun showIntroductoryOverlay() {
mIntroductoryOverlay?.remove()
if (mediaRouteMenuItem?.isVisible == true) {
Looper.myLooper().run {
mIntroductoryOverlay = com.google.android.gms.cast.framework.IntroductoryOverlay.Builder(
this@VideoBrowserActivity, mediaRouteMenuItem!!)
.setTitleText("Introducing Cast")
.setSingleTime()
.setOnOverlayDismissedListener(
object : IntroductoryOverlay.OnOverlayDismissedListener {
override fun onOverlayDismissed() {
mIntroductoryOverlay = null
}
})
.build()
mIntroductoryOverlay!!.show()
}
}
}
ตอนนี้ ให้เพิ่ม CastStateListener
และเรียกเมธอด showIntroductoryOverlay
เมื่ออุปกรณ์แคสต์พร้อมใช้งาน โดยแก้ไขเมธอด onCreate
และลบล้างเมธอด onResume
และ onPause
เพื่อให้ตรงกับกรณีต่อไปนี้
import com.google.android.gms.cast.framework.CastState
import com.google.android.gms.cast.framework.CastStateListener
private var mCastStateListener: CastStateListener? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.video_browser)
setupActionBar()
mCastStateListener = object : CastStateListener {
override fun onCastStateChanged(newState: Int) {
if (newState != CastState.NO_DEVICES_AVAILABLE) {
showIntroductoryOverlay()
}
}
}
mCastContext = CastContext.getSharedInstance(this)
}
override fun onResume() {
super.onResume()
mCastContext?.addCastStateListener(mCastStateListener!!)
}
override fun onPause() {
super.onPause()
mCastContext?.removeCastStateListener(mCastStateListener!!)
}
ล้างข้อมูลแอปหรือนําแอปออกจากอุปกรณ์ แล้วคลิกปุ่มเรียกใช้เพื่อเรียกใช้แอปบนอุปกรณ์เคลื่อนที่ และคุณควรเห็นการวางซ้อนบทนํา (ล้างข้อมูลแอปหากการวางซ้อนไม่แสดง)
10. ตัวควบคุมแบบขยาย
รายการตรวจสอบการออกแบบ Google Cast กําหนดให้แอปของผู้ส่งต้องมีตัวควบคุมแบบขยายสําหรับสื่อที่กําลังแคสต์ ตัวควบคุมแบบขยายเป็นเวอร์ชันเต็มหน้าจอของตัวควบคุมขนาดเล็ก
Cast SDK มีวิดเจ็ตสําหรับตัวควบคุมแบบขยายชื่อ ExpandedControllerActivity
นี่คือชั้นเรียนนามธรรมที่คุณต้องเรียนชั้นย่อยเพื่อเพิ่มปุ่มแคสต์
ก่อนอื่น ให้สร้างไฟล์ทรัพยากรของเมนูใหม่ที่ชื่อ expanded_controller.xml
สําหรับตัวควบคุมแบบขยายให้มีปุ่ม "แคสต์"
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/media_route_menu_item"
android:title="@string/media_route_menu_title"
app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"
app:showAsAction="always"/>
</menu>
สร้างแพ็กเกจใหม่ expandedcontrols
ในแพ็กเกจ com.google.sample.cast.refplayer
จากนั้นสร้างไฟล์ใหม่ชื่อ ExpandedControlsActivity.kt
ในแพ็กเกจ com.google.sample.cast.refplayer.expandedcontrols
package com.google.sample.cast.refplayer.expandedcontrols
import android.view.Menu
import com.google.android.gms.cast.framework.media.widget.ExpandedControllerActivity
import com.google.sample.cast.refplayer.R
import com.google.android.gms.cast.framework.CastButtonFactory
class ExpandedControlsActivity : ExpandedControllerActivity() {
override fun onCreateOptionsMenu(menu: Menu): Boolean {
super.onCreateOptionsMenu(menu)
menuInflater.inflate(R.menu.expanded_controller, menu)
CastButtonFactory.setUpMediaRouteButton(this, menu, R.id.media_route_menu_item)
return true
}
}
ในตอนนี้ ให้ประกาศ ExpandedControlsActivity
ใน AndroidManifest.xml
ภายในแท็ก application
ด้านบน OPTIONS_PROVIDER_CLASS_NAME
<application>
...
<activity
android:name="com.google.sample.cast.refplayer.expandedcontrols.ExpandedControlsActivity"
android:label="@string/app_name"
android:launchMode="singleTask"
android:theme="@style/Theme.CastVideosDark"
android:screenOrientation="portrait"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.google.sample.cast.refplayer.VideoBrowserActivity"/>
</activity>
...
</application>
แก้ไข CastOptionsProvider
และเปลี่ยน NotificationOptions
และ CastMediaOptions
เพื่อตั้งค่ากิจกรรมเป้าหมายเป็น ExpandedControlsActivity
ดังนี้
import com.google.sample.cast.refplayer.expandedcontrols.ExpandedControlsActivity
override fun getCastOptions(context: Context): CastOptions {
val notificationOptions = NotificationOptions.Builder()
.setTargetActivityClassName(ExpandedControlsActivity::class.java.name)
.build()
val mediaOptions = CastMediaOptions.Builder()
.setNotificationOptions(notificationOptions)
.setExpandedControllerActivityClassName(ExpandedControlsActivity::class.java.name)
.build()
return CastOptions.Builder()
.setReceiverApplicationId(context.getString(R.string.app_id))
.setCastMediaOptions(mediaOptions)
.build()
}
อัปเดตเมธอด LocalPlayerActivity
loadRemoteMedia
เพื่อแสดง ExpandedControlsActivity
เมื่อโหลดสื่อระยะไกล
import com.google.sample.cast.refplayer.expandedcontrols.ExpandedControlsActivity
private fun loadRemoteMedia(position: Int, autoPlay: Boolean) {
if (mCastSession == null) {
return
}
val remoteMediaClient = mCastSession!!.remoteMediaClient ?: return
remoteMediaClient.registerCallback(object : RemoteMediaClient.Callback() {
override fun onStatusUpdated() {
val intent = Intent(this@LocalPlayerActivity, ExpandedControlsActivity::class.java)
startActivity(intent)
remoteMediaClient.unregisterCallback(this)
}
})
remoteMediaClient.load(MediaLoadRequestData.Builder()
.setMediaInfo(buildMediaInfo())
.setAutoplay(autoPlay)
.setCurrentTime(position.toLong()).build())
}
คลิกปุ่มเรียกใช้เพื่อเรียกใช้แอปบนอุปกรณ์เคลื่อนที่และแคสต์วิดีโอ คุณควรเห็นตัวควบคุมที่ขยายแล้ว กลับไปที่รายการวิดีโอ เมื่อคุณคลิกตัวควบคุมขนาดเล็ก ตัวควบคุมแบบขยายจะถูกโหลดอีกครั้ง ออกจากแอปเพื่อดูการแจ้งเตือน คลิกรูปภาพการแจ้งเตือนเพื่อโหลดตัวควบคุมที่ขยาย
11. เพิ่มการรองรับ Cast Connect
ไลบรารี Cast Connect ช่วยให้แอปพลิเคชันผู้ส่งที่มีอยู่สามารถสื่อสารกับแอปพลิเคชัน Android TV ผ่านโปรโตคอล Cast Cast Connect สร้างขึ้นบนโครงสร้างพื้นฐาน Cast โดยแอป Android TV จะทําหน้าที่เป็นตัวรับ
การอ้างอิง
หมายเหตุ: สําหรับการใช้ Cast Connect play-services-cast-framework
ต้องมี 19.0.0
ขึ้นไป
ตัวเลือกการเปิดตัว
ในการเปิดใช้แอปพลิเคชัน Android TV หรือเรียกอีกอย่างว่าตัวรับ Android เราจําเป็นต้องตั้งค่าแฟล็ก setAndroidReceiverCompatible
เป็น "จริง" ในออบเจ็กต์ LaunchOptions
ออบเจ็กต์ LaunchOptions
นี้จะกําหนดวิธีเปิดใช้ผู้รับและส่งต่อไปยัง CastOptions
ที่คลาส CastOptionsProvider
แสดงผล การตั้งค่าแฟล็กที่กล่าวถึงข้างต้นเป็น false
จะเปิดตัวรับเว็บสําหรับรหัสแอปที่กําหนดไว้ใน Play Developer Console
ในไฟล์ CastOptionsProvider.kt
ให้เพิ่มค่าต่อไปนี้ลงในเมธอด getCastOptions
import com.google.android.gms.cast.LaunchOptions
...
val launchOptions = LaunchOptions.Builder()
.setAndroidReceiverCompatible(true)
.build()
return new CastOptions.Builder()
.setLaunchOptions(launchOptions)
...
.build()
ตั้งค่าข้อมูลเข้าสู่ระบบที่ใช้
ทางฝั่งผู้ส่ง คุณสามารถระบุ CredentialsData
เพื่อแสดงว่าใครเข้าร่วมเซสชันบ้าง credentials
เป็นสตริงที่ผู้ใช้กําหนดได้ ตราบใดที่แอป ATV เข้าใจได้ CredentialsData
จะส่งไปยังแอป Android TV ระหว่างเวลาเปิดตัวหรือเข้าร่วมเท่านั้น หากตั้งค่าไว้อีกครั้งขณะที่เชื่อมต่ออยู่ ระบบจะไม่ส่งรหัสดังกล่าวไปยังแอป Android TV
หากต้องการตั้งค่าข้อมูลเข้าสู่ระบบการเปิดตัว CredentialsData
จะต้องกําหนดและส่งไปยังออบเจ็กต์ LaunchOptions
เพิ่มโค้ดต่อไปนี้ลงในเมธอด getCastOptions
ในไฟล์ CastOptionsProvider.kt
import com.google.android.gms.cast.CredentialsData
...
val credentialsData = CredentialsData.Builder()
.setCredentials("{\"userId\": \"abc\"}")
.build()
val launchOptions = LaunchOptions.Builder()
...
.setCredentialsData(credentialsData)
.build()
ระบุข้อมูลเข้าสู่ระบบใน LoadRequest
ในกรณีที่แอป Web Receiver และแอป Android TV จัดการ credentials
แตกต่างกัน คุณอาจต้องกําหนด credentials
แยกกันสําหรับแต่ละแอป หากต้องการดําเนินการดังกล่าว ให้เพิ่มโค้ดต่อไปนี้ในไฟล์ LocalPlayerActivity.kt
ในฟังก์ชัน loadRemoteMedia
remoteMediaClient.load(MediaLoadRequestData.Builder()
...
.setCredentials("user-credentials")
.setAtvCredentials("atv-user-credentials")
.build())
โดย SDK จะจัดการข้อมูลเข้าสู่ระบบที่จะใช้สําหรับเซสชันปัจจุบันโดยอัตโนมัติ ทั้งนี้ขึ้นอยู่กับแอปของผู้รับที่แคสต์ไป
กําลังทดสอบ Cast Connect
ขั้นตอนการติดตั้ง APK ของ Android TV ใน Chromecast ที่มี Google TV
- ค้นหาที่อยู่ IP ของอุปกรณ์ Android TV โดยปกติแล้วจะพร้อมใช้งานในส่วนการตั้งค่า > เครือข่ายและอินเทอร์เน็ต > (ชื่อเครือข่ายที่อุปกรณ์เชื่อมต่อ) ซึ่งจะแสดงรายละเอียดและ IP ของอุปกรณ์ในเครือข่ายทางด้านขวา
- ใช้ที่อยู่ IP ของอุปกรณ์เพื่อเชื่อมต่อผ่าน ADB โดยใช้เครื่องชําระเงิน
$ adb connect <device_ip_address>:5555
- จากหน้าต่างเทอร์มินัล ให้ไปที่โฟลเดอร์ระดับบนสุดสําหรับตัวอย่าง Codelab ที่คุณดาวน์โหลดในตอนต้นของ Codelab เช่น
$ cd Desktop/android_codelab_src
- ติดตั้งไฟล์ .apk ในโฟลเดอร์นี้ไปยัง Android TV โดยเรียกใช้:
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
- ตอนนี้คุณควรจะเห็นแอปตามชื่อแคสต์วิดีโอในเมนูแอปของคุณในอุปกรณ์ Android TV
- กลับไปที่โปรเจ็กต์ Android Studio แล้วคลิกปุ่ม "เรียกใช้" เพื่อติดตั้งและเรียกใช้แอปของผู้ส่งบนอุปกรณ์เคลื่อนที่จริง ที่มุมขวาบน ให้คลิกไอคอน "แคสต์" แล้วเลือกอุปกรณ์ Android TV จากตัวเลือกที่พร้อมใช้งาน ตอนนี้คุณควรเปิดแอป Android TV ในอุปกรณ์ Android TV และเล่นวิดีโอได้แล้ว ซึ่งจะช่วยให้คุณควบคุมการเล่นวิดีโอด้วยรีโมต Android TV ได้
12. ปรับแต่งวิดเจ็ตแคสต์
คุณปรับแต่งวิดเจ็ตแคสต์ได้โดยการตั้งค่าสี จัดรูปแบบปุ่ม ข้อความ และลักษณะที่ปรากฏของภาพขนาดย่อ และเลือกประเภทปุ่มที่จะแสดง
อัปเดต res/values/styles_castvideo.xml
<style name="Theme.CastVideosTheme" parent="Theme.AppCompat.Light.NoActionBar">
...
<item name="mediaRouteTheme">@style/CustomMediaRouterTheme</item>
<item name="castIntroOverlayStyle">@style/CustomCastIntroOverlay</item>
<item name="castMiniControllerStyle">@style/CustomCastMiniController</item>
<item name="castExpandedControllerStyle">@style/CustomCastExpandedController</item>
<item name="castExpandedControllerToolbarStyle">
@style/ThemeOverlay.AppCompat.ActionBar
</item>
...
</style>
ประกาศธีมที่กําหนดเองต่อไปนี้
<!-- Customize Cast Button -->
<style name="CustomMediaRouterTheme" parent="Theme.MediaRouter">
<item name="mediaRouteButtonStyle">@style/CustomMediaRouteButtonStyle</item>
</style>
<style name="CustomMediaRouteButtonStyle" parent="Widget.MediaRouter.Light.MediaRouteButton">
<item name="mediaRouteButtonTint">#EEFF41</item>
</style>
<!-- Customize Introductory Overlay -->
<style name="CustomCastIntroOverlay" parent="CastIntroOverlay">
<item name="castButtonTextAppearance">@style/TextAppearance.CustomCastIntroOverlay.Button</item>
<item name="castTitleTextAppearance">@style/TextAppearance.CustomCastIntroOverlay.Title</item>
</style>
<style name="TextAppearance.CustomCastIntroOverlay.Button" parent="android:style/TextAppearance">
<item name="android:textColor">#FFFFFF</item>
</style>
<style name="TextAppearance.CustomCastIntroOverlay.Title" parent="android:style/TextAppearance.Large">
<item name="android:textColor">#FFFFFF</item>
</style>
<!-- Customize Mini Controller -->
<style name="CustomCastMiniController" parent="CastMiniController">
<item name="castShowImageThumbnail">true</item>
<item name="castTitleTextAppearance">@style/TextAppearance.AppCompat.Subhead</item>
<item name="castSubtitleTextAppearance">@style/TextAppearance.AppCompat.Caption</item>
<item name="castBackground">@color/accent</item>
<item name="castProgressBarColor">@color/orange</item>
</style>
<!-- Customize Expanded Controller -->
<style name="CustomCastExpandedController" parent="CastExpandedController">
<item name="castButtonColor">#FFFFFF</item>
<item name="castPlayButtonDrawable">@drawable/cast_ic_expanded_controller_play</item>
<item name="castPauseButtonDrawable">@drawable/cast_ic_expanded_controller_pause</item>
<item name="castStopButtonDrawable">@drawable/cast_ic_expanded_controller_stop</item>
</style>
13. ขอแสดงความยินดี
ตอนนี้คุณดูวิธีแคสต์แอปวิดีโอโดยใช้วิดเจ็ต Cast SDK บน Android แล้ว
โปรดดูรายละเอียดเพิ่มเติมในคู่มือนักพัฒนาแอป Android Sender