Ein Aufnahmesystem zeichnet in der Regel Video- und Audiostreams auf, komprimiert sie muxt die beiden Streams und schreibt den resultierenden Stream dann auf die Festplatte.
<ph type="x-smartling-placeholder">In CameraX besteht die Lösung für Videoaufnahmen
VideoCapture
Anwendungsfall:
Wie in Abbildung 2 gezeigt, umfasst die CameraX-Videoaufzeichnung einige Architekturkomponenten:
SurfaceProvider
für die Videoquelle.AudioSource
für Audioquelle.- Zwei Encoder zum Codieren und Komprimieren von Video/Audio.
- Einen Media-Muxer zum Muxen der beiden Streams
- Ein Dateispeicher zum Ausschreiben des Ergebnisses.
Die VideoCapture API abstrahiert die komplexe Erfassungs-Engine und bietet mit einer wesentlich einfacheren und unkomplizierteren API erstellen.
VideoCapture API
VideoCapture
ist ein Anwendungsfall von CameraX, der allein oder in der Praxis gut funktioniert
in Kombination mit anderen Anwendungsfällen. Speziell unterstützte Kombinationen hängen vom
der Kamera-Hardware, aber Preview
und VideoCapture
sind
für alle Geräte eine gültige Anwendungsfallkombination.
Die VideoCapture API besteht aus den folgenden Objekten, die miteinander kommunizieren. mit Anwendungen:
VideoCapture
ist der/die/das Top-Level-Anwendungsfallklasse.VideoCapture
bindet an einLifecycleOwner
mit einemCameraSelector
und einem anderen CameraX Anwendungsfälle. Weitere Informationen zu diesen Konzepten und Verwendungen finden Sie unter CameraX-Architektur- Ein
Recorder
ist ein Implementierung von VideoOutput, das eng mitVideoCapture
gekoppelt ist.Recorder
wird für die Video- und Audioaufnahme verwendet. Eine App erstellt Aufnahmen aus einemRecorder
. PendingRecording
konfiguriert eine Aufnahme und bietet Optionen wie das Aktivieren der Audiofunktion und Event-Listener. Sie müssen einenRecorder
verwenden, um einenPendingRecording
zu erstellen. MitPendingRecording
wird nichts aufgezeichnet.- Ein
Recording
führt die der eigentlichen Aufnahme. Sie müssen einenPendingRecording
verwenden, um einenRecording
zu erstellen.
Abbildung 3 zeigt die Beziehungen zwischen diesen Objekten:
<ph type="x-smartling-placeholder">Legende:
Recorder
erstellen mitQualitySelector
- Konfigurieren Sie die
Recorder
mit einer derOutputOptions
- Audio aktivieren mit
withAudioEnabled()
wenn nötig. start()
anrufen mitVideoRecordEvent
Listener, um die Aufzeichnung zu starten.pause()
/resume()
/stop()
verwenden fürRecording
um die Aufzeichnung zu steuern.VideoRecordEvents
antworten in Ihrem Event-Listener auf.
Eine detaillierte API-Liste finden Sie in der current.txt-Datei im Quellcode.
VideoCapture API verwenden
So integrierst du den VideoCapture
-Anwendungsfall von CameraX in deine App:
Gehen Sie so vor:
- Bindung
VideoCapture
. - Aufzeichnung vorbereiten und konfigurieren
- Laufzeitaufzeichnung starten und steuern.
In den folgenden Abschnitten wird beschrieben, was Sie in den einzelnen Schritten tun können, um eine Ende-zu-Ende-Aufzeichnung.
VideoCapture binden
So binden Sie den Anwendungsfall VideoCapure
:
- Erstellen Sie ein
Recorder
-Objekt. - Erstellen Sie ein
VideoCapture
-Objekt. - An
Lifecycle
binden.
Die CameraX VideoCapture API folgt dem Designmuster des Builders. Anwendungen
Verwenden Sie Recorder.Builder
, um ein Recorder
zu erstellen. Sie können auch die
Videoauflösung für das Recorder
über ein QualitySelector
-Objekt.
CameraX-Recorder
unterstützt die folgenden vordefinierten Qualities
für Videoauflösungen:
Quality.UHD
für 4K-Ultra-HD-Videogröße (2160p)Quality.FHD
für Full-HD-Videogröße (1080p)Quality.HD
für HD-Videogröße (720p)Quality.SD
für SD-Videogröße (480p)
Beachte, dass KameraX auch andere Auflösungen auswählen kann, wenn dies von der App autorisiert wird.
Die genaue Videogröße jeder Auswahl hängt von der
Funktionen. Weitere Informationen finden Sie in der Dokumentation zu
CamcorderProfile
Anwendungen können die Auflösung konfigurieren, indem ein
QualitySelector
Sie können ein QualitySelector
-Objekt mit einer der folgenden Methoden erstellen:
Geben Sie einige bevorzugte Lösungen an, indem Sie
fromOrderedList()
verwenden und eine Fallback-Strategie für den Fall, dass keine der Auflösungen unterstützt.Die beste Fallback-Lösung kann von CameraX anhand der Weitere Informationen finden Sie in der
FallbackStrategy specification
vonQualitySelector
. . Mit dem folgenden Code wird beispielsweise die höchste unterstützte Auflösung für die Aufzeichnung. Falls keine der Auflösungen der Anfrage unterstützt wird, autorisiere CameraX, die Option auszuwählen, die der SD-Auflösung am nächsten kommt:val qualitySelector = QualitySelector.fromOrderedList( listOf(Quality.UHD, Quality.FHD, Quality.HD, Quality.SD), FallbackStrategy.lowerQualityOrHigherThan(Quality.SD))
Fragen Sie zuerst die Kamerafunktionen ab und wählen Sie dann eine der unterstützten Funktionen aus. Auflösungen mit
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() } }
Beachten Sie, dass die von
QualitySelector.getSupportedQualities()
ist garantiert entweder für denVideoCapture
-Anwendungsfall oder den Kombination ausVideoCapture
- undPreview
-Anwendungsfällen. Bei Bindung mit Anwendungsfall:ImageCapture
oderImageAnalysis
, CameraX kann die Bindung dennoch fehlschlagen, wenn die erforderliche Kombination auf die angeforderte Kamera.
Sobald Sie eine QualitySelector
haben, kann die Anwendung ein
VideoCapture
-Objekt und führen Sie die Bindung aus. Diese Bindung ist
wie bei anderen Anwendungsfällen:
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)
}
bindToLifecycle()
gibt ein Camera
-Objekt zurück. In dieser Anleitung findest du weitere Informationen zur Steuerung der Kameraausgabe, wie z. B. Zoom und Belichtung.
Mit Recorder
wird das am besten geeignete Format für das System ausgewählt. Die meisten
gängiger Video-Codec ist
H.264 AVC) mit
Containerformat
MPEG-4:
Aufzeichnung konfigurieren und erstellen
Aus einem Recorder
kann die App Aufnahmeobjekte erstellen,
die Video- und Audioaufnahme durchzuführen. Anwendungen erstellen Aufzeichnungen
Folgendes:
- Konfigurieren Sie
OutputOptions
mit derprepareRecording()
. - Optional: Aktivieren Sie die Audioaufnahme.
- Mit
start()
registrieren:VideoRecordEvent
und beginnen mit der Videoaufnahme.
Recorder
gibt ein Recording
-Objekt zurück, wenn du die start()
-Funktion aufrufst.
Ihre Anwendung kann dieses Recording
-Objekt verwenden, um die
oder bestimmte Aktionen wie das Pausieren oder Fortsetzen
ausführen.
Eine Recorder
unterstützt jeweils nur ein Recording
-Objekt. Sie können eine
eine neue Aufnahme, nachdem du Recording.stop()
angerufen hast, oder
Recording.close()
für das vorherige Recording
-Objekt.
Sehen wir uns diese Schritte etwas genauer an. Zunächst konfiguriert die Anwendung
OutputOptions
für einen Rekorder mit Recorder.prepareRecording()
.
Ein Recorder
unterstützt die folgenden OutputOptions
-Typen:
FileDescriptorOutputOptions
zum Erfassen in einFileDescriptor
FileOutputOptions
zum Erfassen inFile
.MediaStoreOutputOptions
zum Erfassen in einMediaStore
Bei allen OutputOptions
-Typen können Sie mit
setFileSizeLimit()
. Andere Optionen sind spezifisch für die jeweilige Ausgabe
-Typ, z. B. ParcelFileDescriptor
für die FileDescriptorOutputOptions
.
prepareRecording()
gibt ein PendingRecording
-Objekt zurück, bei dem es sich um
Zwischenobjekt, mit dem das entsprechende
Recording
-Objekt. PendingRecording
ist eine temporäre Klasse, die
in den meisten Fällen unsichtbar und wird selten von der App im Cache gespeichert.
Anwendungen können die Aufzeichnung weiter konfigurieren, z. B.:
- Aktivieren Sie Audio mit
withAudioEnabled()
. - Listener für den Empfang von Videoaufnahmeereignissen registrieren
mit
start(Executor, Consumer<VideoRecordEvent>)
. - Ununterbrochene Aufnahme einer Aufzeichnung erlauben, während VideoCapture an das Video angehängt ist
an eine andere Kamera gebunden.
PendingRecording.asPersistentRecording()
Wenn du die Aufzeichnung starten möchtest, ruf PendingRecording.start()
an. CameraX dreht die
PendingRecording
in eine Recording
ein, stellt die Aufnahmeanfrage in die Warteschlange,
und gibt das neu erstellte Recording
-Objekt an die Anwendung zurück.
Sobald die Aufnahme auf der entsprechenden Kamera beginnt, sendet CameraX eine
VideoRecordEvent.EVENT_TYPE_START
-Ereignis.
Das folgende Beispiel zeigt, wie Sie Video- und Audioinhalte in eine
MediaStore
-Datei:
// 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)
Während die Kameravorschau auf der Frontkamera standardmäßig gespiegelt wird, werden in Videos aufgenommene Videos werden standardmäßig nicht gespiegelt. Mit CameraX 1.3 Videoaufnahmen können jetzt gespiegelt werden, sodass die Frontkamera-Vorschau und Videoaufnahme übereinstimmen.
Es gibt drei MirrorMode-Optionen: MIRROR_MODE_OFF, MIRROR_MODE_ON und
MIRROR_MODE_ON_FRONT_ONLY Um sie am
die Kameravorschau zeigt, empfiehlt Google die Verwendung von MIROR_MODE_ON_FRONT_ONLY. Das bedeutet,
das
Die Spiegelung ist für die Rückkamera nicht aktiviert, für die Frontkamera ist sie aktiviert
Kamera. Weitere Informationen zum Spiegelmodus finden Sie unter
MirrorMode constants
Dieses Code-Snippet zeigt, wie ein
VideoCapture.Builder.setMirrorMode()
mit MIRROR_MODE_ON_FRONT_ONLY
. Für
Weitere Informationen finden Sie unter 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);
Aktive Aufzeichnung steuern
Sie können eine laufende Recording
pausieren, fortsetzen und beenden,
mithilfe der folgenden Methoden:
pause
um die aktuell aktive Aufzeichnung anzuhalten.resume()
um eine pausierte aktive Aufzeichnung fortzusetzen.stop()
um die Aufzeichnung abzuschließen und alle zugehörigen Aufnahmeobjekte zu leeren.mute()
um die aktuelle Aufnahme stummzuschalten bzw. die Stummschaltung aufzuheben.
Beachten Sie, dass Sie unabhängig davon stop()
aufrufen können, um eine Recording
zu beenden.
ob die Aufzeichnung pausiert oder aktiv ist.
Wenn du eine EventListener
registriert hast mit
PendingRecording.start()
, die Recording
kommuniziert
mit einer
VideoRecordEvent
VideoRecordEvent.EVENT_TYPE_STATUS
wird für die Aufzeichnung von Statistiken wie aktuelle Dateigröße und aufgezeichneter Zeitraum.VideoRecordEvent.EVENT_TYPE_FINALIZE
wird für das Aufnahmeergebnis verwendet und Informationen wie den URI der endgültigen Datei sowie eventuellen Fehlern.
Sobald deine App eine EVENT_TYPE_FINALIZE
erhält, die eine erfolgreiche
Aufzeichnungssitzung können Sie dann vom Standort aus auf das aufgenommene Video zugreifen.
in OutputOptions
angegeben.
Weitere Informationen
Weitere Informationen zu CameraX finden Sie in den folgenden zusätzlichen Ressourcen:
- Codelab: Erste Schritte mit CameraX
- Offizielle CameraX-Beispiel-App
- Liste der neuesten CameraX Video Capture API
- Versionshinweise zu CameraX
- CameraX-Quellcode