1. บทนำ
อัปเดตล่าสุด: 2020-09-09
การเพิ่ม MediaSession รอบการเล่นวิดีโอมีประโยชน์อย่างไร
เซสชันสื่อเป็นลิงก์สำคัญระหว่างแพลตฟอร์ม Android กับแอปสื่อ ซึ่งไม่เพียงแต่แจ้งให้ Android ทราบว่ากำลังเล่นสื่ออยู่เพื่อให้สามารถส่งต่อการดำเนินการกับสื่อไปยังเซสชันที่ถูกต้องได้ แต่ยังแจ้งให้แพลตฟอร์มทราบว่ากำลังเล่นอะไรอยู่และจะควบคุมได้อย่างไรด้วย
การเปิดเผย MediaSession ผ่านแอปของคุณมีประโยชน์ต่างๆ ที่ผู้ใช้จะได้รับ ลองดูตัวอย่างที่ยอดเยี่ยมต่อไปนี้
Google Assistant
ผู้ใช้สามารถโต้ตอบกับสื่อในแอปของคุณได้อย่างง่ายดายผ่านคำสั่งเสียง เช่น "หยุดชั่วคราว" "เล่นต่อ" และ "ถัดไป" นอกจากนี้ยังใช้ข้อมูลเมตาจากสื่อเพื่อรับคำตอบเกี่ยวกับสิ่งที่กำลังเล่นได้ด้วย
Android TV
ในประสบการณ์การใช้งานบนหน้าจอขนาดใหญ่ แอป Android TV สามารถใช้รีโมตคอนโทรลทั่วไปสำหรับผู้ใช้ที่มีทีวีที่รองรับ HDMI-CEC ได้ ระบบจะส่งต่อคำสั่งที่ออกโดยปุ่มเล่น/หยุดชั่วคราว หยุด ถัดไป และก่อนหน้าไปยังแอปของคุณ
ตัวควบคุมสื่อบนหน้าจอ
ตั้งแต่ Android 4.0 (ระดับ API 14) เป็นต้นไป ระบบจะเข้าถึงสถานะการเล่นและข้อมูลเมตาของเซสชันสื่อได้ ฟังก์ชันนี้ช่วยให้หน้าจอล็อกแสดงตัวควบคุมสื่อและอาร์ตเวิร์กได้ ลักษณะการทำงานนี้จะแตกต่างกันไปตามเวอร์ชันของ Android
สื่อพื้นหลัง
คุณควบคุมสื่อได้ในทุกสถานการณ์ต่อไปนี้ แม้ว่าแอปที่เล่นสื่อจะทำงานในเบื้องหลังอยู่ก็ตาม
Ambient Computing
การเปิดเผยสื่อด้วยข้อมูลเกี่ยวกับสิ่งที่กำลังเล่นและวิธีควบคุมจะช่วยเชื่อมต่ออุปกรณ์ต่างๆ เพื่อให้ผู้ใช้โต้ตอบกับสื่อได้หลายวิธีตามที่ต้องการ
สิ่งที่คุณจะสร้าง
ใน Codelab นี้ คุณจะได้ขยายตัวอย่าง ExoPlayer ที่มีอยู่เพื่อเพิ่มการรองรับเซสชันสื่อ แอปของคุณจะทำสิ่งต่อไปนี้
- แสดงสถานะที่ใช้งานอยู่ของเซสชันสื่ออย่างถูกต้อง
- ส่งต่อตัวควบคุมสื่อไปยัง ExoPlayer
- ส่งข้อมูลเมตาของรายการในคิวไปยังเซสชันสื่อ
สิ่งที่คุณจะได้เรียนรู้
- เหตุใดเซสชันสื่อจึงมอบประสบการณ์ที่สมบูรณ์ยิ่งขึ้นแก่ผู้ใช้
- วิธีสร้างเซสชันสื่อและจัดการสถานะ
- วิธีเชื่อมต่อเซสชันสื่อกับ ExoPlayer
- วิธีรวมข้อมูลเมตาของรายการในคิวการเล่นไว้ในเซสชันสื่อ
- วิธีเพิ่มการดำเนินการเพิ่มเติม (ที่กำหนดเอง)
Codelab นี้มุ่งเน้นที่ MediaSession SDK เราจะไม่กล่าวถึงแนวคิดและบล็อกโค้ดที่ไม่เกี่ยวข้อง รวมถึงรายละเอียดเกี่ยวกับการใช้งาน ExoPlayer แต่จะให้คุณคัดลอกและวางได้เลย
สิ่งที่คุณต้องมี
- Android Studio เวอร์ชันล่าสุด (3.5 ขึ้นไป)
- มีความรู้พื้นฐานเกี่ยวกับการพัฒนาแอปพลิเคชัน Android
2. การเริ่มตั้งค่า
จุดเริ่มต้นของเราคืออะไร
จุดเริ่มต้นของเราคือการสาธิตหลักจาก ExoPlayer การสาธิตนี้มีวิดีโอที่มีตัวควบคุมการเล่นบนหน้าจอ แต่ไม่ได้ใช้เซสชันสื่อตั้งแต่ต้น ซึ่งเป็นที่ที่เหมาะสำหรับเราในการเจาะลึกและเพิ่มข้อมูลดังกล่าว
รับตัวอย่าง ExoPlayer
มาเริ่มด้วยตัวอย่าง ExoPlayer เพื่อให้การเริ่มต้นเป็นไปอย่างราบรื่น โคลนที่เก็บ GitHub โดยเรียกใช้โค้ดด้านล่าง
git clone https://github.com/google/ExoPlayer.git
เปิดเดโม
ใน Android Studio ให้เปิดโปรเจ็กต์สาธิตหลักที่อยู่ใน demos/main
Android Studio จะแจ้งให้คุณตั้งค่าเส้นทาง SDK คุณอาจต้องทำตามคำแนะนำสำหรับการอัปเดต IDE และเครื่องมือ SDK หากพบปัญหา

หากระบบขอให้คุณใช้ Gradle เวอร์ชันล่าสุด ให้อัปเดต
โปรดสละเวลาสักครู่เพื่อทำความเข้าใจพื้นฐานเกี่ยวกับวิธีออกแบบแอป โปรดทราบว่ามีกิจกรรม 2 อย่าง ได้แก่ SampleChooserActivity และ PlayerActivity เราจะใช้เวลาที่เหลือของ Codelab ใน PlayerActivity ซึ่งเป็นที่ที่สื่อเล่นจริง ดังนั้นให้เปิดคลาสนี้แล้วไปที่ส่วนถัดไป
3. สร้างเซสชันสื่อและจัดการสถานะของเซสชัน
สร้างเซสชันสื่อ
เปิด PlayerActivity.java คลาสนี้สร้าง ExoPlayer และจัดการฟังก์ชันต่างๆ เช่น การแสดงวิดีโอบนหน้าจอ ในกิจกรรมนี้ เราจะเชื่อมต่อ ExoPlayer กับเซสชันสื่อ
ประกาศฟิลด์ 2 รายการต่อไปนี้ที่ด้านบนของคลาส เราจะใช้ช่องเหล่านี้ตลอดทั้งส่วนนี้
private MediaSessionCompat mediaSession;
private MediaSessionConnector mediaSessionConnector;
คุณจะต้องเพิ่มทรัพยากร Dependency ของโปรเจ็กต์ "extension-mediasession" ลงใน build.gradle ระดับโมดูลสำหรับ "Module: demo" ดังนี้
implementation project(path: ':extension-mediasession')
โปรดทราบว่า Android Studio ช่วยคุณเพิ่มทรัพยากร Dependency นี้ได้โดยอัตโนมัติหากคุณวางเมาส์เหนือข้อผิดพลาดในการแก้ไข MediaSessionConnector

สุดท้าย ให้แก้ไขการนำเข้าชั้นเรียนโดยเพิ่มข้อมูลต่อไปนี้
import android.support.v4.media.session.MediaSessionCompat;
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
เมื่อสร้างกิจกรรมแล้ว เราจะต้องสร้างเซสชันสื่อและตัวเชื่อมต่อเซสชันสื่อซึ่งทำหน้าที่เป็นตัวกลางระหว่างเซสชันสื่อกับ ExoPlayer
ตำแหน่งที่เหมาะสำหรับการแทรกคือตำแหน่งที่สร้าง ExoPlayer ในแอปเดโม เราสามารถต่อท้ายโค้ดไว้ที่ส่วนท้ายของ initializePlayer() อย่าลืมเพิ่มตรรกะนี้หลังจากสร้างอินสแตนซ์ของผู้เล่นแล้ว
private void initializePlayer() {
if (player == null) {
...
player = ...
...
mediaSession = new MediaSessionCompat(this, "sample");
mediaSessionConnector = new MediaSessionConnector(mediaSession);
mediaSessionConnector.setPlayer(player);
}
...
}
ปล่อยเซสชันสื่อ
ปล่อยเซสชันสื่อเมื่อไม่จำเป็นต้องใช้แล้ว เมื่อเปิดตัว ExoPlayer ใน releasePlayer() เราจะใส่โค้ดต่อไปนี้เพื่อดำเนินการดังกล่าวได้ด้วย
private void releasePlayer() {
if (mediaSession != null) {
mediaSession.release();
}
...
}
จัดการสถานะเซสชันสื่อ
ตอนนี้เราได้สร้างอินสแตนซ์ของเซสชันสื่อแล้ว เราจึงต้องตรวจสอบว่าสถานะของเซสชันสื่อแสดงอย่างถูกต้องเมื่อผู้ใช้โต้ตอบกับกิจกรรม
เมื่อผู้ใช้เริ่มกิจกรรม เซสชันสื่อควรจะใช้งานได้ ดังนี้
@Override
public void onStart() {
...
if (mediaSession != null) {
mediaSession.setActive(true);
}
}
เนื่องจากแอปพลิเคชันของเราไม่ได้เล่นสื่อในเบื้องหลัง คุณจึงต้องตรวจสอบว่าเซสชันสื่อจะไม่มีการใช้งานเมื่อผู้ใช้ออกจากกิจกรรม
@Override
public void onStop() {
super.onStop();
if (mediaSession != null) {
mediaSession.setActive(false);
}
...
}
มาลองใช้เดโมกัน
- แนบอุปกรณ์ Android หรือเริ่มโปรแกรมจำลอง
- ตรวจสอบว่าได้เลือก "demo" เพื่อเรียกใช้จากแถบเครื่องมือ Android Studio แล้ว

- คลิก
จากแถบเครื่องมือ Android Studio - เมื่อแอปเปิดขึ้นในอุปกรณ์แล้ว ให้เลือกสตรีมวิดีโอที่จะเล่น
- เมื่อการเล่นเริ่มขึ้น ให้ลองใช้
adbคำสั่งต่อไปนี้เพื่อควบคุมเซสชันสื่อ
adb shell media dispatch pause
adb shell media dispatch play
adb shell media dispatch play-pause
adb shell media dispatch fast-forward
adb shell media dispatch rewind
- นอกจากนี้ ให้ดูว่า Android มองเห็นเซสชันสื่อของคุณอย่างไร โดยเฉพาะอย่างยิ่ง คุณสามารถตรวจสอบได้ว่าระบบรองรับการดำเนินการใดบ้างโดยดูที่ช่องการดำเนินการ หมายเลขที่คุณเห็นที่นี่คือการรวมรหัสการดำเนินการตามที่ประกาศไว้ในออบเจ็กต์ PlaybackState วิธีดูเซสชันสื่อที่กำลังทำงานมีดังนี้
adb shell dumpsys media_session - หากใช้อุปกรณ์จริงที่มีไมโครโฟน ให้ลองเรียกใช้ Google Assistant และออกคำสั่งเสียง เช่น "หยุดชั่วคราว" "เล่นต่อ" "กรอไปข้างหน้า 1 นาที"
ตัวอย่าง ExoPlayer ที่ทำงานบน Android TV
4. รวมข้อมูลเมตาของรายการในคิวการเล่น
ตอนนี้เราสามารถขยายฟีเจอร์ที่รองรับของเซสชันสื่อได้แล้ว ซึ่งก่อนหน้านี้เราได้สร้าง MediaSessionConnector ไว้ใน initializePlayer()
การเพิ่ม TimelineQueueNavigator
ExoPlayer แสดงโครงสร้างของสื่อเป็นไทม์ไลน์ หากต้องการทราบรายละเอียดเกี่ยวกับวิธีการทำงานนี้ โปรดอ่านข้อมูลเกี่ยวกับออบเจ็กต์ไทม์ไลน์ของ ExoPlayer การใช้โครงสร้างนี้จะช่วยให้เราทราบเมื่อเนื้อหามีการเปลี่ยนแปลงและแสดงข้อมูลเมตาของสิ่งที่กำลังเล่นอยู่เมื่อมีการขอ
เราจะกำหนด TimelineQueueNavigator เพื่อให้บรรลุเป้าหมายนี้ ค้นหาการเริ่มต้นของ MediaSessionConnector ใน initializePlayer() และเพิ่มการติดตั้งใช้งาน TimelineQueueNavigator หลังจาก mediaSession เริ่มต้น
mediaSessionConnector.setQueueNavigator(new TimelineQueueNavigator(mediaSession) {
@Override
public MediaDescriptionCompat getMediaDescription(Player player, int windowIndex) {
return new MediaDescriptionCompat.Builder()
.setTitle(player.getCurrentMediaItem().mediaMetadata.title)
.setDescription("MediaDescription description for " + windowIndex)
.setSubtitle("MediaDescription subtitle")
.build();
}
});
แก้ไขการนำเข้าชั้นเรียนโดยเพิ่มข้อมูลต่อไปนี้
import android.support.v4.media.MediaDescriptionCompat;
import com.google.android.exoplayer2.ext.mediasession.TimelineQueueNavigator;
โปรดสังเกตว่าพารามิเตอร์ windowIndex สอดคล้องกับรายการของดัชนีนั้นในคิวการเล่น
เมื่อเพิ่มข้อมูลเมตาแล้ว คุณจะทดสอบได้ว่า Assistant เข้าใจสิ่งที่กำลังเล่นอยู่หรือไม่ ขณะเล่นวิดีโอบน Android TV ให้เรียกใช้ Assistant แล้วถามว่า "เปิดอะไรอยู่"

5. การปรับแต่งการดำเนินการ
บางทีเครื่องเล่นอาจไม่รองรับการดำเนินการบางอย่าง หรือคุณอาจต้องการรวมการรองรับเพิ่มเติม ตอนนี้เรามาเจาะลึกเซสชันสื่อที่เราสร้าง MediaSessionConnector ไว้ก่อนหน้านี้ใน initializePlayer() กัน
การประกาศการดำเนินการที่รองรับ
ลองใช้ mediaSessionConnector.setEnabledPlaybackActions() เพื่อปรับแต่งการดำเนินการที่ต้องการให้เซสชันสื่อรองรับ
โปรดทราบว่าชุดข้อมูลที่สมบูรณ์คือ
mediaSessionConnector.setEnabledPlaybackActions(
PlaybackStateCompat.ACTION_PLAY_PAUSE
| PlaybackStateCompat.ACTION_PLAY
| PlaybackStateCompat.ACTION_PAUSE
| PlaybackStateCompat.ACTION_SEEK_TO
| PlaybackStateCompat.ACTION_FAST_FORWARD
| PlaybackStateCompat.ACTION_REWIND
| PlaybackStateCompat.ACTION_STOP
| PlaybackStateCompat.ACTION_SET_REPEAT_MODE
| PlaybackStateCompat.ACTION_SET_SHUFFLE_MODE
);
มาดูกันอีกครั้งว่าแพลตฟอร์มจะแสดงข้อมูลนี้อย่างไร
- เริ่มวิดีโอเหมือนเดิม
- ดูวิธีที่ Android เห็นข้อมูลเมตาจากเซสชันสื่อโดยการเรียกใช้
adb shell dumpsys media_session - ค้นหาบรรทัดที่มีข้อมูลเมตาและสังเกตว่ามีชื่อและคำอธิบายรวมอยู่และเชื่อมโยงกับ
com.google.android.exoplayer2.demo/sample
การเพิ่มการดำเนินการเพิ่มเติม
เราสามารถขยายเซสชันสื่อด้วยการดำเนินการเพิ่มเติมบางอย่าง ในส่วนนี้ เราจะเพิ่มการรองรับเฉพาะคำบรรยายแทนเสียง
คำบรรยายแทนเสียงที่รองรับ
การเพิ่มการรองรับคำบรรยายแทนเสียงในเซสชันสื่อจะช่วยให้ผู้ใช้เปิด/ปิดคำบรรยายแทนเสียงได้ด้วยเสียง เพิ่มข้อมูลต่อไปนี้ในตำแหน่งที่คุณเริ่มต้นตัวเชื่อมต่อเซสชันสื่อ
mediaSessionConnector.setCaptionCallback(new MediaSessionConnector.CaptionCallback() {
@Override
public void onSetCaptioningEnabled(Player player, boolean enabled) {
Log.d("MediaSession", "onSetCaptioningEnabled: enabled=" + enabled);
}
@Override
public boolean hasCaptions(Player player) {
return true;
}
@Override
public boolean onCommand(Player player, ControlDispatcher controlDispatcher, String command, Bundle extras, ResultReceiver cb) {
return false;
}
}
);
สุดท้าย ให้แก้ไขการนำเข้าที่ขาดหายไป
คุณทดสอบได้โดยเรียกใช้ Google Assistant ใน Android TV แล้วพูดว่า "เปิดใช้คำบรรยายแทนเสียง" ตรวจสอบ Logcat เพื่อดูข้อความว่าการเรียกใช้โค้ดของคุณเป็นอย่างไร
6. ขอแสดงความยินดี
ขอแสดงความยินดี คุณเพิ่มเซสชันสื่อลงในตัวอย่างเรียบร้อยแล้ว
คุณได้รับฟังก์ชันการทำงานมากมายโดยการทำสิ่งต่อไปนี้
- การเพิ่มเซสชันสื่อ
- การเชื่อมต่อเซสชันสื่อกับอินสแตนซ์ของ ExoPlayer
- การเพิ่มข้อมูลเมตาและการดำเนินการเพิ่มเติม
ตอนนี้คุณทราบขั้นตอนสำคัญที่จำเป็นในการเพิ่มคุณค่าให้กับแอปสื่อและมอบประสบการณ์การใช้งานที่หลากหลายยิ่งขึ้นแก่ผู้ใช้แล้ว
หมายเหตุ สุดท้าย
Codelab นี้สร้างขึ้นจากตัวอย่างในซอร์สโค้ด ExoPlayer คุณไม่จำเป็นต้องใช้ ExoPlayer จากแหล่งที่มา และเราขอแนะนำให้ดึงข้อมูลการอ้างอิงสำหรับ ExoPlayer และ MediaSessionConnector แทน เพื่อให้คุณอัปเดตข้อมูลล่าสุดได้ง่ายขึ้น
โดยแทนที่การอ้างอิงโปรเจ็กต์ เช่น
implementation project(modulePrefix + 'library-core')
implementation project(path: ':extension-mediasession')
เพื่อดึงข้อมูลจากที่เก็บ Maven เช่น
implementation 'com.google.android.exoplayer:exoplayer-core:2.+'
implementation 'com.google.android.exoplayer:extension-mediasession:2.+'