Auf dieser Seite wird beschrieben, wie Sie einen DefaultPreloadManager erstellen, der Medieninhalte für Ihre App basierend auf der von Ihnen gewählten Strategie vorab lädt.
Mit Preload-Managern, die auf der abstrakten Klasse BasePreloadManager basieren, können Sie Inhalte nach den von Ihnen ausgewählten Kriterien sortieren. In diesem Dokument wird erläutert, wie Sie die abgeleitete Klasse DefaultPreloadManager verwenden, in der jede Mediendatei mit einer Ganzzahl bewertet wird, die ihre Position in einer Liste darstellt (z. B. ihre Position in einem Videokarussell). Der Preload-Manager priorisiert das Laden der Elemente danach, wie nah sie am Element sind, das der Nutzer gerade abspielt. Wenn ein Nutzer zu einem anderen Element wechselt, kann die Wiedergabe des neuen Elements sofort gestartet werden.
Eine Instanz von DefaultPreloadManager wird in drei Schritten erstellt:
- Definiere einen
TargetPreloadStatusControl, den der Preload Manager abfragen kann, um herauszufinden, ob die Mediendatei geladen werden kann und wie viel geladen werden soll. - Erstellen Sie den Builder, mit dem Sie den Preload-Manager und die
ExoPlayer-Objekte Ihrer App erstellen. - Verwenden Sie den Builder, um den Preload-Manager zu erstellen, indem Sie die Methode
build()des Builders aufrufen.
Steuerelement für den Ziel-Vorablade-Status erstellen
Wenn Sie die DefaultPreloadManager.Builder erstellen, übergeben Sie ihr ein von Ihnen definiertes Objekt zur Steuerung des Vorabladestatus. Dieses Objekt implementiert die TargetPreloadStatusControl-Schnittstelle. Wenn der Preload Manager Medien vorab laden möchte, ruft er die Methode getTargetPreloadStatus() der Statussteuerung auf, um zu bestimmen, ob Inhalte für eine Mediendatei vorbereitet, geladen oder im Cache gespeichert werden sollen. Beim Laden werden Mediendaten direkt in den In-Memory-Zwischenspeicher eines Players geladen, sodass sie sofort wiedergegeben werden können. Beim Caching werden die Mediendaten in einem nichtflüchtigen Datenträger-Cache gespeichert, um den Arbeitsspeicher des Players zu schonen. Die Statussteuerung kann einen der folgenden Statuscodes zurückgeben:
STAGE_SPECIFIED_RANGE_LOADED: Der Preload-Manager sollte den Inhalt ab der angegebenen Startposition und für die angegebene Dauer (in Millisekunden) in den In-Memory-Zwischenspeicher des Players laden.STAGE_SPECIFIED_RANGE_CACHED: Der Preload-Manager sollte den Inhalt ab der angegebenen Startposition und für die angegebene Dauer (in Millisekunden) im Datenträger-Cache speichern.STAGE_TRACKS_SELECTED: Der Preload-Manager sollte die Informationen des Inhaltstracks laden und verarbeiten und die Tracks auswählen. Der Preload-Manager sollte noch nicht mit dem Laden der Inhalte beginnen.STAGE_SOURCE_PREPARED: Der Preload-Manager sollte die Contentquelle vorbereiten. Wenn sich die Metadaten des Inhalts beispielsweise in einer separaten Manifestdatei befinden, kann der Preload Manager dieses Manifest abrufen und parsen.null: Der Preload-Manager sollte keine Inhalte oder Metadaten für diese Mediendatei laden.
Du benötigst eine Strategie, um zu entscheiden, wie viele Inhalte für die einzelnen Mediendateien geladen werden sollen. In diesem Beispiel werden mehr Inhalte für Elemente geladen, die dem aktuell wiedergegebenen Element am nächsten sind. Wenn der Nutzer Inhalte mit dem Index n wiedergibt, gibt der Controller die folgenden Codes zurück:
- Index n+1 (die nächste Mediendatei): 3.000 ms (3 Sekunden) ab der Standardstartposition laden
- Index n-1 (die vorherige Mediendatei): 1.000 ms (1 Sekunde) ab der Standardstartposition laden
- Andere Mediendateien im Bereich n-2 bis n+2: Rückgabe
PreloadStatus.TRACKS_SELECTED - Andere Mediendateien im Bereich n-4 bis n+4:
PreloadStatus.SOURCE_PREPAREDzurückgeben - Für alle anderen Mediendateien wird
nullzurückgegeben.
class MyTargetPreloadStatusControl(var currentPlayingIndex: Int = 0) : TargetPreloadStatusControl<Int, DefaultPreloadManager.PreloadStatus> { override fun getTargetPreloadStatus(index: Int): DefaultPreloadManager.PreloadStatus { if (index - currentPlayingIndex == 1) { // next track // return a PreloadStatus that is labelled by STAGE_SPECIFIED_RANGE_LOADED and // suggest loading 3000ms from the default start position return DefaultPreloadManager.PreloadStatus.specifiedRangeLoaded(3000L) } else if (index - currentPlayingIndex == -1) { // previous track // return a PreloadStatus that is labelled by STAGE_SPECIFIED_RANGE_LOADED and // suggest loading 3000ms from the default start position return DefaultPreloadManager.PreloadStatus.specifiedRangeLoaded(3000L) } else if (abs(index - currentPlayingIndex) == 2) { // return a PreloadStatus that is labelled by STAGE_TRACKS_SELECTED return DefaultPreloadManager.PreloadStatus.PRELOAD_STATUS_TRACKS_SELECTED } else if (abs(index - currentPlayingIndex) <= 4) { // return a PreloadStatus that is labelled by STAGE_SOURCE_PREPARED return DefaultPreloadManager.PreloadStatus.PRELOAD_STATUS_SOURCE_PREPARED } return DefaultPreloadManager.PreloadStatus.PRELOAD_STATUS_NOT_PRELOADED } }
Wichtige Punkte zum Code
- Wenn Sie eine Instanz von
MyTargetPreloadStatusControlerstellen, übergeben Sie sie an den PreloadManager-Builder. currentPlayingIndexenthält den Index der aktuell wiedergegebenen Mediendatei. Es ist die Aufgabe der App, diesen Wert auf dem neuesten Stand zu halten.- Wenn der Preload-Manager bereit ist, Inhalte zu laden, ruft er
getTargetPreloadStatusauf und übergibt die Ranking-Informationen, die du für die entsprechende Mediendatei angegeben hast. Im Fall vonDefaultPreloadManagerist diese Ranking-Information eine Ganzzahl, die die Position des Elements in einem Karussell angibt. Die Methode wählt den zurückzugebenden Code aus, indem sie diesen Index mit dem Index des aktuell ausgewählten Elements vergleicht.
PreloadManager erstellen
Zum Erstellen des Preload-Managers benötigen Sie einen DefaultPreloadManager.Builder.
Dieser Builder wird mit dem aktuellen Kontext und der Ziel-Preload-Statussteuerung der App konfiguriert. Sie können einen Preload-Manager mit allen Standardkonfigurationen erstellen.
val targetPreloadStatusControl = MyTargetPreloadStatusControl() val preloadManagerBuilder = DefaultPreloadManager.Builder(context, targetPreloadStatusControl) val preloadManager = preloadManagerBuilder.build()
Der Builder bietet auch Setter-Methoden, mit denen Sie die benutzerdefinierten Komponenten des Preload-Managers festlegen können.
Beispielsweise kannst du die Ziel-Gesamtpufferbytes für alle vorab geladenen Medienquellen in DefaultPreloadManager anpassen, damit die vorab geladenen Daten dieses Limit nicht überschreiten. Sie können dieses Limit mit setPlayerTargetBufferBytes(String, int) für einen benutzerdefinierten DefaultLoadControl.Builder mit dem Playernamen "preload" konfigurieren und diese Instanz an den Preload Manager Builder übergeben:
val targetPreloadStatusControl = MyTargetPreloadStatusControl() val preloadManagerBuilder = DefaultPreloadManager.Builder(context, targetPreloadStatusControl) preloadManagerBuilder.setLoadControl( DefaultLoadControl.Builder() .setPlayerTargetBufferBytes("preload", 128 * 1024 * 1024) // 128 MiB .build() ) val preloadManager = preloadManagerBuilder.build()
Die Setter-Methoden des Builders sind für die Anpassung grundsätzlich optional. Wenn du jedoch Mediendateien auf dem Laufwerk im Cache speichern möchtest, musst du den Builder mit einem Cache konfigurieren, indem du setCache() aufrufst. Wenn kein Cache konfiguriert ist, führt der Versuch, die Medieninhalte im Cache zu speichern, zu einem IllegalStateException.
ExoPlayer erstellen, um die vorab geladene Mediendatei abzuspielen
Mit dem Builder können Sie nicht nur den Preload Manager erstellen, sondern auch die ExoPlayer-Objekte, die Ihre App zum Abspielen der Inhalte verwendet. So kann der ExoPlayer Komponenten korrekt mit dem Preload Manager teilen. Du kannst die wiedergabespezifischen Konfigurationen für den ExoPlayer weiterhin festlegen, indem du eine ExoPlayer.Builder-Instanz mit diesen Konfigurationen übergibst.
// Direct creation val exoPlayer = preloadManagerBuilder.buildExoPlayer() // Creation with custom playback specific configurations val skipSilenceExoPlayerBuilder = ExoPlayer.Builder(context).setSkipSilenceEnabled(true) val skipSilenceExoPlayer = preloadManagerBuilder.buildExoPlayer(skipSilenceExoPlayerBuilder)