MediaPlayer – Übersicht

Das Multimedia-Framework von Android unterstützt die Wiedergabe verschiedener gängiger Medientypen, sodass mit dem Sie Audio, Videos und Bilder ganz einfach in Ihre Anwendungen einbinden können. Sie können Audioinhalte oder Videos aus Mediendateien, die in den Ressourcen Ihrer Anwendung gespeichert sind (Rohressourcen), aus eigenständigen Dateien im Dateisystem oder aus einem über eine Netzwerkverbindung eingehenden Datenstream – alles unter Verwendung von MediaPlayer-APIs.

In diesem Dokument erfahren Sie, wie Sie MediaPlayer zum Schreiben einer Mediawiedergabe die mit dem Nutzer und dem System interagiert, um gute Leistung und User Experience zu schaffen. Alternativ können Sie ExoPlayer, eine anpassbare Open-Source-Software, Bibliothek, die leistungsstarke Funktionen unterstützt, die in MediaPlayer nicht verfügbar sind

Hinweis:Sie können die Audiodaten nur über die Standardausgabe wiedergeben. . Im Moment ist das der Lautsprecher des Mobilgeräts oder ein Bluetooth-Headset. Du kannst keinen Ton abspielen Audiodateien während eines Anrufs.

Grundlagen

Die folgenden Klassen werden für die Wiedergabe von Ton und Video im Android-Framework verwendet:

MediaPlayer
Diese Klasse ist die primäre API für die Wiedergabe von Ton und Video.
AudioManager
In diesem Kurs werden die Audioquellen und die Audioausgabe auf einem Gerät verwaltet.

Manifestdeklarationen

Bevor Sie mit der Entwicklung Ihrer Anwendung mit MediaPlayer beginnen, stellen Sie sicher, dass Ihr Manifest die entsprechenden Deklarationen, um die Nutzung zugehöriger Funktionen zu ermöglichen.

  • Internet Permission – wenn Sie MediaPlayer zum Streamen netzwerkbasierter Inhalt enthält, muss Ihre Anwendung Netzwerkzugriff anfordern.
    <uses-permission android:name="android.permission.INTERNET" />
    
  • Berechtigung für Wake Lock – wenn Ihre Player-App den Bildschirm beibehalten muss nicht gedimmt oder der Prozessor in den Ruhezustand wechselt, oder es werden MediaPlayer.setScreenOnWhilePlaying() oder MediaPlayer.setWakeMode()-Methoden verwenden, müssen Sie diese Berechtigung anfordern.
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    

MediaPlayer verwenden

Eine der wichtigsten Komponenten des Medien-Frameworks ist die MediaPlayer . Ein Objekt dieser Klasse kann sowohl Audio- als auch Videoinhalte abrufen, decodieren und wiedergeben mit minimalem Einrichtungsaufwand. Es werden verschiedene Medienquellen unterstützt, darunter:

  • Lokale Ressourcen
  • Interne URIs, beispielsweise solche, die Sie von einem Content Resolver erhalten
  • Externe URLs (Streaming)

Eine Liste der von Android unterstützten Medienformate finden Sie auf der Seite Unterstützte Medien Seite „Formate“.

Hier ist ein Beispiel der Audiowiedergabe, die als lokale Rohressource verfügbar ist (gespeichert im res/raw/-Verzeichnis):

Kotlin

var mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1)
mediaPlayer.start() // no need to call prepare(); create() does that for you

Java

MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1);
mediaPlayer.start(); // no need to call prepare(); create() does that for you

In diesem Fall wird ein „Roh“-Wert Ressource ist eine Datei, die das System nicht auf eine bestimmte Weise zu parsen. Der Inhalt dieser Ressource sollte jedoch nicht unbearbeitete Audioinhalte sind. Es sollte sich dabei um eine korrekt codierte und formatierte Mediendatei in einem unterstützt.

Und so können Sie einen URI abspielen, der lokal im System verfügbar ist: (z. B. die Sie über einen Content Resolver erhalten haben):

Kotlin

val myUri: Uri = .... // initialize Uri here
val mediaPlayer = MediaPlayer().apply {
    setAudioAttributes(
        AudioAttributes.Builder()
            .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
            .setUsage(AudioAttributes.USAGE_MEDIA)
            .build()
    )
    setDataSource(applicationContext, myUri)
    prepare()
    start()
}

Java

Uri myUri = ....; // initialize Uri here
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioAttributes(
    new AudioAttributes.Builder()
        .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
        .setUsage(AudioAttributes.USAGE_MEDIA)
        .build()
);
mediaPlayer.setDataSource(getApplicationContext(), myUri);
mediaPlayer.prepare();
mediaPlayer.start();

Die Wiedergabe über eine Remote-URL per HTTP-Streaming sieht so aus:

Kotlin

val url = "http://........" // your URL here
val mediaPlayer = MediaPlayer().apply {
    setAudioAttributes(
        AudioAttributes.Builder()
            .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
            .setUsage(AudioAttributes.USAGE_MEDIA)
            .build()
    )
    setDataSource(url)
    prepare() // might take long! (for buffering, etc)
    start()
}

Java

String url = "http://........"; // your URL here
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioAttributes(
    new AudioAttributes.Builder()
        .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
        .setUsage(AudioAttributes.USAGE_MEDIA)
        .build()
);
mediaPlayer.setDataSource(url);
mediaPlayer.prepare(); // might take long! (for buffering, etc)
mediaPlayer.start();

Hinweis: Wenn Sie eine URL übergeben, um eine Online-Mediendatei zu streamen, muss die Datei progressiver Download.

Achtung:Sie müssen den Code entweder abfangen oder übergeben. IllegalArgumentException und IOException bei Verwendung setDataSource(), weil Die Datei, auf die Sie verweisen, ist möglicherweise nicht vorhanden.

Asynchrone Vorbereitung

Die Verwendung von MediaPlayer kann unkompliziert sein in Prinzip. Es ist jedoch wichtig zu bedenken, dass um sie korrekt in eine typische Android-App zu integrieren. Für kann der Aufruf von prepare() lange dauern, da die müssen Mediendaten abgerufen und decodiert werden. Wie bei allen anderen deren Ausführung lange dauern kann, sollten Sie sie niemals aus Ihrem des UI-Threads der Anwendung. Dadurch bleibt die Benutzeroberfläche hängen, bis die Methode zurückgegeben wird. Dies beeinträchtigt die Nutzererfahrung und kann zu einem ANR-Fehler (Application Not Responding) führen. Selbst wenn erwarten, dass Ihre Ressource schnell geladen wird, denken Sie daran, dass alles, was mehr als ein Zehntel in der Benutzeroberfläche zu antworten, führt zu einer spürbaren Pause und der Nutzer den Eindruck hat, dass Ihre Anwendung langsam ist.

Erstellen Sie einen weiteren Thread, um das Aufhängen des UI-Threads zu vermeiden. Bereiten Sie das MediaPlayer vor und benachrichtigen Sie den Hauptthread, wenn Sie fertig sind. Während könnten Sie die Threading-Logik schreiben, Dieses Muster ist bei der Verwendung von MediaPlayer so weit verbreitet, dass das Framework bietet eine bequeme Möglichkeit, diese Aufgabe mithilfe des prepareAsync()-Methode. Diese Methode beginnt im Hintergrund mit der Vorbereitung der Medien und kehrt sofort zurück. Wenn die Medien die Vorbereitung abgeschlossen ist, wird der onPrepared() von MediaPlayer.OnPreparedListener konfiguriert durch setOnPreparedListener() wird aufgerufen.

Status verwalten

Ein weiterer Aspekt einer MediaPlayer, den Sie berücksichtigen sollten, dass sie bundesstaatenbasiert ist. Das heißt, die MediaPlayer hat einen internen Status die Sie beim Schreiben Ihres Codes immer beachten müssen, da bestimmte Vorgänge sind nur gültig, wenn sich der Player in einem bestimmten Status befindet. Wenn Sie einen Vorgang im falsch ist, kann das System eine Ausnahme auslösen oder andere unerwünschte Verhaltensweisen verursachen.

Die Dokumentation im Die Klasse MediaPlayer zeigt ein vollständiges Zustandsdiagramm, mit welchen Methoden MediaPlayer von einem Status in einen anderen verschoben wird. Wenn Sie beispielsweise eine neue MediaPlayer erstellen, befindet sie sich im Bereich Inaktiv. Bundesstaat. An dieser Stelle sollten Sie sie initialisieren, indem Sie setDataSource() und dabei in den Status Initialized gesetzt. Danach müssen Sie sie entweder mit dem prepare() oder prepareAsync()-Methode. Wann? Die MediaPlayer ist fertig vorbereitet und tritt in Prepared ein. Das bedeutet, dass Sie start() aufrufen können. damit die Medien wiedergegeben werden. Wie das Diagramm zeigt, kannst du zwischen den Status Gestartet, Pausiert und Wiedergabe abgeschlossen wechseln. indem wir Methoden wie start(), pause() und seekTo(), unter anderem. Wenn Sie stop() aufrufen. Beachten Sie jedoch, dass Sie kann start() erst wieder anrufen, wenn Sie Bereiten Sie MediaPlayer noch einmal vor.

Zustandsdiagramm immer beibehalten wenn Sie Code schreiben, der mit einem MediaPlayer-Objekt, da das Aufrufen der Methoden vom falschen Status ein Ursache von Fehlern zu finden.

MediaPlayer freigeben

Ein MediaPlayer kann wertvolle Systemressourcen. Treffen Sie daher immer zusätzliche Vorsichtsmaßnahmen, um sicherzustellen, dass die Verbindung zu einer MediaPlayer-Instanz länger als nötig dauert. Wenn Sie sollten Sie immer zuerst anrufen, release(), um sicherzustellen, dass Systemressourcen ordnungsgemäß freigegeben werden. Wenn Sie zum Beispiel MediaPlayer verwendet und deine Aktivität einen Anruf an onStop() empfängt, musst du MediaPlayer freigeben, weil es macht es wenig Sinn, sie festzuhalten, wenn die Aktivität nicht mit ihnen interagiert. (es sei denn, Sie spielen Medien im Hintergrund ab, was im nächsten Abschnitt erläutert wird). Wenn Ihre Aktivität wieder aufgenommen oder neu gestartet wird, müssen Sie natürlich Erstellen Sie ein neues MediaPlayer und bereiten Sie es noch einmal vor, bevor Sie die Wiedergabe fortsetzen.

So kannst du deine MediaPlayer freigeben und dann auf null setzen:

Kotlin

mediaPlayer?.release()
mediaPlayer = null

Java

mediaPlayer.release();
mediaPlayer = null;

Denken Sie zum Beispiel an die Probleme, die auftreten können, wenn Sie hat vergessen, den MediaPlayer freizugeben, wenn die Aktivität beendet wurde, aber erstellt einen wenn die Aktivität wieder beginnt. Wie Sie vielleicht wissen, ändert sich Bildschirmausrichtung (oder ändert die Gerätekonfiguration auf andere Weise), erledigt das System dies, indem es die Aktivität (standardmäßig) neu startet. als Nutzer alle Systemressourcen verbrauchen. wechselt das Gerät zwischen Hoch- und Querformat, da bei jedem wird ein neues Gerät (MediaPlayer) erstellt, das nie Veröffentlichung. Weitere Informationen zu Laufzeitneustarts finden Sie unter Umgang mit Laufzeitänderungen.

Du fragst dich vielleicht, was passiert, wenn du „Hintergrundmedien“ selbst wenn der Nutzer Ihre Aktivität beendet, ähnlich wie wie sich die integrierte Musik-App verhält. In diesem Fall benötigen Sie eine MediaPlayer, die von einem Dienst kontrolliert wird, wie werden wir im nächsten Abschnitt

MediaPlayer in einem Dienst verwenden

Wenn Sie möchten, dass Ihre Medien auch dann im Hintergrund wiedergegeben werden, wenn Ihre App nicht auf dem Bildschirm ist, d. h., die Wiedergabe soll fortgesetzt werden, während der Nutzer Anwendungen interagieren müssen, müssen Sie eine Bedienen und steuern Sie MediaPlayer-Instanz. Sie müssen den MediaPlayer in einem MediaBrowserServiceCompat-Dienst verwenden und interagieren sie mit einem MediaBrowserCompat in einer anderen Aktivität.

Gehen Sie bei der Client-/Server-Einrichtung mit Bedacht vor. Es gibt Erwartungen, wie ein Spieler, der in einem Hintergrunddienst läuft, mit dem Rest des System. Wenn Ihre App diese Erwartungen nicht erfüllt, kann der Nutzer schlechte Erfahrungen machen. Gelesen Audio-App erstellen .

In diesem Abschnitt werden spezielle Anweisungen zum Verwalten eines MediaPlayers beschrieben, wenn er in einem Dienst implementiert ist.

Asynchron ausführen

Wie bei einem Activity funktionieren alle in einem Service erfolgt in einem einzelnen Thread von Wenn Sie eine Aktivität und einen Dienst aus derselben Anwendung ausführen, verwenden standardmäßig denselben Thread (den „Hauptthread“). Daher müssen Dienste eingehende Intents schnell verarbeiten und führen nie langwierige Berechnungen durch. Bei starken zu erwarten ist, müssen Sie diese Aufgaben asynchron ausführen: entweder aus eines anderen Threads, den Sie selbst implementieren, oder die vielen Möglichkeiten des Frameworks nutzen. für die asynchrone Verarbeitung.

Wenn Sie beispielsweise einen MediaPlayer aus Ihrem Hauptthread verwenden, sollten Sie prepareAsync() aufrufen, statt prepare() und implementieren Sie MediaPlayer.OnPreparedListener um benachrichtigt zu werden, wenn die Vorbereitung abgeschlossen ist und du mit dem Spielen beginnen kannst. Beispiel:

Kotlin

private const val ACTION_PLAY: String = "com.example.action.PLAY"

class MyService: Service(), MediaPlayer.OnPreparedListener {

    private var mMediaPlayer: MediaPlayer? = null

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        ...
        val action: String = intent.action
        when(action) {
            ACTION_PLAY -> {
                mMediaPlayer = ... // initialize it here
                mMediaPlayer?.apply {
                    setOnPreparedListener(this@MyService)
                    prepareAsync() // prepare async to not block main thread
                }

            }
        }
        ...
    }

    /** Called when MediaPlayer is ready */
    override fun onPrepared(mediaPlayer: MediaPlayer) {
        mediaPlayer.start()
    }
}

Java

public class MyService extends Service implements MediaPlayer.OnPreparedListener {
    private static final String ACTION_PLAY = "com.example.action.PLAY";
    MediaPlayer mediaPlayer = null;

    public int onStartCommand(Intent intent, int flags, int startId) {
        ...
        if (intent.getAction().equals(ACTION_PLAY)) {
            mediaPlayer = ... // initialize it here
            mediaPlayer.setOnPreparedListener(this);
            mediaPlayer.prepareAsync(); // prepare async to not block main thread
        }
    }

    /** Called when MediaPlayer is ready */
    public void onPrepared(MediaPlayer player) {
        player.start();
    }
}

Asynchrone Fehler verarbeiten

Bei synchronen Vorgängen treten normalerweise Fehler auf mit einer Ausnahme oder einem Fehlercode signalisiert werden, aber wenn Sie asynchrone sollten Sie darauf achten, dass Ihre Anwendung Fehler angemessen zu erfassen. Im Fall von MediaPlayer können Sie dies erreichen, indem Sie MediaPlayer.OnErrorListener und in Ihrer MediaPlayer-Instanz festlegen:

Kotlin

class MyService : Service(), MediaPlayer.OnErrorListener {

    private var mediaPlayer: MediaPlayer? = null

    fun initMediaPlayer() {
        // ...initialize the MediaPlayer here...
        mediaPlayer?.setOnErrorListener(this)
    }

    override fun onError(mp: MediaPlayer, what: Int, extra: Int): Boolean {
        // ... react appropriately ...
        // The MediaPlayer has moved to the Error state, must be reset!
    }
}

Java

public class MyService extends Service implements MediaPlayer.OnErrorListener {
    MediaPlayer mediaPlayer;

    public void initMediaPlayer() {
        // ...initialize the MediaPlayer here...
        mediaPlayer.setOnErrorListener(this);
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        // ... react appropriately ...
        // The MediaPlayer has moved to the Error state, must be reset!
    }
}

Wichtig: Wenn ein Fehler auftritt, wird die Funktion MediaPlayer in den Status Error (Fehler). MediaPlayer für das vollständige Zustandsdiagramm) Sie müssen es zurücksetzen, bevor Sie es wieder verwenden können.

Wakelocks verwenden

Beim Entwerfen von Anwendungen, die Medien abspielen im Hintergrund ausgeführt wird, wechselt das Gerät möglicherweise in den Ruhemodus während der Dienst ausgeführt wird. Da das Android-System versucht, während das Gerät im Ruhezustand ist, versucht das System, alle Funktionen des Smartphones, nicht notwendig, auch die CPU- und WLAN-Hardware. Wenn Ihr Dienst jedoch Musik wiedergibt oder streamt, möchten Sie verhindern, dass dass das System die Wiedergabe nicht beeinträchtigt.

Um sicherzustellen, dass Ihr Dienst weiterhin unter müssen Sie „Wakelocks“ verwenden. Ein Wakelock ist eine Möglichkeit, dem System, das Ihre Anwendung verwendet, eine Funktion, die in der Regel auch wenn das Smartphone inaktiv ist.

Hinweis:Wakelocks sollten immer sparsam verwendet und in den Händen gehalten werden. nur so lange wie nötig, da sie die Akkulaufzeit erheblich verkürzen. .

Damit die CPU weiter ausgeführt wird, während MediaPlayer ausgeführt wird starten, rufen Sie beim Initialisieren von MediaPlayer die Methode setWakeMode() auf. Danach MediaPlayer behält die angegebene Sperre beim Abspielen bei und gibt die Sperre frei wenn sie pausiert oder angehalten wird:

Kotlin

mediaPlayer = MediaPlayer().apply {
    // ... other initialization here ...
    setWakeMode(applicationContext, PowerManager.PARTIAL_WAKE_LOCK)
}

Java

mediaPlayer = new MediaPlayer();
// ... other initialization here ...
mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);

Der in diesem Beispiel erworbene Wakelock garantiert jedoch nur, dass die CPU aktiv bleibt. Wenn streamt man Medien über das und ein WLAN-Netzwerk nutzt, empfiehlt es sich, WifiLock als die ihr manuell erwerben und veröffentlichen müsst. Wenn Sie also anfangen, MediaPlayer durch die Remote-URL ersetzt, sollten Sie die WLAN-Sperre erstellen und abrufen. Beispiel:

Kotlin

val wifiManager = getSystemService(Context.WIFI_SERVICE) as WifiManager
val wifiLock: WifiManager.WifiLock =
    wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, "mylock")

wifiLock.acquire()

Java

WifiLock wifiLock = ((WifiManager) getSystemService(Context.WIFI_SERVICE))
    .createWifiLock(WifiManager.WIFI_MODE_FULL, "mylock");

wifiLock.acquire();

Wenn Sie Ihre Medien pausieren oder stoppen oder wenn Sie die Netzwerk aktivieren, sollten Sie die Sperre aufheben:

Kotlin

wifiLock.release()

Java

wifiLock.release();

Bereinigung wird durchgeführt

Wie bereits erwähnt, kann ein MediaPlayer-Objekt einen erheblichen auf eine ausreichend große Menge an Systemressourcen hin. Daher sollten Sie sie nur so lange behalten, wie Sie benötigen, release(), wenn du damit fertig bist. Es ist wichtig, explizit aufzurufen, anstatt sich auf die automatische Speicherbereinigung des Systems zu verlassen, kann es einige Zeit dauern, bis die automatische Speicherbereinigung das MediaPlayer-Objekt zurückfordert. da sie nur empfindlich auf Erinnerungsbedürfnisse reagieren und nicht auf einen Mangel an anderen medienbezogenen Ressourcen. Wenn Sie also einen Dienst nutzen, sollten Sie onDestroy()-Methode, um sicherzustellen, dass MediaPlayer:

Kotlin

class MyService : Service() {

    private var mediaPlayer: MediaPlayer? = null
    // ...

    override fun onDestroy() {
        super.onDestroy()
        mediaPlayer?.release()
    }
}

Java

public class MyService extends Service {
   MediaPlayer mediaPlayer;
   // ...

   @Override
   public void onDestroy() {
       super.onDestroy();
       if (mediaPlayer != null) mediaPlayer.release();
   }
}

Du solltest immer nach anderen Möglichkeiten zur Veröffentlichung deines MediaPlayer suchen abgesehen davon, dass es beim Herunterfahren freigegeben wird. Wenn Sie beispielsweise keine Medien über einen längeren Zeitraum wiedergeben zu können (z. B. nach dem Verlust des Audiofokus), sollten Sie Ihre vorhandene MediaPlayer auf jeden Fall freigeben und neu erstellen. . Am Wenn Sie die Wiedergabe nur für kurze Zeit stoppen möchten, sollten Sie MediaPlayer behalten, um den Aufwand für die Erstellung und Vorbereitung zu vermeiden noch einmal.

Digitale Rechteverwaltung (Digital Rights Management, DRM)

Ab Android 8.0 (API-Level 26) enthält MediaPlayer APIs, die die Wiedergabe von DRM-geschütztem Material unterstützen. Sie ähneln dem Low-Level-API von MediaDrm, befinden sich jedoch auf einer höheren Ebene und haben die zugrunde liegenden Extraktor-, drm- und Crypto-Objekte preisgeben.

Obwohl die MediaPlayer DRM API nicht die volle Funktionalität von MediaDrm unterstützt die gängigsten Anwendungsfälle. Die Die aktuelle Implementierung kann die folgenden Inhaltstypen verarbeiten:

  • Widevine-geschützte lokale Mediendateien
  • Widevine-geschützte Remote-/Streaming-Mediendateien

Das folgende Code-Snippet zeigt, wie der neue DRM MediaPlayer verwendet wird. in einer einfachen synchronen Implementierung.

Um DRM-gesteuerte Medien zu verwalten, müssen Sie die neuen Methoden neben dem üblichen Ablauf von MediaPlayer-Aufrufen, wie unten dargestellt:

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();

Beginnen Sie mit dem Initialisieren des MediaPlayer-Objekts und der Einstellung aus seiner Quelle mit setDataSource(), wie gewohnt. So nutzen Sie die digitale Rechteverwaltung:

  1. Wenn Ihre App eine benutzerdefinierte Konfiguration vornehmen soll, definieren Sie ein OnDrmConfigHelper-Schnittstelle und hängen Sie sie an die Player mit setOnDrmConfigHelper().
  2. prepare() anrufen.
  3. getDrmInfo() anrufen. Ob die Quelle über digitale Rechteverwaltung verfügt Inhalt enthält, gibt die Methode einen Wert ungleich null zurück. MediaPlayer.DrmInfo-Wert.

Wenn MediaPlayer.DrmInfo vorhanden ist:

  1. Sehen Sie sich die Karte der verfügbaren UUIDs an und wählen Sie eine aus.
  2. Bereiten Sie die DRM-Konfiguration für die aktuelle Quelle vor. Rufen Sie dazu prepareDrm() auf.
    • Wenn Sie ein OnDrmConfigHelper-Callback: Dieser heißt während prepareDrm() ausgeführt wird. So können Sie die digitale Rechteverwaltung (DRM) benutzerdefiniert konfigurieren. bevor Sie die DRM-Sitzung öffnen. Der Callback wird als synchron im Thread an, prepareDrm() Bis auf die DRM-Eigenschaften zugreifen, getDrmPropertyString() und setDrmPropertyString(). Vermeiden Sie langwierige Vorgänge.
    • Wenn das Gerät noch nicht bereitgestellt wurde, prepareDrm() greift auf den Bereitstellungsserver zu, um das Gerät bereitzustellen. Dies kann bis zu variieren je nach Netzwerkverbindung.
  3. Um ein intransparentes Schlüsselanforderungs-Byte-Array zu erhalten, das an einen Lizenzserver gesendet werden soll, rufen Sie getKeyRequest()
  4. Um das DRM-Modul über die Schlüsselantwort vom Lizenzserver zu informieren, rufen Sie provideKeyResponse() Das Ergebnis hängt von der Art der Schlüsselanfrage ab: <ph type="x-smartling-placeholder">
      </ph>
    • Wenn sich die Antwort auf eine Offlineschlüsselanforderung bezieht, ist das Ergebnis eine Schlüsselsatzkennung. Sie können diese Schlüsselsatz-ID mit restoreKeys(), um die Schlüssel auf einen neuen Wert wiederherzustellen Sitzung.
    • Wenn sich die Antwort auf eine Streaming- oder Release-Anfrage bezieht, ist das Ergebnis null.

prepareDrm() asynchron ausführen

Standardmäßig prepareDrm() wird synchron ausgeführt und blockiert, bis die Vorbereitung abgeschlossen ist. Genau kann die erste DRM-Vorbereitung auf einem neuen Gerät auch eine Bereitstellung erfordern. werden intern von prepareDrm() und kann aufgrund des Netzwerkbetriebs einige Zeit in Anspruch nehmen. Sie können Blockierung vermeiden auf prepareDrm() von Definieren und Festlegen von MediaPlayer.OnDrmPreparedListener.

Wenn Sie eine OnDrmPreparedListener festlegen, prepareDrm() führt bei Bedarf die Bereitstellung und Vorbereitung im Hintergrund aus. Wann? Bereitstellung und Vorbereitung abgeschlossen sind, wird der Listener aufgerufen. Sie sollten keine Annahmen über die aufrufende Sequenz oder den Thread treffen, in dem Listener wird ausgeführt, es sei denn, der Listener ist in einem Handler-Thread registriert. Der Listener kann vor oder nach dem prepareDrm() Rücksendungen.

DRM asynchron einrichten

Sie können die digitale Rechteverwaltung asynchron initialisieren, indem Sie die Datei MediaPlayer.OnDrmInfoListener für die Vorbereitung auf die digitale Rechteverwaltung und die MediaPlayer.OnDrmPreparedListener, um den Player zu starten. Sie arbeiten in Verbindung mit prepareAsync(), wie unten gezeigt:

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();
}

Verschlüsselte Medien verarbeiten

Ab Android 8.0 (API-Level 26) kann MediaPlayer auch die App entschlüsseln Common Encryption Scheme (CENC) und HLS-Verschlüsselte Medien auf Sampleebene (METHOD=SAMPLE-AES) für die Elementarstreamtypen H.264 und AAC. Bisher wurden vollständig segmentverschlüsselte Medien (METHOD=AES-128) unterstützt.

Medien von einem ContentResolver abrufen

Eine weitere Funktion, die in einer Mediaplayer-Anwendung nützlich sein kann, ist die Möglichkeit, Musik abrufen, die sich auf dem Gerät befindet. Fragen Sie dazu den ContentResolver nach externen Medien ab:

Kotlin

val resolver: ContentResolver = contentResolver
val uri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
val cursor: Cursor? = resolver.query(uri, null, null, null, null)
when {
    cursor == null -> {
        // query failed, handle error.
    }
    !cursor.moveToFirst() -> {
        // no media on the device
    }
    else -> {
        val titleColumn: Int = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media.TITLE)
        val idColumn: Int = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media._ID)
        do {
            val thisId = cursor.getLong(idColumn)
            val thisTitle = cursor.getString(titleColumn)
            // ...process entry...
        } while (cursor.moveToNext())
    }
}
cursor?.close()

Java

ContentResolver contentResolver = getContentResolver();
Uri uri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = contentResolver.query(uri, null, null, null, null);
if (cursor == null) {
    // query failed, handle error.
} else if (!cursor.moveToFirst()) {
    // no media on the device
} else {
    int titleColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media.TITLE);
    int idColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media._ID);
    do {
       long thisId = cursor.getLong(idColumn);
       String thisTitle = cursor.getString(titleColumn);
       // ...process entry...
    } while (cursor.moveToNext());
}

So verwenden Sie es mit dem MediaPlayer:

Kotlin

val id: Long = /* retrieve it from somewhere */
val contentUri: Uri =
    ContentUris.withAppendedId(android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id )

mediaPlayer = MediaPlayer().apply {
    setAudioAttributes(
        AudioAttributes.Builder()
            .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
            .setUsage(AudioAttributes.USAGE_MEDIA)
            .build()
    )
    setDataSource(applicationContext, contentUri)
}

// ...prepare and start...

Java

long id = /* retrieve it from somewhere */;
Uri contentUri = ContentUris.withAppendedId(
        android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id);

mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioAttributes(
    new AudioAttributes.Builder()
        .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
        .setUsage(AudioAttributes.USAGE_MEDIA)
        .build()
);
mediaPlayer.setDataSource(getApplicationContext(), contentUri);

// ...prepare and start...

Weitere Informationen

Auf diesen Seiten werden Themen zum Aufzeichnen, Speichern und Abspielen von Audio- und Videoinhalten behandelt.