Videoframes extrahieren

Die Klasse FrameExtractor bietet eine effiziente Möglichkeit, decodierte Frames aus einem MediaItem zu extrahieren.

Zu den häufigsten Anwendungsfällen gehören:

  • Thumbnails generieren: Hochwertige Thumbnails für eine Videogalerie oder Fortschrittsanzeige erstellen.
  • Vorschau für die Videobearbeitung: In der Zeitachse eines Editors werden präzise Frame-Vorschauen angezeigt, sodass Nutzer durch den Inhalt scrollen und Frames genau visualisieren können.
  • Transformationen anwenden, z. B. Skalieren, Zuschneiden oder Drehen, direkt während des Extrahierens, um einen separaten Nachbearbeitungsschritt zu vermeiden.
  • Inhaltsanalyse: Extrahieren von Frames in bestimmten Intervallen, um sie an eine Analyse-Pipeline für Aufgaben wie Szenenerkennung, Objekterkennung oder Qualitätskontrolle zu senden.

Übersicht

Die Verwendung von FrameExtractor erfolgt in zwei Schritten:

  1. Extraktor erstellen: Erstellen Sie eine Instanz mit FrameExtractor.Builder. Übergeben Sie eine Context und die MediaItem, die Sie prüfen möchten, an den Builder. Sie können auch Konfigurationsmethoden für Builder verketten, um erweiterte Einstellungen zu konfigurieren.
  2. Frames extrahieren: Rufen Sie getFrame() auf, um einen Frame zu einem bestimmten Zeitstempel zu extrahieren, oder getThumbnail(), um ein repräsentatives Thumbnail anzufordern. Diese Methoden sind asynchron und geben ein ListenableFuture zurück. Daher wird der Hauptthread nicht durch die komplexe Decodierungsarbeit blockiert.

Kotlin

suspend fun extractFrame(context: Context, mediaItem: MediaItem) {
    try {
        // 1. Build the frame extractor.
        // `FrameExtractor` implements `AutoCloseable`, so wrap it in
        // a Kotlin `.use` block, which calls `close()` automatically.
        FrameExtractor.Builder(context, mediaItem).build().use { extractor ->
            // 2. Extract frames asynchronously.
            val frame = extractor.getFrame(5000L).await()
            val thumbnail = extractor.thumbnail.await()
            handleFrame(frame, thumbnail)
        }
    } catch (e: Exception) {
        Log.e(TAG, "Exception: $e")
    }
}

Java

public void extractFrame(Context context, MediaItem mediaItem) {
    // 1. Build the frame extractor.
    // `FrameExtractor` implements `AutoCloseable`, so use try-with-resources
    // so that the resources are automatically released.
    try (FrameExtractor frameExtractor = new FrameExtractor.Builder(context, mediaItem).build()) {
        // 2. Extract frames asynchronously.
        ListenableFuture<FrameExtractor.Frame> frameFuture = frameExtractor.getFrame(5000L);
        ListenableFuture<FrameExtractor.Frame> thumbnailFuture = frameExtractor.getThumbnail();

        ListenableFuture<List<Object>> allFutures = Futures.allAsList(frameFuture, thumbnailFuture);
        Futures.addCallback(allFutures, new FutureCallback<>() {
            @Override
            public void onSuccess(List<Object> result) {
                handleFrame(Futures.getUnchecked(frameFuture), Futures.getUnchecked(thumbnailFuture));
            }

            @Override
            public void onFailure(@NonNull Throwable t) {
                handleFailure(t);
            }
        }, MoreExecutors.directExecutor());
    }
}