Novità sul prodotto

Presentazione di CameraX 1.5: registrazione video potente e acquisizione di immagini a livello professionale

7 minuti di lettura
Scott Nien
Ingegnere del software

Il team di CameraX è entusiasta di annunciare la release della versione 1.5. Questo ultimo aggiornamento si concentra sull'offrire funzionalità di livello professionale a portata di mano, semplificando al contempo la configurazione della sessione della videocamera.

Per la registrazione video, gli utenti possono ora acquisire senza sforzo video in slow motion o con frame rate elevato. Ancora più importante, la nuova API Feature Group ti consente di attivare con sicurezza combinazioni complesse come HDR a 10 bit e 60 FPS, garantendo risultati coerenti sui dispositivi supportati.

Per quanto riguarda l'acquisizione di immagini , ottieni la massima flessibilità grazie al supporto per l'acquisizione di file DNG (RAW) non elaborati e non compressi. Inoltre, ora puoi sfruttare l'output Ultra HDR anche quando utilizzi le potenti estensioni della videocamera.

Alla base di queste funzionalità c'è la nuova API SessionConfig, che semplifica la configurazione e la riconfigurazione della videocamera. Ora, approfondiamo i dettagli di queste nuove ed entusiasmanti funzionalità.

Registrazione video potente: alta velocità e combinazioni di funzionalità

CameraX 1.5 espande in modo significativo le sue funzionalità video, consentendo esperienze di registrazione più creative e robuste.

Video in slow motion e con frame rate elevato

Una delle funzionalità più attese, il video in slow motion, è ora disponibile. Ora puoi acquisire video ad alta velocità (ad es. 120 o 240 fps) e codificarli direttamente in un video in slow motion. In alternativa, puoi registrare con la stessa frequenza fotogrammi elevata per produrre video eccezionalmente fluidi.

L'implementazione è semplice se hai familiarità con l'API VideoCapture.

1. Verifica il supporto dell'alta velocità: utilizza il nuovo Recorder.getHighSpeedVideoCapabilities() metodo per verificare se il dispositivo supporta questa funzionalità.

  val cameraInfo = cameraProvider.getCameraInfo(cameraSelector)

val highSpeedCapabilities = Recorder.getHighSpeedVideoCapabilities(cameraInfo)

if (highSpeedCapabilities == null) {
    // This camera device does not support high-speed video.
    return
}

2. Configura e associa il caso d'uso: utilizza l'oggetto videoCapabilities restituito (che contiene informazioni sulla qualità video supportata) per creare un oggetto HighSpeedVideoSessionConfig. Dopodiché, devi eseguire una query sugli intervalli di frequenza fotogrammi supportati tramite cameraInfo.getSupportedFrameRateRanges() e impostare l'intervallo desiderato. Richiama setSlowMotionEnabled(true) per registrare video in slow motion, altrimenti verranno registrati video con frame rate elevato. Il passaggio finale consiste nell'utilizzare il normale metodo Recorder.prepareRecording().start() per avviare la registrazione del video.

  val preview = Preview.Builder().build()
val quality = highSpeedCapabilities
        .getSupportedQualities(DynamicRange.SDR).first()

val recorder = Recorder.Builder()
      .setQualitySelector(QualitySelector.from(quality)))
      .build()

val videoCapture = VideoCapture.withOutput(recorder)

val frameRateRange = cameraInfo.getSupportedFrameRateRanges(      
       HighSpeedVideoSessionConfig(videoCapture, preview)
).first()

val sessionConfig = HighSpeedVideoSessionConfig(
    videoCapture, 
    preview, 
    frameRateRange = frameRateRange, 
    // Set true for slow-motion playback, or false for high-frame-rate
    isSlowMotionEnabled = true
)

cameraProvider.bindToLifecycle(
     lifecycleOwner, cameraSelector, sessionConfig)

// Start recording slow motion videos. 
val recording = recorder.prepareRecording(context, outputOption)
      .start(executor, {})

Compatibilità e limitazioni

La registrazione ad alta velocità richiede il supporto specifico di CameraConstrainedHighSpeedCaptureSession e CamcorderProfile. Esegui sempre il controllo delle funzionalità e attiva la registrazione ad alta velocità solo sui dispositivi supportati per evitare una cattiva esperienza utente. Al momento, questa funzionalità è supportata sulle fotocamere posteriori di quasi tutti i dispositivi Pixel e su alcuni modelli di altri produttori.

Per maggiori dettagli, consulta il post del blog.

Combina le funzionalità con sicurezza: l'API Feature Group

CameraX 1.5 introduce l'API Feature Group, che elimina le incertezze sulla compatibilità delle funzionalità. Basandoti sull'API di query di combinazione di funzionalità di Android 15, ora puoi attivare con sicurezza più funzionalità contemporaneamente, garantendo una sessione della videocamera stabile. Il gruppo di funzionalità supporta attualmente: HDR (HLG), 60 fps, stabilizzazione dell'anteprima e Ultra HDR. Ad esempio, puoi attivare contemporaneamente HDR, 60 fps e stabilizzazione dell'anteprima sulle serie Pixel 10 e Galaxy S25. Sono previsti miglioramenti futuri per includere la registrazione in 4K e lo zoom ultrawide. 

L'API Feature Group consente due casi d'uso essenziali:

Caso d'uso 1: dare la priorità alla qualità migliore

Se vuoi acquisire utilizzando la migliore combinazione possibile di funzionalità, puoi fornire un elenco con priorità. CameraX tenterà di attivarle in ordine, selezionando la prima combinazione completamente supportata dal dispositivo.

  val sessionConfig = SessionConfig(
    useCases = listOf(preview, videoCapture),
    preferredFeatureGroup = listOf(
        GroupableFeature.HDR_HLG10,
        GroupableFeature.FPS_60,
        GroupableFeature.PREVIEW_STABILIZATION
    )
).apply {
    // (Optional) Get a callback with the enabled features to update your UI.
    setFeatureSelectionListener { selectedFeatures ->
        updateUiIndicators(selectedFeatures)
    }
}
processCameraProvider.bindToLifecycle(activity, cameraSelector, sessionConfig)

In questo esempio, CameraX tenta di attivare le funzionalità in questo ordine:

  1. HDR + 60 FPS + stabilizzazione dell'anteprima
  2. HDR + 60 FPS
  3. HDR + stabilizzazione dell'anteprima
  4. HDR
  5. 60 FPS + stabilizzazione dell'anteprima
  6. 60 FPS
  7. Stabilizzazione dell'anteprima
  8. Nessuno

Caso d'uso 2: creazione di un'interfaccia utente delle impostazioni rivolta all'utente

Ora puoi riflettere con precisione quali combinazioni di funzionalità sono supportate nell'interfaccia utente delle impostazioni della tua app, disattivando i pulsanti di attivazione/disattivazione per le opzioni non supportate, come nell'immagine riportata di seguito. 

unsupported-features-disabled.gif

Per determinare se disattivare un pulsante di attivazione/disattivazione, utilizza i seguenti codici per verificare il supporto della combinazione di funzionalità. Inizialmente, esegui una query sullo stato di ogni singola funzionalità. Una volta attivata una funzionalità, esegui di nuovo una query sulle funzionalità rimanenti con le funzionalità attivate per verificare se i relativi pulsanti di attivazione/disattivazione devono essere disattivati a causa di vincoli di compatibilità.

  fun disableFeatureIfNotSuported(
   enabledFeatures: Set<GroupableFeature>,     
   featureToCheck:GroupableFeature
) {
 val sessionConfig = SessionConfig(
     useCases = useCases,
     requiredFeatureGroup = enabledFeatures + featureToCheck
 )
 val isSupported = cameraInfo.isFeatureGroupSupported(sessionConfig)

 if (!isSupported) {
     // disable the toggle for featureToCheck
 }
}

Per maggiori informazioni, consulta il post del blog Feature Group

Altri miglioramenti video

  • Miglioramenti simultanei della videocamera: con CameraX 1.5.1, ora puoi associare contemporaneamente i casi d'uso Anteprima + ImageCapture + VideoCapture per ogni SingleCameraConfig in modalità non di composizione. Inoltre, in modalità di composizione (gli stessi casi d'uso con CompositionSettings),  ora puoi impostare l'oggetto CameraEffect applicato al risultato della composizione finale.
  • Disattivazione dinamica dell'audio: ora puoi avviare una registrazione con l'audio disattivato utilizzando PendingRecording.withAudioEnabled(boolean initialMuted) e consentire all'utente di riattivare l'audio in un secondo momento utilizzando Recording.mute(boolean muted).
  • Gestione migliorata dello spazio di archiviazione insufficiente: ora CameraX invia in modo affidabile l'errore VideoRecordEvent.Finalize.ERROR_INSUFFICIENT_STORAGE, consentendo alla tua app di gestire correttamente le situazioni di spazio di archiviazione insufficiente e di informare l'utente.
  • Potenziamento in condizioni di scarsa illuminazione: sui dispositivi supportati (come la serie Pixel 10), puoi attivare CameraControl.enableLowLightBoostAsync per illuminare automaticamente l'anteprima e gli stream video in ambienti bui.

Acquisizione di immagini a livello professionale

CameraX 1.5 introduce importanti aggiornamenti a ImageCapture per gli sviluppatori che richiedono la massima qualità e flessibilità.

Libera il controllo creativo con l'acquisizione DNG (RAW)

Per un controllo completo della post-elaborazione, CameraX ora supporta l'acquisizione DNG (RAW). In questo modo, hai accesso ai dati delle immagini non elaborati e non compressi direttamente dal sensore della videocamera, consentendo l'editing e la correzione cromatica a livello professionale. L'API supporta l'acquisizione del solo file DNG o l'acquisizione simultanea di output JPEG e DNG. Per scoprire come acquisire simultaneamente file JPEG e DNG, consulta l'esempio di codice campione riportato di seguito.

  val capabilities = ImageCapture.getImageCaptureCapabilities(cameraInfo)
val imageCapture = ImageCapture.Builder().apply {
    if (capabilities.supportedOutputFormats
             .contains(OUTPUT_FORMAT_RAW_JPEG)) {
        // Capture both RAW and JPEG formats.
        setOutputFormat(OUTPUT_FORMAT_RAW_JPEG)
    }
}.build()
// ... bind imageCapture to lifecycle ...


// Provide separate output options for each format.
val outputOptionRaw = /* ... configure for image/x-adobe-dng ... */
val outputOptionJpeg = /* ... configure for image/jpeg ... */
imageCapture.takePicture(
    outputOptionRaw,
    outputOptionJpeg,
    executor,
    object : ImageCapture.OnImageSavedCallback {
        override fun onImageSaved(results: OutputFileResults) {
            // This callback is invoked twice: once for the RAW file
            // and once for the JPEG file.
        }

        override fun onError(exception: ImageCaptureException) {}
    }
)

Ultra HDR per le estensioni della videocamera

Ottieni il meglio di entrambi i mondi: la straordinaria fotografia computazionale delle estensioni della videocamera (come la modalità notturna) combinata con il colore brillante e la gamma dinamica di Ultra HDR. Questa funzionalità è ora supportata su molti smartphone Android premium recenti, come le serie Pixel 9/10 e Samsung S24/S25.

  // Support UltraHDR when Extension is enabled. 

val extensionsEnabledCameraSelector = extensionsManager
     .getExtensionEnabledCameraSelector(
        CameraSelector.DEFAULT_BACK_CAMERA, ExtensionMode.NIGHT)

val imageCapabilities = ImageCapture.getImageCaptureCapabilities(
               cameraProvider.getCameraInfo(extensionsEnabledCameraSelector)

val imageCapture = ImageCapture.Builder()
     .apply {
       if (imageCapabilities.supportedOutputFormats
                .contains(OUTPUT_FORMAT_JPEG_ULTRA_HDR) {
           setOutputFormat(OUTPUT_FORMAT_JPEG_ULTRA_HDR)

       }

     }.build()

Miglioramenti dell'API principale e dell'usabilità

Un nuovo modo di configurare: SessionConfig

Come mostrato negli esempi precedenti, SessionConfig è un nuovo concetto in CameraX 1.5. Centralizza la configurazione e semplifica l'API in due modi principali:

  1. Non sono più necessarie chiamate unbind() manuali: le API CameraX sono sensibili al ciclo di vita. Annullerà implicitamente l'associazione dei casi d'uso quando l'attività o un altro LifecycleOwner viene eliminato. Tuttavia, l'aggiornamento dei casi d'uso o il cambio di videocamera richiede comunque di chiamare unbind() o unbindAll() prima di eseguire una nuova associazione. Ora, con CameraX 1.5, quando associ un nuovo SessionConfig, CameraX aggiorna automaticamente la sessione, eliminando la necessità di chiamare `unbind()`.
  2. Controllo deterministico della frequenza fotogrammi: la nuova API SessionConfig introduce un modo deterministico per gestire la frequenza fotogrammi. A differenza del precedente setTargetFrameRate, che era solo un suggerimento, questo nuovo metodo garantisce che l'intervallo di frequenza fotogrammi specificato venga applicato dopo la configurazione. Per garantire l'accuratezza, devi eseguire una query sulle frequenze fotogrammi supportate utilizzando CameraInfo.getSupportedFrameRateRanges(SessionConfig). Passando l'oggetto SessionConfig completo, CameraX può determinare con precisione gli intervalli supportati in base alle configurazioni degli stream.

Camera-Compose è ora stabile

Sappiamo quanto ti piace Jetpack Compose e siamo entusiasti di annunciare che la camera-compose libreria è ora stabile alla versione 1.5.1! Questa release include correzioni di bug critici relativi all'utilizzo di CameraXViewfinder con le funzionalità di Compose come moveableContentOf e Pager, oltre alla risoluzione di un problema di allungamento dell'anteprima. Continueremo ad aggiungere altre funzionalità a camera-compose nelle release future.

Miglioramenti di ImageAnalysis e CameraControl

  • Regolazione della potenza della torcia: ottieni un controllo preciso sulla torcia del dispositivo con le nuove API. Puoi eseguire una query sulla potenza massima supportata utilizzando CameraInfo.getMaxTorchStrengthLevel() e poi impostare il livello desiderato con CameraControl.setTorchStrengthLevel().
  • Supporto di NV21 in ImageAnalysis: ora puoi richiedere il formato immagine NV21 direttamente da ImageAnalysis, semplificando l'integrazione con altre librerie e API. Questa funzionalità è attivata richiamando ImageAnalysis.Builder.setOutputImageFormat(OUTPUT_IMAGE_FORMAT_NV21).

Inizia oggi stesso

Aggiorna oggi stesso le dipendenze a CameraX 1.5 ed esplora le nuove ed entusiasmanti funzionalità. Non vediamo l'ora di scoprire cosa creerai.

Per utilizzare CameraX 1.5,  aggiungi le seguenti dipendenze a libs.versions.toml. (Ti consigliamo di utilizzare la versione 1.5.1, che contiene molte correzioni di bug critici e miglioramenti simultanei della videocamera.)

  [versions]

camerax = "1.5.1"


[libraries]

..

androidx-camera-core = { module = "androidx.camera:camera-core", version.ref = "camerax" }

androidx-camera-compose = { module = "androidx.camera:camera-compose", version.ref = "camerax" }

androidx-camera-view = { module = "androidx.camera:camera-view", version.ref = "camerax" }

androidx-camera-lifecycle = { group = "androidx.camera", name = "camera-lifecycle", version.ref = "camerax" }

androidx-camera-camera2 = { module = "androidx.camera:camera-camera2", version.ref = "camerax" }

androidx-camera-extensions = { module = "androidx.camera:camera-extensions", version.ref = "camerax" }

Aggiungi poi queste dipendenze a build.gradle.kts del modulo:

  dependencies {

  ..

  implementation(libs.androidx.camera.core)
  implementation(libs.androidx.camera.lifecycle)

  implementation(libs.androidx.camera.camera2)

  implementation(libs.androidx.camera.view) // for PreviewView 
  implementation(libs.androidx.camera.compose) // for compose UI

  implementation(libs.androidx.camera.extensions) // For Extensions 

}

Hai domande o vuoi entrare in contatto con il team di CameraX? Partecipa al gruppo di discussione degli sviluppatori di CameraX o invia una segnalazione di bug:

Scritto da:

Continua a leggere