QML-Videorekorder
Aufnahme von Audio und Video mit Qt Quick.
QML Recorder demonstriert eine einfache Anwendung, die Audio und Video getrennt oder zusammen aufzeichnen kann, unter Verwendung eines Mikrofons, einer Kamera oder mit Bildschirmaufzeichnung.
Ausführen des Beispiels
Zum Ausführen des Beispiels von Qt Creatorzu starten, öffnen Sie den Modus Welcome und wählen Sie das Beispiel aus Examples. Weitere Informationen finden Sie unter Erstellen und Ausführen eines Beispiels.
Überblick
Im Kern handelt es sich um eine QML-Anwendung, siehe Erste Schritte in der Programmierung mit Qt Quick. Diese Dokumentation konzentriert sich darauf, wie dieses Beispiel die Qt Multimedia QML Types.
Das Beispiel verwendet die QML-Typen Camera und AudioInput, die mit einem CaptureSession verbunden sind. Ein MediaRecorder -Objekt wird dann verwendet, um die erfassten Audio- und Videodaten aufzuzeichnen.
Zusätzlich zu QtMultimedia werden Funktionen von Qt Quick Windows, Controls und Layouts verwendet, um die grafische Benutzeroberfläche und Funktionalität zu implementieren. Die Wiedergabe wird hier nicht behandelt, siehe dazu das QML Media Player-Beispiel.
Das Beispiel demonstriert das Folgende:
- Eingabegeräte können ausgewählt werden.
- Ein Eingabetyp kann ausgeschaltet werden.
- Einstellungen für das Capturing wie Qualität, Codec-Auswahl, Dateiformat und Zuweisung von Metadaten.
- Erfasste Dateien werden gespeichert und können wiedergegeben werden.
Aufzeichnung
Die Anwendung implementiert die Aufzeichnung.
captureSession
In main.qml
wird captureSession
wie folgt deklariert:
CaptureSession { id: captureSession recorder: recorder audioInput: controls.audioInput camera: controls.camera screenCapture: controls.screenCapture windowCapture: controls.windowCapture videoOutput: videoOutput }
recorder
In main.qml
behandelt MediaRecorder recorder
die Aufnahme von Medien sowie die Erfassung einer Miniaturansicht für die Datei und deren Anhängen an ein ListModel, mediaList
.
MediaRecorder { id: recorder onRecorderStateChanged: (state) => { if (state === MediaRecorder.StoppedState) { root.contentOrientation = Qt.PrimaryOrientation mediaList.append() } else if (state === MediaRecorder.RecordingState && captureSession.camera) { // lock orientation while recording and create a preview image root.contentOrientation = root.screen.orientation; videoOutput.grabToImage(function(res) { mediaList.mediaThumbnail = res.url }) } } onActualLocationChanged: (url) => { mediaList.mediaUrl = url } onErrorOccurred: { recorderErrorText.text = recorder.errorString; recorderError.open(); } }
mediaList
wird im Frame deklariert. mediaListFrame
Frame { id: mediaListFrame height: 150 width: parent.width anchors.bottom: controlsFrame.top x: controls.capturesVisible ? 0 : parent.width background: Rectangle { anchors.fill: parent color: palette.base opacity: 0.8 } Behavior on x { NumberAnimation { duration: 200 } } MediaList { id: mediaList anchors.fill: parent playback: playback
Steuerelemente
Diese sind in Controls.qml
definiert und in main.qml deklariert.
Die Wurzel ist eine Row, die die Columns inputControls
, recordButton
, optionButtons
enthält, die jeweils in ihren eigenen .qml-Dateien definiert sind.
Auswählen einer Videoquelle
Definiert in VideoSourceSelect.qml
, besteht VideoSourceSlect
aus einer Switch und einer ComboBox und ermöglicht dem Benutzer die Auswahl aus den verfügbaren Kameras.
Row { id: root height: Style.height property Camera selectedCamera: cameraAvailable ? camera : null property ScreenCapture selectedScreenCapture: screenAvailable ? screenCapture : null property WindowCapture selectedWindowCapture: windowAvailable ? windowCapture : null property bool sourceAvailable: typeof comboBox.currentValue !== 'undefined' && comboBox.currentValue.type !== 'toggler' && videoSourceSwitch.checked property bool cameraAvailable: sourceAvailable && comboBox.currentValue.type === 'camera' property bool screenAvailable: sourceAvailable && comboBox.currentValue.type === 'screen' property bool windowAvailable: sourceAvailable && comboBox.currentValue.type === 'window' Component.onCompleted: { videoSourceModel.populate() for (var i = 0; i < videoSourceModel.count; i++) { if (videoSourceModel.get(i).value.type !== 'toggler') { comboBox.currentIndex = i break } } } Camera { id: camera active: cameraAvailable } ScreenCapture { id: screenCapture active: screenAvailable } WindowCapture { id: windowCapture active: windowAvailable } MediaDevices { id: mediaDevices onVideoInputsChanged: { videoSourceModel.populate() for (var i = 0; i < videoSourceModel.count; i++) { if (videoSourceModel.get(i).value.type !== 'toggler') { comboBox.currentIndex = i break } } } } Switch { id: videoSourceSwitch anchors.verticalCenter: parent.verticalCenter checked: true } ListModel { id: videoSourceModel property var enabledSources: { 'camera': true, 'screen': true, 'window': false } function toggleEnabledSource(type) { enabledSources[type] = !enabledSources[type] populate() } function appendItem(text, value) { append({ text: text, value: value}) } function appendToggler(name, sourceType) { appendItem((enabledSources[sourceType] ? "- Hide " : "+ Show ") + name, { type: 'toggler', 'sourceType': sourceType }) } function populate() { clear() appendToggler('Cameras', 'camera') if (enabledSources['camera']) for (var camera of mediaDevices.videoInputs) appendItem(camera.description, { type: 'camera', camera: camera }) appendToggler('Screens', 'screen') if (enabledSources['screen']) for (var screen of Application.screens) appendItem(screen.name, { type: 'screen', screen: screen }) appendToggler('Windows', 'window') if (enabledSources['window']) for (var window of windowCapture.capturableWindows()) appendItem(window.description, { type: 'window', window: window }) } }
comboBox
Die im obigen Ausschnitt deklarierte Funktion "Video" weist die aktuelle Videoquelle zu.
ComboBox { id: comboBox width: Style.widthLong height: Style.height background: StyleRectangle { anchors.fill: parent } model: videoSourceModel displayText: typeof currentValue === 'undefined' || currentValue.type === 'toggler' ? "Unavailable" : currentText font.pointSize: Style.fontSize textRole: "text" valueRole: "value" onCurrentValueChanged: { if (typeof currentValue === 'undefined') return if (currentValue.type === 'screen') screenCapture.screen = currentValue.screen else if (currentValue.type === 'camera') camera.cameraDevice = currentValue.camera
Auswählen eines Audioeingangs
Wird auf dieselbe Weise wie die Auswahl einer Videoquelle implementiert und in AudioInputSelect.qml
wie folgt definiert:
Row { id: root height: Style.height property AudioInput selected: available ? audioInput : null property bool available: (typeof comboBox.currentValue !== 'undefined') && audioSwitch.checked Component.onCompleted: { audioInputModel.populate() comboBox.currentIndex = 0 } MediaDevices { id: mediaDevices } AudioInput { id: audioInput; muted: !audioSwitch.checked } Switch { id: audioSwitch; height: Style.height; checked: true } ListModel { id: audioInputModel property var audioInputs: mediaDevices.audioInputs function populate() { audioInputModel.clear() for (var audioDevice of audioInputs) audioInputModel.append({ text: audioDevice.description, value: { type: 'audioDevice', audioDevice: audioDevice } }) } } ComboBox { id: comboBox width: Style.widthLong height: Style.height background: StyleRectangle { anchors.fill: parent } model: audioInputModel textRole: "text" font.pointSize: Style.fontSize displayText: typeof currentValue === 'undefined' ? "unavailable" : currentText valueRole: "value"
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.