Anleitungen

High-Speed-Aufnahme und Zeitlupenvideo mit CameraX 1.5

Lesezeit: 6 Minuten
Leo Huang
Softwareentwickler

Schnelle Bewegungen klar aufzunehmen, ist eine wichtige Funktion moderner Kamera-Apps. Das wird durch High-Speed-Aufnahmen erreicht, bei denen Bilder mit einer Bildrate von 120 oder 240 fps aufgenommen werden. Diese Aufnahme mit hoher Wiedergabetreue kann für zwei verschiedene Zwecke verwendet werden: zum Erstellen eines Videos mit hoher Bildrate für detaillierte Analysen Frame für Frame oder zum Erstellen eines Zeitlupenvideos, in dem die Action auf dem Bildschirm dramatisch dargestellt wird.

Bisher war die Implementierung dieser Funktionen mit der Camera2 API ein aufwendigerer Prozess. Mit der neuen High-Speed-API in CameraX 1.5 wird der gesamte Prozess vereinfacht. Sie können entweder Videos mit hoher Bildrate oder Slow-Motion-Clips erstellen. In diesem Beitrag erfahren Sie, wie Sie beides meistern. Wenn Sie noch nicht mit CameraX vertraut sind, können Sie sich in der CameraX-Übersicht informieren.


Das Prinzip hinter der Zeitlupe

Das Grundprinzip der Zeitlupe besteht darin, Videos mit einer viel höheren Framerate aufzunehmen, als sie wiedergegeben werden. Wenn Sie beispielsweise ein Ereignis von einer Sekunde mit 120 Bildern pro Sekunde (fps) aufzeichnen und die Aufnahme dann mit den standardmäßigen 30 fps wiedergeben, dauert die Wiedergabe des Videos vier Sekunden. Durch diese „Dehnung“ der Zeit entsteht der dramatische Zeitlupeneffekt, der es dir ermöglicht, Details zu sehen, die für das bloße Auge zu schnell sind.

Damit das endgültige Ausgabevideo flüssig wiedergegeben wird, sollte es in der Regel mit mindestens 30 fps gerendert werden. Das bedeutet, dass die ursprüngliche Aufnahmerate mindestens 120 fps betragen muss, um ein Video in 4‑facher Zeitlupe zu erstellen (120 fps ÷ 4 = 30 fps).

Nachdem das Material mit hoher Bildrate aufgenommen wurde, gibt es zwei primäre Möglichkeiten, das gewünschte Ergebnis zu erzielen:

  • Vom Nutzer gesteuerte Zeitlupe (Video mit hoher Framerate): Die Hochgeschwindigkeitsaufnahme (z.B. 120 fps) wird direkt als Videodatei mit hoher Framerate gespeichert. Der Videoplayer ist dann dafür verantwortlich, die Wiedergabegeschwindigkeit zu verlangsamen. So kann der Nutzer flexibel zwischen normaler und Zeitlupenwiedergabe wechseln.
  • Wiedergabebereite Zeitlupe (neu codiertes Video): Der High-Speed-Videostream wird verarbeitet und in eine Datei mit einer Standard-Bildrate (z.B. 30 fps) neu codiert. Der Zeitlupeneffekt wird durch Anpassen der Frame-Zeitstempel „eingebaut“. Das resultierende Video wird in jedem Standardvideoplayer ohne besondere Bearbeitung in Zeitlupe abgespielt. Das Video wird standardmäßig in Zeitlupe wiedergegeben. Videoplayer können jedoch weiterhin Steuerelemente für die Wiedergabegeschwindigkeit bereitstellen, mit denen der Nutzer die Geschwindigkeit erhöhen und das Video in der Originalgeschwindigkeit ansehen kann.

Die CameraX API vereinfacht dies, da Sie einheitlich auswählen können, welchen Ansatz Sie verwenden möchten.


Die neue High-Speed Video API

Die neue CameraX-Lösung basiert auf zwei Hauptkomponenten:

  • Recorder#getHighSpeedVideoCapabilities(CameraInfo): Mit dieser Methode können Sie prüfen, ob die Kamera mit hoher Geschwindigkeit aufzeichnen kann und, falls ja, welche Auflösungen (Quality-Objekte) unterstützt werden.
  • HighSpeedVideoSessionConfig: Dies ist ein spezielles Konfigurationsobjekt, das Ihre Anwendungsfälle VideoCapture und Preview gruppiert und CameraX anweist, eine einheitliche High-Speed-Kamerasitzung zu erstellen. Der VideoCapture-Stream wird mit der konfigurierten hohen Framerate ausgeführt, der Preview-Stream wird jedoch in der Regel vom Kamerasystem auf eine Standardrate von mindestens 30 Bilder pro Sekunde begrenzt, um eine flüssige Darstellung auf dem Bildschirm zu gewährleisten.

Erste Schritte

Bevor Sie beginnen, müssen Sie der build.gradle.kts-Datei Ihrer App die erforderlichen CameraX-Abhängigkeiten hinzufügen. Sie benötigen das camera-video-Artefakt zusammen mit den CameraX-Kernbibliotheken.

// build.gradle.kts (Module: app)

dependencies {

    val camerax_version = "1.5.1"


    implementation("androidx.camera:camera-core:$camerax_version")

    implementation("androidx.camera:camera-camera2:$camerax_version")

    implementation("androidx.camera:camera-lifecycle:$camerax_version")

    implementation("androidx.camera:camera-video:$camerax_version")

    implementation("androidx.camera:camera-view:$camerax_version")

}

Hinweis zu experimentellen APIs

Es ist wichtig zu beachten, dass die APIs für Hochgeschwindigkeitsaufnahmen derzeit experimentell sind. Das bedeutet, dass sie sich in zukünftigen Releases ändern können. Wenn Sie sie verwenden möchten, müssen Sie sie aktivieren, indem Sie Ihrem Code die folgende Annotation hinzufügen:

@kotlin.OptIn(ExperimentalSessionConfig::class, ExperimentalHighSpeedVideo::class)

Implementierung

Die Implementierung für beide Ergebnisse beginnt mit denselben Einrichtungsschritten. Die Entscheidung, ob Sie ein Video mit hoher Bildrate oder ein Zeitlupenvideo erstellen möchten, hängt von einer einzigen Einstellung ab.

1. High-Speed Capture einrichten

Unabhängig von Ihrem Ziel müssen Sie zuerst die ProcessCameraProvider abrufen, die Gerätefunktionen prüfen und Ihre Anwendungsfälle erstellen.

Der folgende Codeblock zeigt den vollständigen Einrichtungsvorgang in einer suspend-Funktion. Sie können diese Funktion aus einem Coroutine-Bereich wie lifecycleScope.launch aufrufen.

// Add the OptIn annotation at the top of your function or class

@kotlin.OptIn(ExperimentalSessionConfig::class, ExperimentalHighSpeedVideo::class)

private suspend fun setupCamera() {

    // Asynchronously get the CameraProvider

    val cameraProvider = ProcessCameraProvider.awaitInstance(this)



    // -- CHECK CAPABILITIES --

    val cameraInfo = cameraProvider.getCameraInfo(CameraSelector.DEFAULT_BACK_CAMERA)

    val videoCapabilities = Recorder.getHighSpeedVideoCapabilities(cameraInfo)

    if (videoCapabilities == null) {

        // This camera device does not support high-speed video.

        return

    }




    // -- CREATE USE CASES --

    val preview = Preview.Builder().build()    


    // You can create a Recorder with default settings.

    // CameraX will automatically select a suitable quality.

    val recorder = Recorder.Builder().build()


    // Alternatively, to use a specific resolution, you can configure the
    // Recorder with a QualitySelector. This is useful if your app has
    // specific resolution requirements or you want to offer user
    // preferences. 

    // To use a specific quality, you can uncomment the following lines.

    // Get the list of qualities supported for high-speed video. 

    // val supportedQualities = videoCapabilities.getSupportedQualities(DynamicRange.SDR)

    // Build the Recorder using the quality from the supported list.

    // val recorderWithQuality = Recorder.Builder()

    //     .setQualitySelector(QualitySelector.from(supportedQualities.first()))

    //     .build()



    // Create the VideoCapture use case, using either recorder or recorderWithQuality

    val videoCapture = VideoCapture.withOutput(recorder)

    // Now you are ready to configure the session for your desired output...

}

2. Ausgabe auswählen

Jetzt müssen Sie entscheiden, welche Art von Video Sie erstellen möchten. Dieser Code würde in der oben gezeigten Funktion setupCamera() suspend ausgeführt.

Option A: Video mit hoher Framerate erstellen

Wählen Sie diese Option aus, wenn die endgültige Datei eine hohe Framerate haben soll (z.B. ein Video mit 120 fps).

// Create a builder for the high-speed session

val sessionConfigBuilder = HighSpeedVideoSessionConfig.Builder(videoCapture)

    .setPreview(preview)


// Query and apply a supported frame rate. Common supported frame rates include 120 and 240 fps.

val supportedFrameRateRanges =

    cameraInfo.getSupportedFrameRateRanges(sessionConfigBuilder.build())


sessionConfigBuilder.setFrameRateRange(supportedFrameRateRanges.first())

Option B: Zeitlupenvideo erstellen, das direkt abgespielt werden kann

Wählen Sie diese Option aus, wenn Sie ein Video möchten, das in jedem Standardvideoplayer automatisch in Zeitlupe wiedergegeben wird.

// Create a builder for the high-speed session

val sessionConfigBuilder = HighSpeedVideoSessionConfig.Builder(videoCapture)

    .setPreview(preview)



// This is the key: enable automatic slow-motion!

sessionConfigBuilder.setSlowMotionEnabled(true)



// Query and apply a supported frame rate. Common supported frame rates include 120, 240, and 480 fps.

val supportedFrameRateRanges =

   cameraInfo.getSupportedFrameRateRanges(sessionConfigBuilder.build())

sessionConfigBuilder.setFrameRateRange(supportedFrameRateRanges.first())

Diese einzelne Markierung ist der Schlüssel zum Erstellen eines abspielbereiten Zeitlupenvideos. Wenn setSlowMotionEnabled „true“ ist, verarbeitet CameraX den High-Speed-Stream und speichert ihn als Standardvideodatei mit 30 fps. Die Zeitlupengeschwindigkeit wird durch das Verhältnis zwischen der Aufnahmebildrate und dieser Standardwiedergabegeschwindigkeit bestimmt.

Beispiel:

  • Bei einer Aufnahme mit 120 fps wird ein Video erstellt, das mit 1/4-facher Geschwindigkeit wiedergegeben wird (120 ÷ 30 = 4).
  • Bei einer Aufnahme mit 240 fps wird ein Video mit einer Wiedergabegeschwindigkeit von 1/8x erstellt (240 ÷ 30 = 8).

Das Gesamtbild: Video aufnehmen

Nachdem Sie HighSpeedVideoSessionConfig konfiguriert und an den Lebenszyklus gebunden haben, müssen Sie nur noch die Aufzeichnung starten. Das Vorbereiten von Ausgabeoptionen, das Starten der Aufnahme und die Verarbeitung von Videoereignissen erfolgt genauso wie bei einer Standardvideoaufnahme.

In diesem Beitrag geht es hauptsächlich um die Konfiguration für hohe Geschwindigkeiten. Daher wird der Aufzeichnungsprozess nicht im Detail behandelt. Einen umfassenden Leitfaden zu allen Themen, von der Vorbereitung eines FileOutputOptions- oder MediaStoreOutputOptions-Objekts bis hin zur Verarbeitung der VideoRecordEvent-Callbacks, finden Sie in der VideoCapture-Dokumentation.

// Bind the session config to the lifecycle

cameraProvider.bindToLifecycle(

    this as LifecycleOwner,

    CameraSelector.DEFAULT_BACK_CAMERA,

    sessionConfigBuilder.build() // Bind the config object from Option A or B

)



// Start the recording using the VideoCapture use case

val recording = videoCapture.output

    .prepareRecording(context, outputOptions) // See docs for creating outputOptions

    .start(ContextCompat.getMainExecutor(context)) { recordEvent ->

        // Handle recording events (e.g., Start, Pause, Finalize)

    }

Unterstützung von Zeitlupenvideos in Google Fotos

Wenn Sie setSlowMotionEnabled(true) in CameraX aktivieren, ist die resultierende Videodatei so konzipiert, dass sie in Standardvideoplayern und Galerie-Apps sofort als Zeitlupe erkannt und wiedergegeben werden kann. Google Fotos bietet insbesondere für Zeitlupenvideos mit einer Aufnahme-Framerate von 120, 240, 360, 480 oder 960 fps erweiterte Funktionen:

  • Unterscheidung von normalen Videos durch Benutzeroberflächenelemente in der Miniaturansicht:In Ihrer Google Fotos-Galerie können Sie Zeitlupenvideos anhand bestimmter Benutzeroberflächenelemente erkennen.
normal.png
slowmotion.png
Normales Video-ThumbnailThumbnail für Zeitlupenvideo
  • Anpassbare Geschwindigkeitssegmente bei der Wiedergabe:Wenn Sie ein Zeitlupenvideo abspielen, bietet Google Fotos Steuerelemente, mit denen Sie anpassen können, welche Teile des Videos in Zeitlupe und welche in normaler Geschwindigkeit wiedergegeben werden. So haben Sie mehr kreative Kontrolle. Das bearbeitete Video kann dann über die Schaltfläche Teilen als neue Videodatei exportiert werden. Die von Ihnen definierten Zeitlupensegmente bleiben dabei erhalten.
normal2.png
slowmotion2.png
Normale VideowiedergabeWiedergabe von Zeitlupenvideos 
mit Bearbeitungsfunktionen 

Hinweis zur Geräteunterstützung

Die High-Speed-API von CameraX basiert auf dem zugrunde liegenden Android-System CamcorderProfile, um zu ermitteln, welche High-Speed-Auflösungen und ‑Bildraten ein Gerät unterstützt. CamcorderProfiles werden von der Android Compatibility Test Suite (CTS) validiert. Sie können sich also auf die angegebenen Videofunktionen des Geräts verlassen.

Das bedeutet, dass die Möglichkeit eines Geräts, mit der integrierten Kamera-App Zeitlupenvideos aufzunehmen, nicht garantiert, dass die CameraX-High-Speed-API funktioniert. Diese Diskrepanz entsteht, weil Gerätehersteller für das Ausfüllen der CamcorderProfile-Einträge in der Firmware ihrer Geräte verantwortlich sind und manchmal erforderliche High-Speed-Profile wie CamcorderProfile.QUALITY_HIGH_SPEED_1080P und CamcorderProfile.QUALITY_HIGH_SPEED_720P nicht enthalten sind. Wenn diese Profile fehlen, gibt Recorder.getHighSpeedVideoCapabilities() den Wert null zurück.

Daher ist es wichtig, immer Recorder.getHighSpeedVideoCapabilities() zu verwenden, um programmatisch nach unterstützten Funktionen zu suchen. So lässt sich am zuverlässigsten eine einheitliche Nutzererfahrung auf verschiedenen Geräten gewährleisten. Wenn Sie versuchen, ein HighSpeedVideoSessionConfig auf einem Gerät zu binden, auf dem Recorder.getHighSpeedVideoCapabilities() „null“ zurückgibt, schlägt der Vorgang mit einem IllegalArgumentException fehl. Google Pixel-Geräte unterstützen diese Hochgeschwindigkeitsprofile in der Regel. Außerdem unterstützen verschiedene Geräte anderer Hersteller, z. B. das Motorola Edge 30, das OPPO Find N2 Flip und das Sony Xperia 1 V, die High-Speed-Videofunktionen.


Fazit

Die CameraX-API für High-Speed-Videos ist leistungsstark und flexibel. Ob Sie Aufnahmen mit hoher Bildrate für technische Analysen benötigen oder Ihrer App filmische Zeitlupeneffekte hinzufügen möchten – die HighSpeedVideoSessionConfig bietet eine einheitliche und einfache Lösung. Wenn Sie die Rolle des setSlowMotionEnabled-Flags verstehen, können Sie beide Anwendungsfälle problemlos unterstützen und Ihren Nutzern mehr kreative Kontrolle geben.

Verfasst von:

Weiterlesen