ทำงานร่วมกับ MediaPlayer และการจัดการสิทธิ์ดิจิทัล (DRM)
จัดทุกอย่างให้เป็นระเบียบอยู่เสมอด้วยคอลเล็กชัน
บันทึกและจัดหมวดหมู่เนื้อหาตามค่ากำหนดของคุณ
ตั้งแต่ Android 8.0 (API ระดับ 26) เป็นต้นไป MediaPlayer
จะมี API ที่รองรับการเล่นเนื้อหาที่มีการป้องกัน DRM MediaPlayer DRM API จะคล้ายกับ API ระดับล่างที่ MediaDrm
ให้บริการ แต่ทำงานในระดับที่สูงขึ้นและไม่แสดงเครื่องมือแยก DRM และออบเจ็กต์การเข้ารหัสที่อยู่เบื้องหลัง
แม้ว่า MediaPlayer DRM API จะไม่มีฟังก์ชันการทำงานทั้งหมดของ MediaDrm
แต่รองรับ Use Case ที่พบบ่อยที่สุด การใช้งานปัจจุบันสามารถจัดการเนื้อหาประเภทต่อไปนี้
- ไฟล์สื่อในเครื่องที่ได้รับการป้องกันโดย Widevine
- ไฟล์สื่อแบบสตรีมมิงหรือแบบระยะไกลที่ได้รับการป้องกันโดย Widevine
ข้อมูลโค้ดต่อไปนี้แสดงวิธีใช้MediaPlayer
วิธี DRM ใหม่ในการใช้งานแบบซิงค์
หากต้องการจัดการสื่อที่ควบคุมด้วย DRM คุณต้องใส่เมธอดใหม่ไว้ควบคู่ไปกับขั้นตอนการเรียกใช้ MediaPlayer ตามปกติ ดังที่แสดงในตัวอย่างนี้
Kotlin
mediaPlayer?.apply {
setDataSource()
setOnDrmConfigHelper() // optional, for custom configuration
prepare()
drmInfo?.also {
prepareDrm()
getKeyRequest()
provideKeyResponse()
}
// MediaPlayer is now ready to use
start()
// ...play/pause/resume...
stop()
releaseDrm()
}
Java
setDataSource();
setOnDrmConfigHelper(); // optional, for custom configuration
prepare();
if (getDrmInfo() != null) {
prepareDrm();
getKeyRequest();
provideKeyResponse();
}
// MediaPlayer is now ready to use
start();
// ...play/pause/resume...
stop();
releaseDrm();
เริ่มต้นด้วยการกำหนดค่าออบเจ็กต์ MediaPlayer
และตั้งค่าแหล่งที่มาโดยใช้ setDataSource()
ตามปกติ จากนั้นทำตามขั้นตอนต่อไปนี้เพื่อใช้ DRM
- หากต้องการให้แอปทำการกําหนดค่าเอง ให้กําหนดอินเทอร์เฟซ
OnDrmConfigHelper
แล้วแนบกับเพลเยอร์โดยใช้ setOnDrmConfigHelper()
- โทรหา
prepare()
- โทรหา
getDrmInfo()
หากแหล่งที่มามีเนื้อหา DRM เมธอดจะแสดงผลค่า MediaPlayer.DrmInfo
ที่ไม่ใช่ค่าว่าง
หากมี MediaPlayer.DrmInfo
อยู่แล้ว ให้ทำดังนี้
- ตรวจสอบแผนที่ UUID ที่พร้อมใช้งานและเลือกรายการใดรายการหนึ่ง
- เตรียมการกำหนดค่า DRM สำหรับแหล่งที่มาปัจจุบันโดยเรียกใช้
prepareDrm()
- หากคุณสร้างและลงทะเบียนการเรียกกลับ
OnDrmConfigHelper
ระบบจะเรียกใช้ขณะที่ prepareDrm()
ดําเนินการ ซึ่งจะช่วยให้คุณกำหนดค่าพร็อพเพอร์ตี้ DRM ที่กำหนดเองได้ก่อนที่จะเปิดเซสชัน DRM ระบบจะเรียกใช้การติดต่อกลับแบบซิงค์ในเธรดที่เรียกใช้ prepareDrm()
หากต้องการเข้าถึงพร็อพเพอร์ตี้ DRM ให้เรียกใช้ getDrmPropertyString()
และ setDrmPropertyString()
หลีกเลี่ยงการดำเนินการที่ใช้เวลานาน
- หากยังไม่ได้จัดสรรอุปกรณ์
prepareDrm()
จะเข้าถึงเซิร์ฟเวอร์การจัดสรรเพื่อจัดสรรอุปกรณ์ด้วย การดำเนินการนี้อาจใช้เวลานานสั้นแตกต่างกันไป ทั้งนี้ขึ้นอยู่กับการเชื่อมต่อเครือข่าย
- หากต้องการรับอาร์เรย์ไบต์คำขอคีย์แบบทึบเพื่อส่งไปยังเซิร์ฟเวอร์ใบอนุญาต ให้เรียกใช้
getKeyRequest()
- หากต้องการแจ้งให้เครื่องมือ DRM ทราบเกี่ยวกับการตอบกลับคีย์ที่ได้รับจากเซิร์ฟเวอร์ใบอนุญาต ให้เรียกใช้
provideKeyResponse()
ผลลัพธ์จะขึ้นอยู่กับประเภทของคำขอคีย์ ดังนี้
- หากการตอบกลับเป็นคำขอคีย์แบบออฟไลน์ ผลลัพธ์ที่ได้จะเป็นตัวระบุชุดคีย์ คุณสามารถใช้ตัวระบุชุดคีย์นี้กับ
restoreKeys()
เพื่อกู้คืนคีย์ไปยังเซสชันใหม่ได้
- หากการตอบกลับเป็นการตอบกลับคำขอสตรีมหรือคำขอเผยแพร่ ผลลัพธ์จะเป็นค่า null
เตรียม DRM แบบไม่พร้อมกัน
โดยค่าเริ่มต้น prepareDrm()
จะทํางานแบบซิงค์กัน โดยจะบล็อกจนกว่าการเตรียมจะเสร็จสมบูรณ์ อย่างไรก็ตาม การเตรียม DRM ครั้งแรกในอุปกรณ์ใหม่อาจต้องมีการจัดสรรด้วย ซึ่ง prepareDrm()
จะจัดการเป็นการภายใน และอาจใช้เวลาสักครู่จึงจะเสร็จสมบูรณ์เนื่องจากมีการดำเนินการเกี่ยวกับเครือข่ายที่เกี่ยวข้อง คุณหลีกเลี่ยงการบล็อกใน prepareDrm()
ได้โดยกำหนดและตั้งค่า MediaPlayer.OnDrmPreparedListener
ตั้งค่า OnDrmPreparedListener
prepareDrm()
จะดำเนินการจัดสรร (หากจำเป็น) และเตรียมความพร้อมในเบื้องหลัง เมื่อจัดสรรและเตรียมความพร้อมเสร็จแล้ว ระบบจะเรียกฟัง อย่าคาดเดาเกี่ยวกับลําดับการเรียกหรือเธรดที่ใช้เรียกใช้ Listener (เว้นแต่คุณจะลงทะเบียน Listener กับเธรดแฮนเดิล) ระบบสามารถเรียกใช้ Listener ก่อนหรือหลังจากที่ prepareDrm()
แสดงผล
ตั้งค่า DRM แบบไม่พร้อมกัน
คุณสามารถเริ่มต้น DRM แบบไม่พร้อมกันได้โดยการสร้างและลงทะเบียน MediaPlayer.OnDrmInfoListener
เพื่อเตรียม DRM และ MediaPlayer.OnDrmPreparedListener
เพื่อเริ่มโปรแกรมเล่น ซึ่งทำงานร่วมกับ prepareAsync()
ดังตัวอย่างต่อไปนี้
Kotlin
setOnPreparedListener()
setOnDrmInfoListener()
setDataSource()
prepareAsync()
// ...
// If the data source content is protected you receive a call to the onDrmInfo() callback.
override fun onDrmInfo(mediaPlayer: MediaPlayer, drmInfo: MediaPlayer.DrmInfo) {
mediaPlayer.apply {
prepareDrm()
getKeyRequest()
provideKeyResponse()
}
}
// When prepareAsync() finishes, you receive a call to the onPrepared() callback.
// If there is a DRM, onDrmInfo() sets it up before executing this callback,
// so you can start the player.
override fun onPrepared(mediaPlayer: MediaPlayer) {
mediaPlayer.start()
}
Java
setOnPreparedListener();
setOnDrmInfoListener();
setDataSource();
prepareAsync();
// ...
// If the data source content is protected you receive a call to the onDrmInfo() callback.
onDrmInfo() {
prepareDrm();
getKeyRequest();
provideKeyResponse();
}
// When prepareAsync() finishes, you receive a call to the onPrepared() callback.
// If there is a DRM, onDrmInfo() sets it up before executing this callback,
// so you can start the player.
onPrepared() {
start();
}
จัดการสื่อที่เข้ารหัส
ตั้งแต่ Android 8.0 (API ระดับ 26) เป็นต้นไป MediaPlayer
จะถอดรหัสรูปแบบการเข้ารหัสทั่วไป (CENC) และสื่อที่เข้ารหัสระดับตัวอย่างของ HLS (METHOD=SAMPLE-AES) สำหรับสตรีมพื้นฐานประเภท H.264 และ AAC ได้ด้วย ก่อนหน้านี้ระบบรองรับสื่อที่เข้ารหัสทั้งกลุ่ม (METHOD=AES-128)
ดูข้อมูลเพิ่มเติม
Jetpack Media3 เป็นโซลูชันที่แนะนำสำหรับการเล่นสื่อในแอป อ่านข้อมูลเพิ่มเติมเกี่ยวกับโซลูชันนี้
หน้าเหล่านี้ครอบคลุมหัวข้อเกี่ยวกับการบันทึก การจัดเก็บ และการเล่นเสียงและวิดีโอ
ตัวอย่างเนื้อหาและโค้ดในหน้าเว็บนี้ขึ้นอยู่กับใบอนุญาตที่อธิบายไว้ในใบอนุญาตการใช้เนื้อหา Java และ OpenJDK เป็นเครื่องหมายการค้าหรือเครื่องหมายการค้าจดทะเบียนของ Oracle และ/หรือบริษัทในเครือ
อัปเดตล่าสุด 2025-07-27 UTC
[[["เข้าใจง่าย","easyToUnderstand","thumb-up"],["แก้ปัญหาของฉันได้","solvedMyProblem","thumb-up"],["อื่นๆ","otherUp","thumb-up"]],[["ไม่มีข้อมูลที่ฉันต้องการ","missingTheInformationINeed","thumb-down"],["ซับซ้อนเกินไป/มีหลายขั้นตอนมากเกินไป","tooComplicatedTooManySteps","thumb-down"],["ล้าสมัย","outOfDate","thumb-down"],["ปัญหาเกี่ยวกับการแปล","translationIssue","thumb-down"],["ตัวอย่าง/ปัญหาเกี่ยวกับโค้ด","samplesCodeIssue","thumb-down"],["อื่นๆ","otherDown","thumb-down"]],["อัปเดตล่าสุด 2025-07-27 UTC"],[],[],null,["# Work with MediaPlayer and Digital Rights Management (DRM)\n\nStarting with Android 8.0 (API level 26), [`MediaPlayer`](/reference/android/media/MediaPlayer) includes APIs that\nsupport the playback of DRM-protected material. The MediaPlayer DRM APIs are\nsimilar to the low-level API provided by [`MediaDrm`](/reference/android/media/MediaDrm), but they operate at a\nhigher level and don't expose the underlying extractor, DRM, and crypto objects.\n\nAlthough the MediaPlayer DRM API does not provide the full functionality of\n[`MediaDrm`](/reference/android/media/MediaDrm), it supports the most common use cases. The current\nimplementation can handle the following content types:\n\n- Widevine-protected local media files\n- Widevine-protected remote or streaming media files\n\nThe following code snippet demonstrates how to use the new DRM `MediaPlayer`\nmethods in a synchronous implementation.\n\nTo manage DRM-controlled media, you need to include the new methods alongside\nthe usual flow of MediaPlayer calls, as shown in this example: \n\n### Kotlin\n\n mediaPlayer?.apply {\n setDataSource()\n setOnDrmConfigHelper() // optional, for custom configuration\n prepare()\n drmInfo?.also {\n prepareDrm()\n getKeyRequest()\n provideKeyResponse()\n }\n\n // MediaPlayer is now ready to use\n start()\n // ...play/pause/resume...\n stop()\n releaseDrm()\n }\n\n### Java\n\n setDataSource();\n setOnDrmConfigHelper(); // optional, for custom configuration\n prepare();\n if (getDrmInfo() != null) {\n prepareDrm();\n getKeyRequest();\n provideKeyResponse();\n }\n\n // MediaPlayer is now ready to use\n start();\n // ...play/pause/resume...\n stop();\n releaseDrm();\n\nStart by initializing the [`MediaPlayer`](/reference/android/media/MediaPlayer) object and setting its source using\n[`setDataSource()`](/reference/android/media/MediaPlayer#setDataSource(android.content.Context,%20android.net.Uri)), as usual. Then, to use DRM, perform these steps:\n\n1. If you want your app to perform custom configuration, define an [`OnDrmConfigHelper`](/reference/android/media/MediaPlayer.OnDrmConfigHelper) interface, and attach it to the player using [`setOnDrmConfigHelper()`](/reference/android/media/MediaPlayer#setOnDrmConfigHelper(android.media.MediaPlayer.OnDrmConfigHelper)).\n2. Call [`prepare()`](/reference/android/media/MediaPlayer#prepare()).\n3. Call [`getDrmInfo()`](/reference/android/media/MediaPlayer#getDrmInfo()). If the source has DRM content, the method returns a non-null [`MediaPlayer.DrmInfo`](/reference/android/media/MediaPlayer.DrmInfo) value.\n\nIf [`MediaPlayer.DrmInfo`](/reference/android/media/MediaPlayer.DrmInfo) exists:\n\n1. Examine the map of available UUIDs and choose one.\n2. Prepare the DRM configuration for the current source by calling [`prepareDrm()`](/reference/android/media/MediaPlayer#prepareDrm(java.util.UUID)).\n - If you created and registered an [`OnDrmConfigHelper`](/reference/android/media/MediaPlayer.OnDrmConfigHelper) callback, it is called while [`prepareDrm()`](/reference/android/media/MediaPlayer#prepareDrm(java.util.UUID)) is executing. This lets you perform custom configuration of the DRM properties before opening the DRM session. The callback is called synchronously in the thread that called [`prepareDrm()`](/reference/android/media/MediaPlayer#prepareDrm(java.util.UUID)). To access the DRM properties, call [`getDrmPropertyString()`](/reference/android/media/MediaPlayer#getDrmPropertyString(java.lang.String)) and [`setDrmPropertyString()`](/reference/android/media/MediaPlayer#setDrmPropertyString(java.lang.String,%20java.lang.String)). Avoid performing lengthy operations.\n - If the device has not yet been provisioned, [`prepareDrm()`](/reference/android/media/MediaPlayer#prepareDrm(java.util.UUID)) also accesses the provisioning server to provision the device. This can take a variable amount of time, depending on the network connectivity.\n3. To get an opaque key request byte array to send to a license server, call [`getKeyRequest()`](/reference/android/media/MediaPlayer#getKeyRequest(byte%5B%5D,%20byte%5B%5D,%20java.lang.String,%20int,%20java.util.Map%3Cjava.lang.String,%20java.lang.String%3E)).\n4. To inform the DRM engine about the key response received from the license server, call [`provideKeyResponse()`](/reference/android/media/MediaPlayer#provideKeyResponse(byte%5B%5D,%20byte%5B%5D)). The result depends on the type of key request:\n - If the response is for an offline key request, the result is a key-set identifier. You can use this key-set identifier with [`restoreKeys()`](/reference/android/media/MediaPlayer#restoreKeys(byte%5B%5D)) to restore the keys to a new session.\n - If the response is for a streaming or release request, the result is null.\n\nPrepare DRM asynchronously\n--------------------------\n\nBy default, [`prepareDrm()`](/reference/android/media/MediaPlayer#prepareDrm(java.util.UUID)) runs synchronously, blocking until preparation\nfinishes. However, the very first DRM preparation on a new device may also\nrequire provisioning, which [`prepareDrm()`](/reference/android/media/MediaPlayer#prepareDrm(java.util.UUID)) handles internally, and may take\nsome time to finish due to the network operation involved. You can avoid\nblocking on [`prepareDrm()`](/reference/android/media/MediaPlayer#prepareDrm(java.util.UUID)) by defining and setting a\n[`MediaPlayer.OnDrmPreparedListener`](/reference/android/media/MediaPlayer.OnDrmPreparedListener).\n\nSet an [`OnDrmPreparedListener`](/reference/android/media/MediaPlayer.OnDrmPreparedListener). [`prepareDrm()`](/reference/android/media/MediaPlayer#prepareDrm(java.util.UUID)) performs the\nprovisioning (if needed) and preparation in the background. When provisioning\nand preparation finish, the system calls the listener. Don't make any\nassumptions about the calling sequence or the thread in which the listener runs\n(unless you register the listener with a handler thread). The system can call\nthe listener before or after [`prepareDrm()`](/reference/android/media/MediaPlayer#prepareDrm(java.util.UUID)) returns.\n\nSet up DRM asynchronously\n-------------------------\n\nYou can initialize the DRM asynchronously by creating and registering the\n[`MediaPlayer.OnDrmInfoListener`](/reference/android/media/MediaPlayer.OnDrmInfoListener) for DRM preparation and the\n[`MediaPlayer.OnDrmPreparedListener`](/reference/android/media/MediaPlayer.OnDrmPreparedListener) to start the player. They work in\nconjunction with [`prepareAsync()`](/reference/android/media/MediaPlayer#prepareAsync()), as shown in this example: \n\n### Kotlin\n\n setOnPreparedListener()\n setOnDrmInfoListener()\n setDataSource()\n prepareAsync()\n // ...\n\n // If the data source content is protected you receive a call to the onDrmInfo() callback.\n override fun onDrmInfo(mediaPlayer: MediaPlayer, drmInfo: MediaPlayer.DrmInfo) {\n mediaPlayer.apply {\n prepareDrm()\n getKeyRequest()\n provideKeyResponse()\n }\n }\n\n // When prepareAsync() finishes, you receive a call to the onPrepared() callback.\n // If there is a DRM, onDrmInfo() sets it up before executing this callback,\n // so you can start the player.\n override fun onPrepared(mediaPlayer: MediaPlayer) {\n mediaPlayer.start()\n }\n\n### Java\n\n setOnPreparedListener();\n setOnDrmInfoListener();\n setDataSource();\n prepareAsync();\n // ...\n\n // If the data source content is protected you receive a call to the onDrmInfo() callback.\n onDrmInfo() {\n prepareDrm();\n getKeyRequest();\n provideKeyResponse();\n }\n\n // When prepareAsync() finishes, you receive a call to the onPrepared() callback.\n // If there is a DRM, onDrmInfo() sets it up before executing this callback,\n // so you can start the player.\n onPrepared() {\n\n start();\n }\n\nHandle encrypted media\n----------------------\n\nStarting with Android 8.0 (API level 26) `MediaPlayer` can also decrypt Common\nEncryption Scheme (CENC) and HLS sample-level encrypted media\n(METHOD=SAMPLE-AES) for the elementary stream types H.264, and AAC. Full-segment\nencrypted media (METHOD=AES-128) was previously supported.\n\nLearn more\n----------\n\nJetpack Media3 is the recommended solution for media playback in your app. [Read\nmore](/media/media3) about it.\n\nThese pages cover topics relating to recording, storing, and playing back audio\nand video:\n\n- [Supported Media Formats](/guide/topics/media/media-formats)\n- [MediaRecorder](/guide/topics/media/mediarecorder)\n- [Data Storage](/guide/topics/data/data-storage)"]]