עבודה עם MediaPlayer ועם ניהול זכויות דיגיטלי (DRM)
קל לארגן דפים בעזרת אוספים
אפשר לשמור ולסווג תוכן על סמך ההעדפות שלך.
החל מגרסה Android 8.0 (רמת API 26), MediaPlayer
כולל ממשקי API שתומכים בהפעלה של תוכן שמוגן באמצעות DRM. ממשקי ה-API של MediaPlayer DRM דומים לממשק ה-API ברמה נמוכה ש-MediaDrm
מספק, אבל הם פועלים ברמה גבוהה יותר ולא חושפים את האובייקטים הבסיסיים של ה-extractor, ה-DRM והקריפטוגרפיה.
אמנם MediaPlayer DRM API לא מספק את הפונקציונליות המלאה של MediaDrm
, אבל הוא תומך בתרחישי השימוש הנפוצים ביותר. ההטמעה הנוכחית יכולה לטפל בסוגי התוכן הבאים:
- קובצי מדיה מקומיים שמוגנים על ידי Widevine
- קבצי מדיה מרוחקים או בסטרימינג שמוגנים על ידי Widevine
קטע הקוד הבא מראה איך להשתמש בשיטות החדשות של DRM MediaPlayer
בהטמעה סינכרונית.
כדי לנהל מדיה שנמצאת בשליטת 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
שאינו null.
אם השדה MediaPlayer.DrmInfo
קיים:
- בודקים את המפה של מזהי UUID זמינים ובוחרים אחד מהם.
- מכינים את הגדרת ה-DRM למקור הנוכחי באמצעות קריאה ל-
prepareDrm()
.
- אם יצרתם והרשמתם קריאה חוזרת מסוג
OnDrmConfigHelper
, היא תתבצע בזמן ההרצה של prepareDrm()
. כך תוכלו לבצע הגדרה מותאמת אישית של מאפייני ה-DRM לפני פתיחת הסשן של ה-DRM. פונקציית ה-callback נקראת באופן סינכרוני בשרשור שבו התבצעה הקריאה ל-prepareDrm()
. כדי לגשת למאפייני ה-DRM, צריך להפעיל את הפונקציות getDrmPropertyString()
ו-setDrmPropertyString()
. הימנעו מביצוע פעולות ממושכות.
- אם המכשיר עדיין לא הוקצה,
prepareDrm()
ניגש גם לשרת ההקצאה כדי להקצות את המכשיר. התהליך עשוי להימשך זמן משתנה, בהתאם לקישוריות לרשת.
- כדי לקבל מערך בייט של בקשת מפתח אטום שאפשר לשלוח לשרת רישיונות, צריך לבצע קריאה ל-
getKeyRequest()
.
- כדי להודיע למנוע ה-DRM על תגובת המפתח שהתקבלה משרת הרישיון, צריך לבצע קריאה ל-
provideKeyResponse()
. התוצאה תלויה בסוג הבקשה למפתח:
- אם התשובה היא לבקשת מפתח אופליין, התוצאה היא מזהה של קבוצת מפתחות. אפשר להשתמש במזהה של קבוצת המפתחות עם
restoreKeys()
כדי לשחזר את המפתחות לסשן חדש.
- אם התשובה היא לבקשת סטרימינג או פרסום, התוצאה היא null.
הכנת DRM באופן אסינכרוני
כברירת מחדל, הפונקציה prepareDrm()
פועלת באופן סינכרוני, וחוסמת את הקוד עד שההכנה מסתיימת. עם זאת, יכול להיות שתצטרכו להקצות גם את ההכנה הראשונה של DRM במכשיר חדש. prepareDrm()
מטפל בכך באופן פנימי, ויכול להיות שיחלוף זמן מה עד שההקצאה תסתיים בגלל פעולות הרשת הכרוכות בכך. כדי להימנע מחסימה ב-prepareDrm()
, צריך להגדיר MediaPlayer.OnDrmPreparedListener
.
מגדירים OnDrmPreparedListener
. prepareDrm()
מבצע את ההקצאה (אם יש צורך) וההכנה ברקע. בסיום ההקצאה וההכנה, המערכת קוראת למאזין. אל תניחו הנחות לגבי רצף הקריאות או על השרשור שבו ה-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();
}
טיפול במדיה מוצפנת
החל מגרסה 8.0 של Android (רמת 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)"]]