Istruzioni

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

Lettura di 6 minuti
Leo Huang
Software Engineer

Acquisire azioni in rapido movimento con chiarezza è una funzionalità chiave per le moderne app per la fotocamera. Ciò si ottiene tramite l'acquisizione ad alta velocità, ovvero il processo di acquisizione di frame a velocità come 120 o 240 f/s. Questa acquisizione ad alta fedeltà può essere utilizzata per due scopi distinti: creare un video ad alta frequenza dei fotogrammi per un'analisi dettagliata fotogramma per fotogramma 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 una procedura più pratica. Ora, con la nuova API ad alta velocità in CameraX 1.5, l'intero processo è semplificato, offrendoti la flessibilità di creare video con un frame rate elevato o clip in slow motion pronti per la riproduzione. Questo post ti mostrerà come padroneggiare entrambi. Se non hai mai utilizzato CameraX, puoi iniziare con la panoramica di CameraX.


Il principio alla base dello slow motion

Il principio fondamentale della slow motion è quello di acquisire video a una frequenza fotogrammi molto più elevata 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 di 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 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 gestita dal lettore (video ad alta frequenza fotogrammi): la registrazione ad alta velocità (ad es. 120 fps) viene salvata direttamente come file video ad alta frequenza fotogrammi. È quindi responsabilità del video player rallentare la velocità di riproduzione. In questo modo, l'utente può passare dalla riproduzione normale a quella in slow motion.
  • Video in slow motion pronto per la riproduzione (video ricodificato): il flusso 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" modificando i timestamp dei frame. Il video risultante verrà riprodotto in slow motion in qualsiasi video player standard senza una gestione speciale. Anche se il video viene riprodotto in slow motion per impostazione predefinita, i video player possono comunque fornire controlli della velocità di riproduzione che consentono all'utente di aumentare la velocità e guardare il video alla sua 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 videocamera 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 di VideoCapture e Preview, indicando a CameraX di creare una sessione della fotocamera unificata ad alta velocità. 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 videocamera 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 della tua 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 versioni future. Per utilizzarli, 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 dei fotogrammi o di un video in slow motion dipende da una sola impostazione.

1. Configurare l'acquisizione ad alta velocità

Innanzitutto, indipendentemente dal tuo obiettivo, devi ottenere l'ProcessCameraProvider, verificare le funzionalità del dispositivo e creare i tuoi 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. Scegliere l'output

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

Opzione A: crea un video ad alta frequenza dei 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 che un video venga riprodotto automaticamente in slow motion in qualsiasi video player 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à di riproduzione al rallentatore è determinata dal rapporto tra la frequenza fotogrammi di acquisizione e questa velocità di riproduzione standard.

Ad esempio:

  • La registrazione a 120 f/s produrrà un video riprodotto a velocità 1/4x (120 ÷ 30 = 4).
  • La registrazione a 240 f/s produrrà un video riprodotto a 1/8 della velocità (240 ÷ 30 = 8).

Metti insieme tutti i pezzi: registrazione del 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 di una normale acquisizione video.

Questo post si concentra sulla configurazione ad alta velocità, pertanto non tratteremo in dettaglio il processo 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 attivi setSlowMotionEnabled(true) in CameraX, il file video risultante è progettato per essere immediatamente riconoscibile e riproducibile come slow motion nei video player 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 di UI distinte nella miniatura: nella raccolta di Google Foto, i video in slow motion possono essere identificati da elementi UI specifici, che li distinguono dai video normali.
normal.png
slowmotion.png
Miniatura del video normaleMiniatura del video in slow motion
  • Segmenti di velocità regolabili durante la riproduzione: quando riproduci 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 il controllo creativo. Il video modificato può essere esportato come nuovo file video utilizzando il pulsante Condividi, mantenendo i segmenti in slow motion che hai definito.
normal2.png
slowmotion2.png
Riproduzione video normaleRiproduzione di video in slow motion 
con controlli di modifica 

Una nota sull'assistenza per i dispositivi

L'API ad alta velocità di CameraX si basa sul sistema CamcorderProfile di Android sottostante per determinare quali risoluzioni e frame rate ad alta velocità sono supportati da un dispositivo. I profili videocamera vengono convalidati da Android Compatibility Test Suite (CTS), 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 fotocamera integrata non garantisce il funzionamento dell'API ad alta velocità CameraX. Questa discrepanza si verifica perché i produttori di dispositivi sono responsabili del popolamento delle voci CamcorderProfile nel firmware del dispositivo e a volte non sono inclusi 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() restituirà null.

Pertanto, è essenziale utilizzare sempre Recorder.getHighSpeedVideoCapabilities() per verificare le funzionalità supportate a livello di programmazione, in quanto questo è il modo più affidabile per garantire un'esperienza coerente su diversi dispositivi. Se provi a eseguire il binding di un HighSpeedVideoSessionConfig su un dispositivo in cui Recorder.getHighSpeedVideoCapabilities() restituisce un valore nullo, l'operazione non andrà a buon fine e verrà restituito un IllegalArgumentException. Puoi verificare 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à CameraX è potente e flessibile. Che tu abbia bisogno di riprese ad alta frequenza di fotogrammi per l'analisi tecnica o voglia aggiungere effetti cinematografici in slow motion alla tua app, l'HighSpeedVideoSessionConfig offre una soluzione semplice e unificata. Se comprendi 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