کار با MediaPlayer و مدیریت حقوق دیجیتال (DRM)
با مجموعهها، منظم بمانید
ذخیره و طبقهبندی محتوا براساس اولویتهای شما.
با شروع Android 8.0 (سطح API 26)، MediaPlayer
شامل APIهایی است که از پخش مواد محافظت شده با DRM پشتیبانی می کند. API های MediaPlayer DRM شبیه به API سطح پایین ارائه شده توسط MediaDrm
هستند، اما در سطح بالاتری کار می کنند و استخراج کننده، DRM و اشیاء رمزنگاری زیرین را در معرض دید قرار نمی دهند.
اگرچه MediaPlayer DRM API عملکرد کامل MediaDrm
را ارائه نمی دهد، اما از رایج ترین موارد استفاده پشتیبانی می کند. پیاده سازی فعلی می تواند انواع محتوای زیر را مدیریت کند:
- فایلهای رسانه محلی محافظت شده با Widevine
- فایل های رسانه ای از راه دور یا جریانی محافظت شده با Widevine
قطعه کد زیر نحوه استفاده از روش های جدید DRM MediaPlayer
را در پیاده سازی همزمان نشان می دهد.
برای مدیریت رسانه های کنترل شده با DRM، باید روش های جدید را در کنار جریان معمول تماس های MediaPlayer قرار دهید، همانطور که در این مثال نشان داده شده است:
کاتلین
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()
}
جاوا
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 های موجود را بررسی کنید و یکی را انتخاب کنید.
- با فراخوانی
prepareDrm()
پیکربندی DRM را برای منبع فعلی آماده کنید.- اگر یک
OnDrmConfigHelper
ایجاد و ثبت کرده باشید، در حالی که prepareDrm()
در حال اجرا است فراخوانی می شود. این به شما امکان می دهد تا قبل از باز کردن جلسه DRM، تنظیمات سفارشی خصوصیات DRM را انجام دهید. فراخوانی به طور همزمان در رشته ای که prepareDrm()
نامیده می شود فراخوانی می شود. برای دسترسی به خصوصیات DRM، getDrmPropertyString()
و setDrmPropertyString()
را فراخوانی کنید. از انجام عملیات طولانی مدت خودداری کنید. - اگر دستگاه هنوز تدارک دیده نشده است،
prepareDrm()
نیز به سرور تأمین کننده دسترسی پیدا می کند تا دستگاه را تأمین کند. بسته به اتصال شبکه، ممکن است زمان متغیری طول بکشد.
- برای دریافت آرایه بایت درخواست کلید غیرشفاف برای ارسال به سرور مجوز،
getKeyRequest()
را فراخوانی کنید. - برای اطلاع دادن به موتور DRM در مورد پاسخ کلید دریافتی از سرور مجوز، با
provideKeyResponse()
تماس بگیرید. نتیجه به نوع درخواست کلید بستگی دارد:- اگر پاسخ برای درخواست کلید آفلاین باشد، نتیجه یک شناسه مجموعه کلید است. می توانید از این شناسه مجموعه کلید با
restoreKeys()
برای بازگرداندن کلیدها به یک جلسه جدید استفاده کنید. - اگر پاسخ برای درخواست پخش یا انتشار باشد، نتیجه صفر است.
DRM را به صورت ناهمزمان آماده کنید
بهطور پیشفرض، prepareDrm()
به صورت همزمان اجرا میشود و تا پایان آمادهسازی مسدود میشود. با این حال، اولین آماده سازی DRM در یک دستگاه جدید نیز ممکن است نیاز به تدارک داشته باشد، که prepareDrm()
به صورت داخلی انجام می شود و ممکن است به دلیل عملیات شبکه درگیر مدتی طول بکشد. شما می توانید با تعریف و تنظیم MediaPlayer.OnDrmPreparedListener
از مسدود کردن در prepareDrm()
جلوگیری کنید.
یک OnDrmPreparedListener
تنظیم کنید. prepareDrm()
تهیه (در صورت نیاز) و آماده سازی را در پس زمینه انجام می دهد. هنگام تهیه و آماده سازی، سیستم شنونده را فرا می خواند. در مورد دنباله فراخوانی یا رشته ای که شنونده در آن اجرا می شود هیچ فرضی نداشته باشید (مگر اینکه شنونده را با یک رشته کنترل کننده ثبت کنید). سیستم می تواند شنونده را قبل یا بعد از بازگشت prepareDrm()
فراخوانی کند.
DRM را به صورت ناهمزمان تنظیم کنید
می توانید با ایجاد و ثبت MediaPlayer.OnDrmInfoListener
برای آماده سازی DRM و MediaPlayer.OnDrmPreparedListener
برای شروع پخش کننده، DRM را به صورت ناهمزمان مقداردهی کنید. همانطور که در این مثال نشان داده شده است، آنها در ارتباط با prepareAsync()
کار می کنند:
کاتلین
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()
}
جاوا
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
همچنین میتواند Common Encryption Scheme (CENC) و رسانه رمزگذاریشده در سطح نمونه HLS (METHOD=SAMPLE-AES) را برای انواع جریان ابتدایی H.264 و AAC رمزگشایی کند. رسانه رمزگذاری شده تمام بخش (METHOD=AES-128) قبلاً پشتیبانی می شد.
بیشتر بدانید
Jetpack Media3 راه حل پیشنهادی برای پخش رسانه در برنامه شما است. در مورد آن بیشتر بخوانید .
این صفحات موضوعات مربوط به ضبط، ذخیره و پخش صدا و تصویر را پوشش می دهند:
محتوا و نمونه کدها در این صفحه مشمول پروانههای توصیفشده در پروانه محتوا هستند. جاوا و OpenJDK علامتهای تجاری یا علامتهای تجاری ثبتشده Oracle و/یا وابستههای آن هستند.
تاریخ آخرین بهروزرسانی 2025-07-29 بهوقت ساعت هماهنگ جهانی.
[[["درک آسان","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-29 بهوقت ساعت هماهنگ جهانی."],[],[],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)"]]