Guide pratiche

Acquisizione ad alta velocità e video in slow motion con CameraX 1.5

6 minuti di lettura
Leo Huang
Ingegnere del software

L'acquisizione di azioni in rapido movimento con chiarezza è una funzionalità chiave per le moderne app per fotocamere. Questo risultato si ottiene tramite l'acquisizione ad alta velocità, ovvero il processo di acquisizione di frame a velocità come 120 o 240 fps. Questa acquisizione ad alta fedeltà può essere utilizzata per due scopi distinti: creare un video ad alta frequenza fotogrammi per un'analisi dettagliata frame per frame o generare un video in slow motion in cui l'azione si svolge in modo drammatico sullo schermo.

In precedenza, l'implementazione di queste funzionalità con l'API Camera2 era un processo più pratico. Ora, con la nuova API ad alta velocità in CameraX 1.5, l'intero processo è semplificato, offrendoti la flessibilità di creare video ad alta frequenza fotogrammi o clip in slow motion pronti per la riproduzione. Questo post ti mostrerà come padroneggiare entrambi. Se non hai familiarità con CameraX, puoi consultare la Panoramica di CameraX.


Il principio alla base dello slow motion

Il principio fondamentale dello slow motion è acquisire video a una frequenza fotogrammi molto più alta di quella di riproduzione. Ad esempio, se registri un evento di un secondo a 120 frame al secondo (fps) e poi riproduci la registrazione a 30 fps standard, il video impiegherà quattro secondi per essere riprodotto. Questo "allungamento" del tempo crea l'effetto drammatico dello slow motion, che ti consente di vedere dettagli troppo veloci per l'occhio umano.

Per garantire che il video di output finale sia fluido, in genere deve essere sottoposto a rendering a un minimo di 30 fps. Ciò significa che per creare un video in slow motion 4x, la frequenza fotogrammi di acquisizione originale deve essere di almeno 120 fps (120 fps di acquisizione ÷ 4 = 30 fps di riproduzione).

Una volta acquisito il filmato ad alta frequenza fotogrammi, esistono due modi principali per ottenere il risultato desiderato:

  • Slow motion gestito dal player (video ad alta frequenza fotogrammi): la registrazione ad alta velocità (ad es. 120 fps) viene salvata direttamente come file video ad alta frequenza fotogrammi. Il player video ha quindi la responsabilità di rallentare la velocità di riproduzione. In questo modo, l'utente può passare dalla riproduzione normale a quella in slow motion.
  • Slow motion pronto per la riproduzione (video ricodificato): lo stream video ad alta velocità viene elaborato e ricodificato in un file con una frequenza fotogrammi standard (ad es. 30 fps). L'effetto slow motion viene "incorporato" regolando i timestamp dei frame. Il video risultante verrà riprodotto in slow motion in qualsiasi player video standard senza una gestione speciale. Anche se il video viene riprodotto in slow motion per impostazione predefinita, i player video possono comunque fornire controlli della velocità di riproduzione che consentono all'utente di aumentare la velocità e guardare il video alla velocità originale.

L'API CameraX semplifica questa operazione offrendoti un modo unificato per scegliere l'approccio che preferisci, come vedrai di seguito.


La nuova API video ad alta velocità

La nuova soluzione CameraX si basa su due componenti principali:

  • Recorder#getHighSpeedVideoCapabilities(CameraInfo): questo metodo ti consente di verificare se la fotocamera può registrare ad alta velocità e, in caso affermativo, quali risoluzioni (oggetti Quality) sono supportate.
  • HighSpeedVideoSessionConfig: si tratta di un oggetto di configurazione speciale che raggruppa i casi d'uso VideoCapture e Preview, indicando a CameraX di creare una sessione di fotocamera ad alta velocità unificata. Tieni presente che, sebbene lo stream VideoCapture funzioni alla frequenza fotogrammi elevata configurata, lo stream di anteprima in genere è limitato a una frequenza standard di almeno 30 FPS dal sistema della fotocamera per garantire una visualizzazione fluida sullo schermo.

Per iniziare

Prima di iniziare, assicurati di aver aggiunto le dipendenze CameraX necessarie al file build.gradle.kts dell'app. Avrai bisogno dell'artefatto camera-video insieme alle librerie CameraX principali.

  // 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")

}

Una nota sulle API sperimentali

È importante notare che le API di registrazione ad alta velocità sono attualmente sperimentali. Ciò significa che sono soggette a modifiche nelle release future. Per utilizzarle, devi attivare l'opzione aggiungendo la seguente annotazione al codice:

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

Implementazione

L'implementazione per entrambi i risultati inizia con gli stessi passaggi di configurazione. La scelta tra la creazione di un video ad alta frequenza fotogrammi o di un video in slow motion dipende da una singola impostazione.

1. Configura l'acquisizione ad alta velocità

Innanzitutto, indipendentemente dall'obiettivo, devi ottenere ProcessCameraProvider, verificare le funzionalità del dispositivo e creare i casi d'uso.

Il seguente blocco di codice mostra il flusso di configurazione completo all'interno di una funzione di sospensione. Puoi chiamare questa funzione da un ambito di coroutine, ad esempio lifecycleScope.launch.

  // 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. Scegli l'output

Ora decidi il tipo di video che vuoi creare. Questo codice verrà eseguito all'interno della funzione setupCamera() suspend mostrata sopra.

Opzione A: crea un video ad alta frequenza fotogrammi

Scegli questa opzione se vuoi che il file finale abbia una frequenza fotogrammi elevata (ad es. un video a 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())

Opzione B: crea un video in slow motion pronto per la riproduzione

Scegli questa opzione se vuoi un video che venga riprodotto automaticamente in slow motion in qualsiasi player video standard.

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

Questo singolo flag è la chiave per creare un video in slow motion pronto per la riproduzione. Quando setSlowMotionEnabled è true, CameraX elabora lo stream ad alta velocità e lo salva come file video standard a 30 fps. La velocità dello slow motion è determinata dal rapporto tra la frequenza fotogrammi di acquisizione e questa velocità di riproduzione standard.

Ad esempio:

  • La registrazione a 120 fps produrrà un video che verrà riprodotto a 1/4 della velocità (120 ÷ 30 = 4).
  • La registrazione a 240 fps produrrà un video che verrà riprodotto a 1/8 della velocità (240 ÷ 30 = 8).

Metti tutto insieme: registra il video

Dopo aver configurato HighSpeedVideoSessionConfig e averlo associato al ciclo di vita, l'ultimo passaggio consiste nell'avviare la registrazione. La procedura di preparazione delle opzioni di output, avvio della registrazione e gestione degli eventi video è la stessa della registrazione video standard.

Questo post si concentra sulla configurazione ad alta velocità, quindi non tratteremo in dettaglio la procedura di registrazione. Per una guida completa su tutto, dalla preparazione di un oggetto FileOutputOptions o MediaStoreOutputOptions alla gestione dei callback VideoRecordEvent, consulta la documentazione di VideoCapture.

  // 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)

    }

Supporto di Google Foto per i video in slow motion

Quando abiliti setSlowMotionEnabled(true) in CameraX, il file video risultante è progettato per essere immediatamente riconoscibile e riproducibile in slow motion nei player video standard e nelle app Galleria. Google Foto, in particolare, offre funzionalità avanzate per questi video in slow motion, quando la frequenza fotogrammi di acquisizione è 120, 240, 360, 480 o 960 fps:

  • Riconoscimento dell'interfaccia utente distinta nella miniatura: nella raccolta di Google Foto, i video in slow motion possono essere identificati da elementi specifici dell'interfaccia utente, che li distinguono dai video normali.
normal.png
  • Segmenti di velocità regolabili durante la riproduzione: quando riproduce un video in slow motion, Google Foto fornisce controlli per regolare le parti del video che vengono riprodotte a velocità ridotta e quelle che vengono riprodotte a velocità normale, offrendo agli utenti un controllo creativo. Il video modificato può essere esportato come nuovo file video utilizzando il pulsante Condividi, mantenendo i segmenti in slow motion definiti.
normal2.png

Una nota sul supporto dei dispositivi

L'API ad alta velocità di CameraX si basa sul sistema CamcorderProfile di Android sottostante per determinare quali risoluzioni e frequenze fotogrammi ad alta velocità sono supportate da un dispositivo. I CamcorderProfile vengono convalidati dalla Compatibility Test Suite (CTS) di Android, il che significa che puoi avere fiducia nelle funzionalità di registrazione video segnalate dal dispositivo.

Ciò significa che la capacità di un dispositivo di registrare video in slow motion con la sua app per fotocamere integrata non garantisce il funzionamento dell'API ad alta velocità di CameraX. Questa discrepanza si verifica perché i produttori di dispositivi sono responsabili del riempimento delle voci CamcorderProfile nel firmware del dispositivo e a volte non sono inclusi i profili ad alta velocità necessari, come CamcorderProfile.QUALITY_HIGH_SPEED_1080P e CamcorderProfile.QUALITY_HIGH_SPEED_720P. Quando questi profili non sono presenti, Recorder.getHighSpeedVideoCapabilities() restituisce null.

Pertanto, è essenziale utilizzare sempre Recorder.getHighSpeedVideoCapabilities() per verificare a livello di programmazione le funzionalità supportate, in quanto questo è il modo più affidabile per garantire un'esperienza coerente su diversi dispositivi. Se provi ad associare un HighSpeedVideoSessionConfig su un dispositivo in cui Recorder.getHighSpeedVideoCapabilities() restituisce null, l'operazione non riuscirà con un IllegalArgumentException. Puoi confermare il supporto sui dispositivi Google Pixel, in quanto includono sempre questi profili ad alta velocità. Inoltre, anche vari dispositivi di altri produttori, come Motorola Edge 30, OPPO Find N2 Flip e Sony Xperia 1 V, supportano le funzionalità video ad alta velocità.


Conclusione

L'API video ad alta velocità di CameraX è potente e flessibile. Se hai bisogno di filmati ad alta frequenza fotogrammi per l'analisi tecnica o vuoi aggiungere effetti cinematografici in slow motion alla tua app, HighSpeedVideoSessionConfig offre una soluzione unificata e semplice. Comprendendo il ruolo del flag setSlowMotionEnabled, puoi supportare facilmente entrambi i casi d'uso e offrire agli utenti un maggiore controllo creativo.

Scritto da:

Continua a leggere