Praca z MediaPlayer i zarządzaniem prawami cyfrowymi (DRM)
Zadbaj o dobrą organizację dzięki kolekcji
Zapisuj i kategoryzuj treści zgodnie ze swoimi preferencjami.
Począwszy od Androida 8.0 (poziom interfejsu API 26) MediaPlayer
zawiera interfejsy API, które umożliwiają odtwarzanie materiałów chronionych przez DRM. Interfejsy MediaPlayer DRM są podobne do interfejsu API niskiego poziomu udostępnianego przez MediaDrm
, ale działają na wyższym poziomie i nie udostępniają obiektów extractor, DRM i kryptograficznych obiektów.
Interfejs MediaPlayer DRM API nie zapewnia pełnej funkcjonalności interfejsu MediaDrm
, ale obsługuje najczęstsze przypadki użycia. Obecna implementacja obsługuje te typy treści:
- Pliki multimedialne zabezpieczone technologią Widevine
- Pliki multimedialne chronione przez Widevine, przesyłane strumieniowo lub zdalnie
Ten fragment kodu pokazuje, jak używać nowych metod DRM MediaPlayer
w implementacji synchronicznej.
Aby zarządzać multimediami kontrolowanymi przez DRM, musisz uwzględnić nowe metody obok zwykłego przepływu wywołań MediaPlayer, jak w tym przykładzie:
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();
Zacznij od zainicjowania obiektu MediaPlayer
i ustawienia jego źródła za pomocą funkcji setDataSource()
. Aby korzystać z DRM, wykonaj te czynności:
- Jeśli chcesz, aby aplikacja wykonywała konfigurację niestandardową, zdefiniuj interfejs
OnDrmConfigHelper
i dołącz go do odtwarzacza za pomocą setOnDrmConfigHelper()
.
- Zadzwoń pod numer
prepare()
.
- Zadzwoń pod numer
getDrmInfo()
. Jeśli źródło zawiera treści chronione przez DRM, metoda zwraca wartość niezerową MediaPlayer.DrmInfo
.
Jeśli istnieje grupa MediaPlayer.DrmInfo
:
- Zapoznaj się z mapą dostępnych identyfikatorów UUID i wybierz jeden z nich.
- Przygotuj konfigurację DRM dla bieżącego źródła, wywołując funkcję
prepareDrm()
.
- Jeśli wywołanie zwrotne
OnDrmConfigHelper
zostało utworzone i zarejestrowane, jest ono wywoływane podczas wykonywania funkcji prepareDrm()
. Dzięki temu możesz skonfigurować właściwości DRM przed otwarciem sesji DRM. Wywołanie jest wykonywane synchronicznie w wątku, który wywołał funkcję prepareDrm()
. Aby uzyskać dostęp do właściwości DRM, wywołaj funkcje getDrmPropertyString()
i setDrmPropertyString()
. Unikaj wykonywania długich operacji.
- Jeśli urządzenie nie zostało jeszcze skonfigurowane,
prepareDrm()
uzyskuje dostęp do serwera obsługi administracyjnej, aby skonfigurować urządzenie. Może to potrwać dowolną ilość czasu w zależności od połączenia z siecią.
- Aby uzyskać tablicę bajtów żądania klucza nieprzezroczystego, którą można wysłać do serwera licencji, wywołaj funkcję
getKeyRequest()
.
- Aby poinformować mechanizm DRM o otrzymanej od serwera licencji odpowiedzi dotyczącej klucza, wywołaj funkcję
provideKeyResponse()
. Wynik zależy od typu żądania klucza:
- Jeśli odpowiedź dotyczy żądania klucza offline, wynikiem jest identyfikator zestawu kluczy. Możesz użyć tego identyfikatora zestawu kluczy z
restoreKeys()
, aby przywrócić klucze w nowej sesji.
- Jeśli odpowiedź dotyczy żądania przesyłania strumieniowego lub wydania, wynik jest pusty.
Przygotowanie DRM asynchronicznie
Domyślnie prepareDrm()
działa synchronicznie, blokując się do czasu zakończenia przygotowania. Jednak pierwsze przygotowanie DRM na nowym urządzeniu może wymagać też wdrożenia, które prepareDrm()
obsługuje wewnętrznie. Może to zająć trochę czasu ze względu na działanie sieci. Aby uniknąć blokowania prepareDrm()
, zdefiniuj i ustaw MediaPlayer.OnDrmPreparedListener
.
Ustaw OnDrmPreparedListener
. prepareDrm()
wykonuje w tle konfigurację (jeśli jest potrzebna) i przygotowanie. Po zakończeniu obsługi i przygotowania system wywołuje słuchacza. Nie należy zakładać niczego na temat sekwencji wywołania ani wątku, w którym działa listener (chyba że listener jest zarejestrowany w wątku obsługi). System może wywołać listenera przed powrotem z wynikiem prepareDrm()
lub po nim.
Konfigurowanie DRM asynchronicznie
Możesz zainicjować DRM asynchronicznie, tworząc i rejestrując MediaPlayer.OnDrmInfoListener
na potrzeby przygotowania DRM oraz MediaPlayer.OnDrmPreparedListener
na potrzeby uruchomienia odtwarzacza. Działa ona w połączeniu z prepareAsync()
, jak w tym przykładzie:
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();
}
Obsługa zaszyfrowanych multimediów
Począwszy od Androida 8.0 (interfejs API 26) MediaPlayer
może też odszyfrowywać media szyfrowane według schematu Common Encryption Scheme (CENC) i HLS na poziomie próbki (METHOD=SAMPLE-AES) w przypadku typów strumieni elementarnych H.264 i AAC. Wcześniej obsługiwane były szyfrowane media w całym segmencie (METHOD=AES-128).
Więcej informacji
Jetpack Media3 to zalecane rozwiązanie do odtwarzania multimediów w aplikacji. Dowiedz się więcej o tej usłudze.
Na tych stronach znajdziesz informacje na temat nagrywania, przechowywania i odtwarzania dźwięku i obrazu:
Treść strony i umieszczone na niej fragmenty kodu podlegają licencjom opisanym w Licencji na treści. Java i OpenJDK są znakami towarowymi lub zastrzeżonymi znakami towarowymi należącymi do firmy Oracle lub jej podmiotów stowarzyszonych.
Ostatnia aktualizacja: 2025-07-27 UTC.
[[["Łatwo zrozumieć","easyToUnderstand","thumb-up"],["Rozwiązało to mój problem","solvedMyProblem","thumb-up"],["Inne","otherUp","thumb-up"]],[["Brak potrzebnych mi informacji","missingTheInformationINeed","thumb-down"],["Zbyt skomplikowane / zbyt wiele czynności do wykonania","tooComplicatedTooManySteps","thumb-down"],["Nieaktualne treści","outOfDate","thumb-down"],["Problem z tłumaczeniem","translationIssue","thumb-down"],["Problem z przykładami/kodem","samplesCodeIssue","thumb-down"],["Inne","otherDown","thumb-down"]],["Ostatnia aktualizacja: 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)"]]