// file: poc-qt/poc004/qml/main.qml import QtQuick import QtQuick.Controls import QtQuick.Layouts import QtMultimedia ApplicationWindow { visible: true width: 1100 height: 760 title: "POC004 - Webcam + Micro + Capture + Record" MediaDevices { id: mediaDevices } Camera { id: camera cameraDevice: mediaDevices.defaultVideoInput } AudioInput { id: microphone } ImageCapture { id: imageCapture onImageSaved: function(requestId, filePath) { statusLabel.text = "Image saved: " + filePath } onErrorOccurred: function(requestId, error, errorString) { statusLabel.text = "Image error: " + errorString } } MediaRecorder { id: recorder quality: MediaRecorder.VeryHighQuality onRecorderStateChanged: { if (recorder.recorderState === MediaRecorder.RecordingState) { statusLabel.text = "Recording video..." } else if (recorder.recorderState === MediaRecorder.StoppedState) { statusLabel.text = "Recorder stopped" } } onErrorOccurred: function(error, errorString) { statusLabel.text = "Recorder error: " + errorString } } CaptureSession { id: captureSession camera: camera audioInput: microphone imageCapture: imageCapture recorder: recorder videoOutput: videoOutput } ColumnLayout { anchors.fill: parent anchors.margins: 12 spacing: 10 Rectangle { Layout.fillWidth: true Layout.fillHeight: true color: "black" border.width: 1 border.color: "#555" VideoOutput { id: videoOutput anchors.fill: parent fillMode: VideoOutput.PreserveAspectFit } } RowLayout { Layout.fillWidth: true spacing: 8 Button { text: camera.active ? "Stop camera" : "Start camera" onClicked: { camera.active = !camera.active if (camera.active) { statusLabel.text = "Camera started" } else { statusLabel.text = "Camera stopped" } } } Button { text: "Take snapshot" onClicked: { imageCapture.captureToFile("/home/sinus/Projects/poc-qt/target/captures_imgs/image_" + Date.now() + ".jpg") } } Button { text: recorder.recorderState === MediaRecorder.RecordingState ? "Stop recording" : "Start recording" onClicked: { if (recorder.recorderState === MediaRecorder.RecordingState) { recorder.stop() } else { recorder.outputLocation = "file:///home/sinus/Projects/poc-qt/target/captures_vids/video_" + Date.now() + ".mp4" recorder.record() } } } Button { text: "Restart camera" onClicked: { camera.stop() camera.start() } } } RowLayout { Layout.fillWidth: true spacing: 8 Label { text: mediaDevices.videoInputs.length > 0 ? ("Camera: " + camera.cameraDevice.description) : "No camera detected" Layout.fillWidth: true wrapMode: Text.WrapAnywhere } Label { text: "Mic active" } } Label { id: statusLabel Layout.fillWidth: true text: "Ready" wrapMode: Text.WrapAnywhere } ListView { Layout.fillWidth: true Layout.preferredHeight: 120 clip: true model: mediaDevices.videoInputs delegate: Rectangle { width: ListView.view.width height: 32 color: camera.cameraDevice.id === modelData.id ? "#334" : "transparent" Text { anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left anchors.leftMargin: 8 text: modelData.description color: "white" } MouseArea { anchors.fill: parent onClicked: { camera.stop() camera.cameraDevice = modelData camera.start() statusLabel.text = "Switched camera to: " + modelData.description } } } } } Component.onCompleted: { if (mediaDevices.videoInputs.length > 0) { camera.start() statusLabel.text = "Camera started" } else { statusLabel.text = "No camera detected" } } }