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:
VideoCapture.Come mostrato nella Figura 2, l'acquisizione video di CameraX include alcune componenti architetturali:
SurfaceProviderper l'origine video.AudioSourceper 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.VideoCapturesi associa aLifecycleOwnerconCameraSelectore 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.Recorderviene utilizzato per eseguire l'acquisizione video e audio. Un l'applicazione crea registrazioni da unRecorder. - Un
PendingRecordingconfigura una registrazione, offrendo opzioni quali l'attivazione dell'audio e l'impostazione un listener di eventi. Devi utilizzare unRecorderper creare unPendingRecording. UnPendingRecordingnon registra nulla. - Un'istruzione
Recordingesegue e la registrazione effettiva. Devi utilizzare unPendingRecordingper creare unRecording.
La figura 3 mostra le relazioni tra questi oggetti:
Legenda:
- Crea una
RecorderconQualitySelector. - Configura
Recordercon uno deiOutputOptions - Attiva l'audio con
withAudioEnabled()se necessario. - Chiama il numero
start()conVideoRecordEventper avviare la registrazione. - Usa
pause()/resume()/stop()nellaRecordingper controllare la registrazione. - Rispondi a
VideoRecordEventsall'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:
segui questi passaggi:
- 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.UHDper dimensioni video ultra HD 4K (2160p)Quality.FHDper dimensioni video Full HD (1080p)Quality.HDper dimensioni video HD (720p)Quality.SDper 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 specificationdiQualitySelectorper ulteriori informazioni. 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'usoVideoCaptureo combinazione di casi d'uso diVideoCaptureePreview. Quando si associano Caso d'uso diImageCaptureoImageAnalysis, 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
OutputOptionscon ilprepareRecording(). - (Facoltativo) Attiva la registrazione audio.
- Usa
start()per registrare unVideoRecordEventascoltatore 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:
FileDescriptorOutputOptionsper acquisireFileDescriptorFileOutputOptionsper le acquisizioni inFile.MediaStoreOutputOptionsper 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:
pauseper 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_STATUSviene utilizzato per la registrazione di statistiche come come dimensione del file corrente e intervallo di tempo registrato.- Viene usato
VideoRecordEvent.EVENT_TYPE_FINALIZEper 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