QMLビデオレコーダー
Qt Quick を使った音声とビデオの録画
QML Recorderは、マイクやカメラ、あるいはスクリーンキャプチャを使って、音声と映像を別々に、あるいは一緒に録画することができるシンプルなアプリケーションです。
例の実行
この例を実行するには Qt Creatorからサンプルを実行するには、Welcome モードを開き、Examples からサンプルを選択します。詳細については、Building and Running an Exampleを参照してください。
概要
Qt Quick を使ってプログラミングを始めよう」を参照してください。このドキュメントでは、このサンプルがどのように Qt Multimedia QML Types.
この例では、CaptureSession に接続された QMLCamera とAudioInput を使用しています。MediaRecorder オブジェクトは、キャプチャされた音声と映像を記録するために使用されます。
QtMultimedia に加え、Qt Quick Windows、Controls、Layoutsの機能を使い、グラフィックユーザーインターフェースと機能を実装しています。再生については、QML Media Player Exampleを参照してください。
この例では、次のようなことを実現しています:
- 入力デバイスの選択
- 入力デバイスの選択。
- 品質、コーデックの選択、ファイル形式、メタデータの割り当てなど、キャプチャのための設定。
- キャプチャされたファイルは保存され、再生することができます。
録画
アプリケーションは録画を実装しています。
キャプチャセッション
main.qml
では、captureSession
のように宣言されています:
CaptureSession { id: captureSession recorder: recorder audioInput: controls.audioInput camera: controls.camera screenCapture: controls.screenCapture windowCapture: controls.windowCapture videoOutput: videoOutput }
レコーダー
main.qml
では、MediaRecorder recorder
、メディアの記録と、ファイルのサムネイルをキャプチャして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
は で宣言されている。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
コントロール
これらはControls.qml
で定義され、main.qmlで宣言されている。
そのルートはColumns inputControls
recordButton
optionButtons
を含むRow であり、それぞれ独自の .qml ファイルで定義されています。
ビデオソースの選択
VideoSourceSelect.qml
で定義されているVideoSourceSlect
は、Switch とComboBox で構成され、利用可能なカメラから選択することができます。
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
上記のスニペットで宣言された「ビデオ・ソース」は、現在のビデオ・ソースを割り当てます。
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
音声入力の選択
ビデオソースの選択と同じように実装され、AudioInputSelect.qml
で次のように定義されています:
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.