Un sistema di acquisizione generalmente registra gli stream video e audio, li comprime, esegue il mux dei due flussi, quindi scrive il flusso risultante su disco.
In CameraX, la soluzione per l'acquisizione video è la
VideoCapture
caso d'uso:
Come mostrato nella Figura 2, l'acquisizione video di CameraX include alcune componenti architetturali:
SurfaceProvider
per l'origine video.AudioSource
per la sorgente audio.- Due codificatori per codificare e comprimere i video e l'audio.
- Un media muxer per sincronizzare i due stream.
- Un salvaschermo per scrivere il risultato.
L'API Video Capture astrae il complesso motore di acquisizione e fornisce con un'API molto più semplice e diretta.
Panoramica dell'API Video Capture
VideoCapture
è un caso d'uso di CameraX che funziona bene da solo o quando
in combinazione con altri casi d'uso. Le specifiche combinazioni supportate dipendono
funzionalità hardware della videocamera, ma Preview
e VideoCapture
sono
una combinazione di casi d'uso valida su tutti i dispositivi.
L'API Video Capture è costituita dai seguenti oggetti che comunicano con applicazioni:
VideoCapture
è il di casi d'uso di primo livello.VideoCapture
si associa aLifecycleOwner
conCameraSelector
e un'altra fotocameraX Casi d'uso. Per ulteriori informazioni su questi concetti e utilizzi, vedi Architettura di CameraX.- Un
Recorder
è un implementazione di VideoOutput strettamente associata aVideoCapture
.Recorder
viene utilizzato per eseguire l'acquisizione video e audio. Un l'applicazione crea registrazioni da unRecorder
. - Un
PendingRecording
configura una registrazione, offrendo opzioni quali l'attivazione dell'audio e l'impostazione un listener di eventi. Devi utilizzare unRecorder
per creare unPendingRecording
. UnPendingRecording
non registra nulla. - Un'istruzione
Recording
esegue e la registrazione effettiva. Devi utilizzare unPendingRecording
per creare unRecording
.
La figura 3 mostra le relazioni tra questi oggetti:
Legenda:
- Crea una
Recorder
conQualitySelector
. - Configura
Recorder
con uno deiOutputOptions
- Attiva l'audio con
withAudioEnabled()
se necessario. - Chiama il numero
start()
conVideoRecordEvent
per avviare la registrazione. - Usa
pause()
/resume()
/stop()
nellaRecording
per controllare la registrazione. - Rispondi a
VideoRecordEvents
all'interno del listener di eventi.
L'elenco dettagliato delle API si trova nel file current.txt all'interno del codice sorgente.
Utilizzo dell'API Video Capture
Per integrare il caso d'uso di CameraX VideoCapture
nella tua app:
procedi nel seguente modo:
- Associa
VideoCapture
. - Prepara e configura la registrazione.
- Avvia e controlla la registrazione di runtime.
Le seguenti sezioni descrivono cosa puoi fare in ogni passaggio per ottenere di registrazione end-to-end.
Associa acquisizione video
Per associare il caso d'uso VideoCapure
:
- Crea un oggetto
Recorder
. - Crea oggetto
VideoCapture
. - Associa a
Lifecycle
.
L'API CameraX Video Capture segue il pattern di progettazione del builder. Applicazioni
usa Recorder.Builder
per creare Recorder
. Puoi anche configurare
risoluzione video per Recorder
tramite un oggetto QualitySelector
.
CameraX Recorder
supporta i seguenti valori predefiniti di Qualities
per le risoluzioni video:
Quality.UHD
per dimensioni video ultra HD 4K (2160p)Quality.FHD
per dimensioni video Full HD (1080p)Quality.HD
per dimensioni video HD (720p)Quality.SD
per dimensioni video SD (480p)
Tieni presente che CameraX può anche scegliere altre risoluzioni, se autorizzata dall'app.
Le dimensioni esatte del video per ogni selezione dipendono dalla videocamera e dal codificatore
le funzionalità di machine learning. Per ulteriori informazioni, consulta la documentazione su
CamcorderProfile
Le applicazioni possono configurare la risoluzione creando
QualitySelector
Puoi creare un QualitySelector
utilizzando uno dei seguenti metodi:
Fornisci alcune risoluzioni preferite utilizzando
fromOrderedList()
e includi una strategia di riserva da usare nel caso in cui nessuno dei le risoluzioni preferite sono supportate.CameraX può decidere la migliore corrispondenza di riserva in base alle consulta la sezione
FallbackStrategy specification
diQualitySelector
per ulteriori dettagli. Ad esempio, il seguente codice richiede il livello massimo supportato risoluzione del problema per la registrazione e, se nessuna delle opzioni delle richieste è supportata, autorizzi CameraX a scegliere quella che più si avvicina alla qualità.Risoluzione SD:val qualitySelector = QualitySelector.fromOrderedList( listOf(Quality.UHD, Quality.FHD, Quality.HD, Quality.SD), FallbackStrategy.lowerQualityOrHigherThan(Quality.SD))
Innanzitutto, esegui una query sulle funzionalità della videocamera e scegli una delle funzionalità supportate risoluzioni utilizzando
QualitySelector::from()
:val cameraInfo = cameraProvider.availableCameraInfos.filter { Camera2CameraInfo .from(it) .getCameraCharacteristic(CameraCharacteristics.LENS\_FACING) == CameraMetadata.LENS_FACING_BACK } val supportedQualities = QualitySelector.getSupportedQualities(cameraInfo[0]) val filteredQualities = arrayListOf (Quality.UHD, Quality.FHD, Quality.HD, Quality.SD) .filter { supportedQualities.contains(it) } // Use a simple ListView with the id of simple_quality_list_view viewBinding.simpleQualityListView.apply { adapter = ArrayAdapter(context, android.R.layout.simple_list_item_1, filteredQualities.map { it.qualityToString() }) // Set up the user interaction to manually show or hide the system UI. setOnItemClickListener { _, _, position, _ -> // Inside View.OnClickListener, // convert Quality.* constant to QualitySelector val qualitySelector = QualitySelector.from(filteredQualities[position]) // Create a new Recorder/VideoCapture for the new quality // and bind to lifecycle val recorder = Recorder.Builder() .setQualitySelector(qualitySelector).build() // ... } } // A helper function to translate Quality to a string fun Quality.qualityToString() : String { return when (this) { Quality.UHD -> "UHD" Quality.FHD -> "FHD" Quality.HD -> "HD" Quality.SD -> "SD" else -> throw IllegalArgumentException() } }
Tieni presente che la funzionalità restituita
QualitySelector.getSupportedQualities()
il suo funzionamento è garantito per il caso d'usoVideoCapture
o combinazione di casi d'uso diVideoCapture
ePreview
. Quando si associano Caso d'uso diImageCapture
oImageAnalysis
, FotocameraX l'associazione potrebbe comunque non riuscire quando la combinazione richiesta non è supportata la videocamera richiesta.
Una volta che disponi di un QualitySelector
, l'applicazione può creare un
VideoCapture
ed eseguire l'associazione. Tieni presente che questa associazione
come per altri casi d'uso:
val recorder = Recorder.Builder()
.setExecutor(cameraExecutor).setQualitySelector(qualitySelector)
.build()
val videoCapture = VideoCapture.withOutput(recorder)
try {
// Bind use cases to camera
cameraProvider.bindToLifecycle(
this, CameraSelector.DEFAULT_BACK_CAMERA, preview, videoCapture)
} catch(exc: Exception) {
Log.e(TAG, "Use case binding failed", exc)
}
Tieni presente che bindToLifecycle()
restituisce un oggetto Camera
. Consulta questa guida per ulteriori informazioni su come controllare l'output della fotocamera, ad esempio lo zoom e l'esposizione.
L'Recorder
seleziona il formato più adatto al sistema. Il più
il codec video più comune è
H.264 AVC) con
formato container
MPEG-4.
Configura e crea registrazione
Da un Recorder
, l'applicazione può creare oggetti di registrazione su
eseguire l'acquisizione video e audio. Le applicazioni creano registrazioni
le seguenti:
- Configura
OutputOptions
con ilprepareRecording()
. - (Facoltativo) Attiva la registrazione audio.
- Usa
start()
per registrare unVideoRecordEvent
ascoltatore e avvia l'acquisizione del video.
Recorder
restituisce un oggetto Recording
quando chiami la funzione start()
.
La tua applicazione può utilizzare questo oggetto Recording
per completare l'operazione
acquisire o eseguire altre azioni, come la messa in pausa o la ripresa.
Un'Recorder
supporta un oggetto Recording
alla volta. Puoi avviare una
nuova registrazione dopo che hai chiamato Recording.stop()
o
Recording.close()
sull'oggetto Recording
precedente.
Diamo un'occhiata a questi passaggi in modo più dettagliato. Innanzitutto, l'applicazione configura
OutputOptions
per un Registratore con Recorder.prepareRecording()
.
Un Recorder
supporta i seguenti tipi di OutputOptions
:
FileDescriptorOutputOptions
per acquisireFileDescriptor
FileOutputOptions
per le acquisizioni inFile
.MediaStoreOutputOptions
per acquisireMediaStore
Tutti i tipi di OutputOptions
consentono di impostare le dimensioni massime dei file con
setFileSizeLimit()
. Altre opzioni sono specifiche per il singolo output
ad esempio ParcelFileDescriptor
per FileDescriptorOutputOptions
.
prepareRecording()
restituisce un oggetto PendingRecording
, che è un
oggetto intermedio utilizzato per creare l'oggetto
Recording
oggetto. PendingRecording
è una classe temporanea che dovrebbe
sono invisibili nella maggior parte dei casi e
raramente vengono memorizzate nella cache dall'app.
Le applicazioni possono configurare ulteriormente la registrazione, ad esempio:
- Attiva l'audio con
withAudioEnabled()
. - Registrare un listener per ricevere eventi di registrazione video
con
start(Executor, Consumer<VideoRecordEvent>)
. - Consenti la registrazione continua di una registrazione mentre Video Capture è collegato
a un'altra fotocamera, con
PendingRecording.asPersistentRecording()
.
Per avviare la registrazione, chiama il numero PendingRecording.start()
. CameraX trasforma
PendingRecording
in una Recording
, mette in coda la richiesta di registrazione,
e restituisce all'applicazione l'oggetto Recording
appena creato.
Quando la registrazione inizia sul dispositivo Fotocamera corrispondente, CameraX invia un
VideoRecordEvent.EVENT_TYPE_START
evento.
L'esempio seguente mostra come registrare video e audio in un
File MediaStore
:
// Create MediaStoreOutputOptions for our recorder
val name = "CameraX-recording-" +
SimpleDateFormat(FILENAME_FORMAT, Locale.US)
.format(System.currentTimeMillis()) + ".mp4"
val contentValues = ContentValues().apply {
put(MediaStore.Video.Media.DISPLAY_NAME, name)
}
val mediaStoreOutput = MediaStoreOutputOptions.Builder(this.contentResolver,
MediaStore.Video.Media.EXTERNAL_CONTENT_URI)
.setContentValues(contentValues)
.build()
// 2. Configure Recorder and Start recording to the mediaStoreOutput.
val recording = videoCapture.output
.prepareRecording(context, mediaStoreOutput)
.withAudioEnabled()
.start(ContextCompat.getMainExecutor(this), captureListener)
Mentre l'anteprima della fotocamera viene speculare sulla fotocamera anteriore per impostazione predefinita, i video registrate da Video Capture non vengono sottoposte a mirroring per impostazione predefinita. Con CameraX 1.3, ora è possibile eseguire il mirroring delle registrazioni video in modo che l'anteprima della fotocamera anteriore corrispondenza video registrata.
Sono disponibili tre opzioni MirrorMode: MIRROR_MODE_OFF, MIRROR_MODE_ON e
MIRROR_MODE_ON_FRONT_ONLY. Per allinearsi al
l'anteprima della fotocamera Google consiglia di utilizzare MIROR_MODE_ON_FRONT_ONLY,
che
Il mirroring non è abilitato per la fotocamera posteriore, ma è abilitato per la fotocamera anteriore
fotocamera. Per ulteriori informazioni su MirrorMode, vedi
MirrorMode constants
Questo snippet di codice mostra come chiamare
VideoCapture.Builder.setMirrorMode()
con MIRROR_MODE_ON_FRONT_ONLY
. Per
Per ulteriori informazioni, consulta setMirrorMode()
.
Kotlin
val recorder = Recorder.Builder().build() val videoCapture = VideoCapture.Builder(recorder) .setMirrorMode(MIRROR_MODE_ON_FRONT_ONLY) .build() useCases.add(videoCapture);
Java
Recorder.Builder builder = new Recorder.Builder(); if (mVideoQuality != QUALITY_AUTO) { builder.setQualitySelector( QualitySelector.from(mVideoQuality)); } VideoCapture<Recorder> videoCapture = new VideoCapture.Builder<>(builder.build()) .setMirrorMode(MIRROR_MODE_ON_FRONT_ONLY) .build(); useCases.add(videoCapture);
Controllare una registrazione attiva
Puoi mettere in pausa, riprendere e interrompere un Recording
in corso
utilizzando i seguenti metodi:
pause
per mettere in pausa la registrazione attiva attuale.resume()
per riprendere una registrazione attiva in pausa.stop()
per terminare la registrazione e fare il flush di eventuali oggetti registrati associati.mute()
per disattivare o riattivare l'audio della registrazione corrente.
Tieni presente che puoi chiamare stop()
per terminare una Recording
indipendentemente
che indica se la registrazione è in pausa o attiva.
Se hai registrato EventListener
con
PendingRecording.start()
, Recording
comunica
utilizzando un
VideoRecordEvent
.
VideoRecordEvent.EVENT_TYPE_STATUS
viene utilizzato per la registrazione di statistiche come come dimensione del file corrente e intervallo di tempo registrato.- Viene usato
VideoRecordEvent.EVENT_TYPE_FINALIZE
per il risultato della registrazione e include informazioni quali l'URI del file finale, eventuali errori correlati.
Quando la tua app riceve un EVENT_TYPE_FINALIZE
che indica un esito positivo
di registrazione, potrai accedere al video acquisito dalla località
specificato in OutputOptions
.
Risorse aggiuntive
Per saperne di più su CameraX, consulta le seguenti risorse aggiuntive:
- Iniziare a utilizzare il codelab CameraX
- Esempio di app ufficiale CameraX
- Ultimo elenco di API CameraX Video Capture
- Note di rilascio di CameraX
- Codice sorgente di CameraX