Einfache Mediaplayer-App mit Media3 ExoPlayer erstellen

Jetpack Media3 definiert eine Player-Schnittstelle, die grundlegende Funktionen umreißt. für die Wiedergabe von Video- und Audiodateien. ExoPlayer ist die Standardimplementierung dieser Oberfläche in Media3. Wir empfehlen die Verwendung von ExoPlayer, da es ein umfassende Funktionen, die die meisten Anwendungsfälle der Wiedergabe abdecken und anpassbar, damit Sie auch zusätzliche Anwendungsfälle bewältigen können. ExoPlayer entfernt Geräte- und Betriebssystemfragmentierung, sodass Ihr Code einheitlich funktioniert. im gesamten Android-Ökosystem. ExoPlayer enthält:

Diese Seite führt dich durch einige der wichtigsten Schritte zur Erstellung einer Wiedergabe. App. Weitere Informationen finden Sie in unseren vollständigen Leitfäden Media3 ExoPlayer:

Erste Schritte

Fügen Sie zunächst eine Abhängigkeit vom ExoPlayer, der Benutzeroberfläche und den allgemeinen Modulen von Jetpack Media3:

implementation "androidx.media3:media3-exoplayer:1.4.0"
implementation "androidx.media3:media3-ui:1.4.0"
implementation "androidx.media3:media3-common:1.4.0"

Je nach Anwendungsfall benötigen Sie möglicherweise weitere Module von Media3, wie exoplayer-dash, um Streams im DASH-Format wiederzugeben.

Ersetzen Sie 1.4.0 durch Ihre bevorzugte Version des Bibliothek. Weitere Informationen finden Sie in den Versionshinweisen. um die neueste Version zu sehen.

Mediaplayer erstellen

Bei Media3 können Sie entweder die enthaltene Implementierung der Player ExoPlayer, oder erstellen Sie Ihre eigene benutzerdefinierte Implementierung.

ExoPlayer erstellen

So erstellen Sie eine ExoPlayer-Instanz am einfachsten:

Kotlin

val player = ExoPlayer.Builder(context).build()

Java

ExoPlayer player = new ExoPlayer.Builder(context).build();

Sie können Ihren Mediaplayer in der Lebenszyklusmethode onCreate() der Activity, Fragment oder Service dort, wo sie gespeichert ist.

Die Builder umfasst eine Reihe von Anpassungsoptionen an, die Sie interessieren könnten, wie z. B.:

Media3 bietet eine PlayerView-UI-Komponente, die Sie in die Layoutdatei. Diese Komponente kapselt ein PlayerControlView für die Wiedergabe Steuerelemente, SubtitleView zum Anzeigen von Untertiteln und Surface zum Rendern Video.

Player wird vorbereitet

Medienelemente zu einer Playlist hinzufügen für mit Methoden wie setMediaItem() und addMediaItem(). Rufen Sie dann prepare() an, um Medien zu laden und die erforderlichen Ressourcen zu beschaffen.

Sie sollten diese Schritte nicht ausführen, bevor die App im Vordergrund ausgeführt wird. Wenn Ihr Spieler sich in einem Activity oder Fragment befindet, bedeutet dies, dass der Spieler im Lebenszyklusmethode onStart() auf API-Level 24 und höher oder onResume() auf API-Level 23 und niedriger angewendet. Für einen Spieler, der in einem Service ist, können Sie sie in onCreate() vorbereiten.

Player steuern

Nachdem der Player vorbereitet wurde, kannst du die Wiedergabe durch Aufrufen von Methoden steuern. im Player angezeigt, z. B.:

UI-Komponenten wie PlayerView oder PlayerControlView werden aktualisiert an einen Player gebunden.

Lasse den Player los.

Für die Wiedergabe sind möglicherweise Ressourcen erforderlich, die nur begrenzt verfügbar sind, z. B. Videos. deshalb sollten Sie release() aufrufen, für deinen Spieler, um Ressourcen freizugeben, wenn er nicht mehr benötigt wird.

Wenn sich Ihr Player in einem Activity oder Fragment befindet, lassen Sie ihn in der Lebenszyklusmethode onStop() auf API-Level 24 und höher oder onPause() auf API-Level 23 und niedriger. Für einen Spieler, der in einem Service ist, kannst du in onDestroy() veröffentlichen.

Wiedergabe mit einer Mediensitzung verwalten

Unter Android bieten Mediensitzungen eine standardisierte Möglichkeit, mit Medieninhalten zu interagieren. über Prozessgrenzen hinweg spielen. Mediensitzung mit dem Player verbinden ermöglicht es Ihnen, extern für Ihre Medienwiedergabe zu werben und Wiedergaben aus externen Quellen stammen, um beispielsweise Systemmediensteuerung auf Mobilgeräten und in großen Formaten Bildschirmgeräte.

Um Mediensitzungen zu verwenden, fügen Sie eine Abhängigkeit für das Media3-Sitzungsmodul hinzu:

implementation "androidx.media3:media3-session:1.4.0"

Mediensitzung erstellen

So kannst du nach dem Initialisieren eines Players ein MediaSession erstellen:

Kotlin

val player = ExoPlayer.Builder(context).build()
val mediaSession = MediaSession.Builder(context, player).build()

Java

ExoPlayer player = new ExoPlayer.Builder(context).build();
MediaSession mediaSession = new MediaSession.Builder(context, player).build();

Media3 synchronisiert automatisch den Status von Player mit dem Status von MediaSession. Dies funktioniert mit jeder Player-Implementierung, einschließlich ExoPlayer, CastPlayer oder ein benutzerdefinierte Implementierung.

Anderen Kunden Kontrolle gewähren

Mit Client-Apps kann ein Mediacontroller implementiert werden. um die Wiedergabe Ihrer Mediensitzung zu steuern. Um diese Anfragen zu erhalten, legen Sie einen callback-Objekt, wenn Dein MediaSession wird erstellt.

Wenn ein Controller eine Verbindung zu Ihrer Mediensitzung herstellen möchte, onConnect() aufgerufen wird. Sie können die bereitgestellte ControllerInfo verwenden um zu entscheiden, ob sie akzeptieren möchten, oder ablehnen der Anfrage. Ein Beispiel dafür findest du in der Media3 Session-Demo-App.

Sobald die Verbindung hergestellt ist, kann ein Controller Wiedergabebefehle an die Sitzung senden. Die und delegiert diese Befehle an den Player. Wiedergabe und Playlist Befehle, die in der Player-Schnittstelle definiert sind, werden automatisch vom Sitzung.

Mit anderen Callback-Methoden können Sie zum Beispiel Anfragen für benutzerdefinierte Wiedergabebefehle und die Playlist zu ändern. Diese Callbacks enthalten ähnlich ein ControllerInfo-Objekt, sodass Sie die Zugriffssteuerung für jede Anfrage einzeln festlegen.

Wiedergabe von Medien im Hintergrund

Wenn Sie die Medienwiedergabe fortsetzen möchten, wenn Ihre App nicht im Vordergrund ausgeführt wird, z. B. Musik, Hörbücher oder Podcasts auch dann abzuspielen, wenn der Nutzer deine App nicht hat nicht öffnen, sollten Player und MediaSession in einem Dienst im Vordergrund. Media3 bietet die MediaSessionService-Schnittstelle zu diesem Zweck verwenden.

MediaSessionService implementieren

Erstellen Sie eine Klasse, die MediaSessionService erweitert, und instanziieren Sie Ihre MediaSession in der Lebenszyklusmethode onCreate().

Kotlin

class PlaybackService : MediaSessionService() {
    private var mediaSession: MediaSession? = null

    // Create your Player and MediaSession in the onCreate lifecycle event
    override fun onCreate() {
        super.onCreate()
        val player = ExoPlayer.Builder(this).build()
        mediaSession = MediaSession.Builder(this, player).build()
    }

    // Remember to release the player and media session in onDestroy
    override fun onDestroy() {
        mediaSession?.run {
            player.release()
            release()
            mediaSession = null
        }
        super.onDestroy()
    }
}

Java

public class PlaybackService extends MediaSessionService {
    private MediaSession mediaSession = null;

    @Override
    public void onCreate() {
        super.onCreate();
        ExoPlayer player = new ExoPlayer.Builder(this).build();
        mediaSession = new MediaSession.Builder(this, player).build();
    }

    @Override
    public void onDestroy() {
        mediaSession.getPlayer().release();
        mediaSession.release();
        mediaSession = null;
        super.onDestroy();
    }
}

In Ihrem Manifest ist Ihre Service-Klasse mit dem Intent MediaSessionService Filtern und fordern Sie die Berechtigung FOREGROUND_SERVICE an, um einen Vordergrund auszuführen Dienst:

<service
    android:name=".PlaybackService"
    android:foregroundServiceType="mediaPlayback"
    android:exported="true">
    <intent-filter>
        <action android:name="androidx.media3.session.MediaSessionService"/>
    </intent-filter>
</service>

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

Überschreiben Sie schließlich in der von Ihnen erstellten Klasse die Methode onGetSession(), um Clientzugriff auf Ihre Mediensitzung. MediaSession zurückgeben, um die Verbindungsanfrage an oder geben Sie null zurück, um die Anfrage abzulehnen.

Kotlin

// This example always accepts the connection request
override fun onGetSession(
    controllerInfo: MediaSession.ControllerInfo
): MediaSession? = mediaSession

Java

@Override
public MediaSession onGetSession(MediaSession.ControllerInfo controllerInfo) {
  // This example always accepts the connection request
  return mediaSession;
}

Verbindung zur Benutzeroberfläche wird hergestellt

Da sich Ihre Mediensitzung nun in einer Service befindet, die vom Activity- oder Fragment, wo sich deine Spieler-UI befindet, kannst du MediaController zum Verknüpfen verwenden. miteinander verbinden. In der Methode onStart() der Activity oder Fragment mit der Benutzeroberfläche, erstelle ein SessionToken für MediaSession und verwende dann das SessionToken um eine MediaController zu erstellen. MediaController wird erstellt asynchron programmiert.

Kotlin

override fun onStart() {
  val sessionToken = SessionToken(this, ComponentName(this, PlaybackService::class.java))
  val controllerFuture = MediaController.Builder(this, sessionToken).buildAsync()
  controllerFuture.addListener(
    {
        // Call controllerFuture.get() to retrieve the MediaController.
        // MediaController implements the Player interface, so it can be
        // attached to the PlayerView UI component.
        playerView.setPlayer(controllerFuture.get())
      },
    MoreExecutors.directExecutor()
  )
}

Java

@Override
public void onStart() {
  SessionToken sessionToken =
    new SessionToken(this, new ComponentName(this, PlaybackService.class));
  ListenableFuture<MediaController> controllerFuture =
    new MediaController.Builder(this, sessionToken).buildAsync();
  controllerFuture.addListener(() -> {
    // Call controllerFuture.get() to retrieve the MediaController.
    // MediaController implements the Player interface, so it can be
    // attached to the PlayerView UI component.
    playerView.setPlayer(controllerFuture.get());
  }, MoreExecutors.directExecutor())
}

MediaController implementiert die Player-Schnittstelle, sodass Sie dasselbe wie play() und pause() zur Steuerung der Wiedergabe verwenden. Ähnlich wie andere Komponenten hinzufügen, denken Sie daran, das MediaController freizugeben, wenn es nicht mehr wie z. B. die Lebenszyklusmethode onStop() eines Activity durch den Aufruf von MediaController.releaseFuture()

Benachrichtigungen veröffentlichen

Dienste im Vordergrund sind erforderlich, um eine Benachrichtigung zu veröffentlichen, wenn sie aktiv sind. A MediaSessionService erstellt automatisch einen MediaStyle-Benachrichtigung für Sie in Form eines MediaNotification. Wenn du eine benutzerdefinierte Benachrichtigung senden möchtest, erstelle eine MediaNotification.Provider mit DefaultMediaNotificationProvider.Builder oder durch Erstellen einer benutzerdefinierten Implementierung der Anbieterschnittstelle. Fügen Sie Ihr auf MediaSession mit setMediaNotificationProvider

Werbung für deine Inhaltsbibliothek

Ein MediaLibraryService baut auf einem MediaSessionService auf, indem es dem Client erlaubt, Apps, um die von Ihrer App bereitgestellten Medieninhalte zu durchsuchen. Client-Apps implementieren ein MediaBrowser zum Interagieren mit deinem MediaLibraryService.

Die Implementierung eines MediaLibraryService ähnelt der Implementierung eines MediaSessionService, mit dem Unterschied, dass in onGetSession() ein MediaLibrarySession statt MediaSession. Im Vergleich zu einer MediaSession.Callback, MediaLibrarySession.Callback enthält zusätzliche -Methoden, mit denen ein Browser-Client durch die von Ihrer Website angebotenen Bibliotheksdienst.

Ähnlich wie bei der MediaSessionService deklarieren Sie die MediaLibraryService in Ihrem Manifest und die Berechtigung FOREGROUND_SERVICE anfordern, um einen Vordergrund auszuführen Dienst:

<service
    android:name=".PlaybackService"
    android:foregroundServiceType="mediaPlayback"
    android:exported="true">
    <intent-filter>
        <action android:name="androidx.media3.session.MediaLibraryService"/>
        <action android:name="android.media.browse.MediaBrowserService"/>
    </intent-filter>
</service>

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

Das Beispiel oben enthält einen Intent-Filter für MediaLibraryService und aus Gründen der Abwärtskompatibilität den alten MediaBrowserService. Die Der zusätzliche Intent-Filter aktiviert Client-Apps, die die MediaBrowserCompat API verwenden Service zu erkennen.

Mit einem MediaLibrarySession können Sie Ihre Inhaltsbibliothek in einer Struktur bereitstellen. -Struktur mit einer einzigen Stamm-MediaItem an. Jeder MediaItem in der Baumstruktur kann beliebig viele untergeordnete MediaItem-Knoten. Sie können eine andere Stamm- oder eine basierend auf der Anfrage der Client-App. Zum Beispiel der Baum, den Sie wenn sie zu einem Kunden zurückkehren, der nach einer Liste mit empfohlenen Medienelementen sucht, den Stamm MediaItem und eine einzelne Ebene von untergeordneten MediaItem-Knoten enthalten, Die Baumstruktur, die Sie zu einer anderen Client-App zurückgeben, kann dagegen der gesamten Inhaltsbibliothek.

MediaLibrarySession wird erstellt

MediaLibrarySession erweitert die MediaSession API um APIs zum Durchsuchen von Inhalten. Im Vergleich zu den MediaSession-Callback, MediaLibrarySession-Callback fügt Methoden hinzu wie:

  • onGetLibraryRoot() Für wenn ein Client den MediaItem-Stamm einer Inhaltsstruktur anfordert
  • onGetChildren() Für wenn ein Client die untergeordneten Elemente von MediaItem in der Inhaltsstruktur anfordert
  • onGetSearchResult() wenn ein Client Suchergebnisse aus der Inhaltsstruktur für eine bestimmte Suchanfrage

Relevante Callback-Methoden sind LibraryParams. Objekt mit zusätzlichen Signalen zum Typ der Inhaltsstruktur, die eine Client-App interessiert.