Enregistreur vidéo QML
Enregistrement audio et vidéo à l'aide de Qt Quick.

QML Recorder présente une application simple qui peut enregistrer de l'audio et de la vidéo séparément ou ensemble, à l'aide d'un microphone, d'une caméra ou d'une capture d'écran.
Exécution de l'exemple
Pour exécuter l'exemple à partir de Qt Creatorouvrez le mode Welcome et sélectionnez l'exemple à partir de Examples. Pour plus d'informations, voir Qt Creator: Tutoriel : Construire et exécuter.
Vue d'ensemble
Au fond, il s'agit d'une application QML, voir Premiers pas avec les applications Qt Quick . Cette documentation se concentre sur la façon dont cet exemple utilise la méthode Qt Multimedia QML Types.
L'exemple utilise les types QML Camera et AudioInput connectés à un objet CaptureSession. Un objet MediaRecorder est ensuite utilisé pour enregistrer l'audio et la vidéo capturés.
En plus de QtMultimedia, les caractéristiques de Qt Quick Windows, Controls et Layouts sont utilisées pour implémenter l'interface utilisateur graphique et la fonctionnalité. La lecture ne sera pas abordée ici, pour cela voir l'exemple de lecteur multimédia QML.
L'exemple démontre ce qui suit :
- Les périphériques d'entrée peuvent être sélectionnés.
- Un type d'entrée peut être désactivé.
- Paramètres de capture tels que la qualité, le choix du codec, le format de fichier et l'attribution de métadonnées.
- Les fichiers capturés sont stockés et peuvent être lus.
Enregistrement
L'application implémente l'enregistrement.
captureSession
Dans Main.qml, captureSession est déclaré comme suit :
CaptureSession { id: captureSession recorder: recorder audioInput: controls.audioInput camera: controls.camera screenCapture: controls.screenCapture windowCapture: controls.windowCapture videoOutput: videoOutput }
recorder
Dans Main.qml, la session MediaRecorder recorder gère l'enregistrement des médias ainsi que la capture d'une vignette pour le fichier et son ajout à un modèle de liste (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 = Screen.orientation; videoOutput.grabToImage(function(res) { mediaList.mediaThumbnail = res.url }) } } onActualLocationChanged: (url) => { mediaList.mediaUrl = url } onErrorOccurred: { recorderErrorText.text = recorder.errorString; recorderError.open(); } }
mediaList est déclaré dans le fichier Frame 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
contrôles
Ceux-ci sont définis dans Controls.qml et déclarés dans Main.qml.
Sa racine est un Row qui contient les Columns inputControls , recordButton, optionButtons, chacun défini dans son propre fichier .qml.
Sélection d'une source vidéo
Défini dans VideoSourceSelect.qml, VideoSourceSlect est composé de Switch et ComboBox et permet à l'utilisateur de choisir parmi les caméras disponibles.
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: root.cameraAvailable && PermissionHelper.cameraStatus === Qt.PermissionStatus.Granted } ScreenCapture { id: screenCapture active: root.screenAvailable } WindowCapture { id: windowCapture active: root.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 }) } }
comboBoxLe fichier .qml , déclaré dans l'extrait ci-dessus, attribue la source vidéo actuelle.
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
Sélection d'une entrée audio
Cette fonction est mise en œuvre de la même manière que la sélection d'une source vidéo et est définie dans AudioInputSelect.qml de la manière suivante :
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"
© 2026 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.