العمل مع MediaPlayer وإدارة الحقوق الرقمية (DRM)
تنظيم صفحاتك في مجموعات
يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.
بدءًا من Android 8.0 (المستوى 26 من واجهة برمجة التطبيقات)، يتضمّن MediaPlayer
واجهات برمجة تطبيقات
تتيح تشغيل المواد المحمية بإدارة الحقوق الرقمية. تشبه واجهات برمجة تطبيقات إدارة الحقوق الرقمية في MediaPlayer
واجهة برمجة التطبيقات ذات المستوى المنخفض التي يوفّرها MediaDrm
، ولكنّها تعمل على
مستوى أعلى ولا تُعرِض عناصر الاستخراج وإدارة الحقوق الرقمية والتشفير الأساسية.
على الرغم من أنّ MediaPlayer DRM API لا توفّر الوظائف الكاملة لسمة
MediaDrm
، إلا أنّها تتوافق مع حالات الاستخدام الأكثر شيوعًا. يمكن للتنفيذ الحالي التعامل مع أنواع المحتوى التالية:
- ملفات الوسائط المحلية المحمية بتقنية Widevine
- ملفات الوسائط المتوفّرة للبث أو المحتوى المتوفّر عن بُعد المحمي بتقنية Widevine
يوضّح مقتطف الرمز البرمجي التالي كيفية استخدام طرق إدارة الحقوق الرقمية 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()
كالمعتاد. بعد ذلك، اتّبِع الخطوات التالية لاستخدام إدارة الحقوق الرقمية:
- إذا كنت تريد أن يُجري تطبيقك عملية ضبط مخصّصة، حدِّد واجهة
OnDrmConfigHelper
، واربطها بالمشغّل باستخدام
setOnDrmConfigHelper()
.
- يُرجى الاتصال على
prepare()
.
- يُرجى الاتصال على
getDrmInfo()
. إذا كان المصدر يتضمّن محتوى مُدارًا بإدارة الحقوق الرقمية، تُرجِع الطريقة
قيمة MediaPlayer.DrmInfo
غير صفرية.
إذا كان MediaPlayer.DrmInfo
متوفّرًا:
- راجِع خريطة معرّفات UUID المتاحة واختَر معرّفًا.
- حضِّر إعدادات إدارة الحقوق الرقمية للمصدر الحالي من خلال الاتصال بـ
prepareDrm()
.
- إذا أنشأت وسجلت طلب معاودة اتصال
OnDrmConfigHelper
،
يتم استدعاؤه أثناء تنفيذ prepareDrm()
. يتيح لك ذلك إجراء
إعداد مخصّص لخصائص إدارة الحقوق الرقمية قبل فتح جلسة
إدارة الحقوق الرقمية. يتم استدعاء دالة الاستدعاء بشكل متزامن في سلسلة المحادثات التي استدعت prepareDrm()
. للوصول إلى خصائص إدارة الحقوق الرقمية، يُرجى الاتصال بالرقمَين getDrmPropertyString()
وsetDrmPropertyString()
. تجنَّب
تنفيذ عمليات طويلة.
- إذا لم يتم إعداد الجهاز بعد، يدخل
prepareDrm()
أيضًا إلى خادم الإعداد لإعداد الجهاز. يمكن أن تستغرق هذه العملية
مدّة زمنية متغيرة، وذلك استنادًا إلى إمكانية الاتصال بالشبكة.
- للحصول على صفيف بايت لطلب مفتاح غير شفاف لإرساله إلى خادم الترخيص، يمكنك الاتصال بـ
getKeyRequest()
.
- لإعلام محرّك إدارة الحقوق الرقمية (DRM) باستجابة المفتاح التي تم تلقّيها من ملف الترخيص
الخادم، اتصل بالرقم
provideKeyResponse()
. تعتمد النتيجة على نوع
طلب المفتاح:
- إذا كان الردّ على طلب مفتاح بلا إنترنت، تكون النتيجة معرّفًا لسلسلة مفاتيح. يمكنك استخدام معرّف مجموعة المفاتيح هذا مع
restoreKeys()
لاستعادة المفاتيح إلى جلسة جديدة.
- إذا كان الردّ على طلب بث أو إصدار، تكون النتيجة
null.
إعداد إدارة الحقوق الرقمية بشكل غير متزامن
يتم تشغيل prepareDrm()
بشكل متزامن تلقائيًا، ما يؤدي إلى حظر المحتوى إلى أن تنتهي عملية الإعداد. ومع ذلك، قد يتطلّب الإعداد الأوّل لنظام إدارة الحقوق الرقمية على جهاز جديد أيضًا
عملية توفير تُجريها prepareDrm()
داخليًا، وقد يستغرق اكتمالها
بعض الوقت بسبب عملية تشغيل الشبكة المعنيّة. يمكنك تجنُّب
الحظر على prepareDrm()
من خلال تحديد
MediaPlayer.OnDrmPreparedListener
وضبطه.
اضبط OnDrmPreparedListener
. ينفِّذ prepareDrm()
عملية الإعداد (إذا لزم الأمر) والتحضير في الخلفية. عند اكتمال عملية الإعداد
والتحضير، يتصل النظام بالمستمع. لا تفترض أيًا
من الافتراضات حول تسلسل الاستدعاء أو سلسلة المهام التي يتم فيها تشغيل أداة الاستماع
(ما لم تسجِّل أداة الاستماع في سلسلة مهام معالِج). يمكن للنظام استدعاء
المستمع قبل أو بعد إرجاع prepareDrm()
.
إعداد إدارة الحقوق الرقمية بشكل غير متزامن
يمكنك إعداد إدارة الحقوق الرقمية بشكل غير متزامن من خلال إنشاء وتسجيل الرسالة
MediaPlayer.OnDrmInfoListener
لإعداد إدارة الحقوق الرقمية والرسالة
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 (المستوى 26 من واجهة برمجة التطبيقات)، يمكن لنظام التشغيل MediaPlayer
أيضًا فك تشفير محتوى الوسائط المشفَّر على مستوى عيّنة ملف Common
Encryption Scheme (CENC) وHLS (METHOD=SAMPLE-AES) لأنواع البث الأساسي H.264 وAAC. كان من الممكن سابقًا استخدام الوسائط المشفَّرة بالكامل (METHOD=AES-128).
مزيد من المعلومات
Jetpack Media3 هو الحلّ المُقترَح لتشغيل الوسائط في تطبيقك. اطّلِع على
مزيد من المعلومات حوله.
تتناول هذه الصفحات مواضيع تتعلّق بتسجيل المحتوى الصوتي
والفيديو وتخزينه وتشغيله:
يخضع كل من المحتوى وعيّنات التعليمات البرمجية في هذه الصفحة للتراخيص الموضحّة في ترخيص استخدام المحتوى. إنّ Java وOpenJDK هما علامتان تجاريتان مسجَّلتان لشركة Oracle و/أو الشركات التابعة لها.
تاريخ التعديل الأخير: 2025-07-27 (حسب التوقيت العالمي المتفَّق عليه)
[[["يسهُل فهم المحتوى.","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 (حسب التوقيت العالمي المتفَّق عليه)"],[],[],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)"]]