diff options
author | Piotr Srebrny <piotr.srebrny@qt.io> | 2021-06-28 16:50:33 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2021-07-01 12:37:42 +0200 |
commit | 9b14b2878a4690e8c2d3781b8845730d1a4f4cd1 (patch) | |
tree | e941b85b0ebcc78fb0ece433c97e4f6b3c94aa25 /examples/multimedia/video/recorder | |
parent | 53c11b72114fe262e4ba95a92b29fe7f92090678 (diff) |
Add a simple recorder app for capturing audio or audio/video streams
Change-Id: Iad6e33f6ec77aa28121b8b0d1b9c0ae32616c30e
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'examples/multimedia/video/recorder')
17 files changed, 1487 insertions, 0 deletions
diff --git a/examples/multimedia/video/recorder/AudioInputSelect.qml b/examples/multimedia/video/recorder/AudioInputSelect.qml new file mode 100644 index 000000000..5295b56f4 --- /dev/null +++ b/examples/multimedia/video/recorder/AudioInputSelect.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtMultimedia + +Row { + id: root + + property AudioInput selected: available ? audioInput : null + property bool available: (typeof comboBox.currentValue !== 'undefined') && audioSwitch.checked + + MediaDevices { id: mediaDevices } + + AudioInput { id: audioInput; muted: false } + + Switch { id: audioSwitch } + + ComboBox { + id: comboBox + width: Style.widthLong + height: parent.height + background: StyleRectangle { anchors.fill: parent } + model: mediaDevices.audioInputs + textRole: "description" + displayText: typeof currentValue === 'undefined' ? "unavailable" : currentValue.description + onCurrentValueChanged: if (typeof comboBox.currentValue !== 'undefined') audioInput.device = currentValue + } +} diff --git a/examples/multimedia/video/recorder/CMakeLists.txt b/examples/multimedia/video/recorder/CMakeLists.txt new file mode 100644 index 000000000..794fcac04 --- /dev/null +++ b/examples/multimedia/video/recorder/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.14) + +project(recorder LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(QT NAMES Qt6 COMPONENTS Core Quick Multimedia REQUIRED) +find_package(Qt6 COMPONENTS Core Quick Multimedia REQUIRED) + +set(PROJECT_SOURCES + main.cpp + qml.qrc +) + +qt_add_executable(recorder + ${PROJECT_SOURCES} +) + +target_compile_definitions(recorder + PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>) +target_link_libraries(recorder + PRIVATE Qt6::Core Qt6::Quick Qt6::Multimedia) diff --git a/examples/multimedia/video/recorder/CameraSelect.qml b/examples/multimedia/video/recorder/CameraSelect.qml new file mode 100644 index 000000000..61c834f34 --- /dev/null +++ b/examples/multimedia/video/recorder/CameraSelect.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtMultimedia + +Row { + id: root + + property Camera selected: available ? camera : null + property bool available: (typeof comboBox.currentValue !== 'undefined') && cameraSwitch.checked + + Camera { + id: camera + active: available + } + + MediaDevices { id: mediaDevices } + + Switch { id: cameraSwitch } + + ComboBox { + id: comboBox + width: Style.widthLong + height: parent.height + background: StyleRectangle { anchors.fill: parent } + model: mediaDevices.videoInputs + displayText: typeof currentValue === 'undefined' ? "Unavailable" : currentValue.description + textRole: "description" + onCurrentValueChanged: if (typeof comboBox.currentValue !== 'undefined') camera.cameraDevice = currentValue + } +} diff --git a/examples/multimedia/video/recorder/Controls.qml b/examples/multimedia/video/recorder/Controls.qml new file mode 100644 index 000000000..ff810181f --- /dev/null +++ b/examples/multimedia/video/recorder/Controls.qml @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtMultimedia + +RowLayout { + id: root + + required property MediaRecorder recorder + + property bool settingsVisible: false + property bool capturesVisible: false + + property alias audioInput: audioInputSelect.selected + property alias camera: cameraSelect.selected + + Column { + id: inputControls + spacing: Style.intraSpacing + + CameraSelect { id: cameraSelect } + AudioInputSelect { id: audioInputSelect } + } + + Item { + // Position RecordButton in the center + Layout.minimumWidth: root.width / 2 - inputControls.width - recordButton.width / 2 + } + + Column { + width: recordButton.width + RecordButton { + id: recordButton + recording: recorder.recorderState === MediaRecorder.RecordingState + onClicked: recording ? recorder.stop() : recorder.record() + } + Text { + id: recordingTime + anchors.horizontalCenter: parent.horizontalCenter + } + } + + Item { + Layout.fillWidth: true + } + + Column { + spacing: Style.intraSpacing + Button { + height: Style.height + width: Style.widthShort + background: StyleRectangle { anchors.fill: parent } + onClicked: root.capturesVisible = !root.capturesVisible + text: "Captures" + } + Button { + height: Style.height + width: Style.widthShort + background: StyleRectangle { anchors.fill: parent } + onClicked: root.settingsVisible = !root.settingsVisible + text: "Settings" + } + } + + Timer { + running: true; interval: 100; repeat: true + onTriggered: { + var m = Math.floor(recorder.duration / 60000) + var ms = (recorder.duration / 1000 - m * 60).toFixed(1) + recordingTime.text = `${m}:${ms.padStart(4, 0)}` + } + } +} diff --git a/examples/multimedia/video/recorder/MediaList.qml b/examples/multimedia/video/recorder/MediaList.qml new file mode 100644 index 000000000..33c65d32c --- /dev/null +++ b/examples/multimedia/video/recorder/MediaList.qml @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtMultimedia +import QtQuick.Layouts + +Item { + id: root + + required property Playback playback + + property string mediaThumbnail + property string mediaUrl + + function append() { + if (mediaUrl !== "") + mediaList.append({"thumbnail": root.mediaThumbnail, "url": root.mediaUrl}) + mediaThumbnail = "" + mediaUrl = "" + } + + ListModel { id: mediaList } + + ListView { + id: listView + anchors.fill: parent + model: mediaList + orientation: ListView.Horizontal + spacing: Style.intraSpacing + + delegate: Frame { + padding: Style.intraSpacing + width: root.height + height: root.height + background: StyleRectangle { anchors.fill: parent } + + required property string url + required property string thumbnail + + ColumnLayout { + anchors.fill: parent + Image { + id: image + Layout.fillWidth: true + Layout.fillHeight: true + source: thumbnail + fillMode: Image.PreserveAspectFit + } + + Text { + Layout.fillWidth: true + elide: Text.ElideLeft + text: url + } + } + RoundButton { + anchors.centerIn: parent + width: 30 + height: 30 + text: "\u25B6"; + onClicked: { playback.playUrl(url) } + } + } + } +} diff --git a/examples/multimedia/video/recorder/Playback.qml b/examples/multimedia/video/recorder/Playback.qml new file mode 100644 index 000000000..921e53ac2 --- /dev/null +++ b/examples/multimedia/video/recorder/Playback.qml @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtMultimedia +import QtQuick.Controls + +Item { + id: root + + required property VideoOutput videoOutput + property bool active: false + + function playUrl(url) { + root.active = true + mediaPlayer.videoOutput = videoOutput + mediaPlayer.audioOutput = audioOutput + mediaPlayer.source = url + mediaPlayer.play() + } + + function stop() { + mediaPlayer.stop() + mediaPlayer.videoOutput = null + mediaPlayer.audioOutput = null + root.active = false + } + + AudioOutput { id: audioOutput } + + MediaPlayer { id: mediaPlayer } + + HoverHandler { id: hover } + + RoundButton { + width: 50 + height: 50 + opacity: hover.hovered && active ? 1.0 : 0.0 + anchors.centerIn: root + radius: 25 + text: "\u25A0"; + onClicked: root.stop() + + Behavior on opacity { NumberAnimation { duration: 200 } } + } +} diff --git a/examples/multimedia/video/recorder/RecordButton.qml b/examples/multimedia/video/recorder/RecordButton.qml new file mode 100644 index 000000000..d83fd0ffa --- /dev/null +++ b/examples/multimedia/video/recorder/RecordButton.qml @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtMultimedia + +Item { + id: root + width: outerRadius * 2 + height: outerRadius * 2 + + required property bool recording + + property int outerRadius: 25 + property int innerRadius: mouse.pressedButtons === Qt.LeftButton ? outerRadius - 6 : outerRadius - 5 + + signal clicked + + Rectangle { + anchors.fill: parent + radius: outerRadius + opacity: 0.5 + border.color: "black" + border.width: 1 + } + + Rectangle { + anchors.centerIn: parent + width: recording ? innerRadius * 2 - 15 : innerRadius * 2 + height: recording ? innerRadius * 2 - 15 : innerRadius * 2 + radius: recording ? 2 : innerRadius + color: "red" + + Behavior on width { NumberAnimation { duration: 100 }} + Behavior on height { NumberAnimation { duration: 100 }} + Behavior on radius { NumberAnimation { duration: 100 }} + + MouseArea { + id: mouse + anchors.fill: parent + onClicked: root.clicked() + } + } +} diff --git a/examples/multimedia/video/recorder/SettingsEncoder.qml b/examples/multimedia/video/recorder/SettingsEncoder.qml new file mode 100644 index 000000000..c129eaed0 --- /dev/null +++ b/examples/multimedia/video/recorder/SettingsEncoder.qml @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtMultimedia + +Column { + id: root + spacing: Style.intraSpacing + Component.onCompleted: root.populateModels() + + required property MediaRecorder recorder + + function populateModels() { + audioCodecModel.populate() + videoCodecModel.populate() + fileFormatModel.populate() + } + + Connections { + target: recorder + function onMediaFormatChanged() { root.populateModels() } + } + + Text { text: "Encoder settings" } + + StyleParameter { + label: "Quality" + model: ListModel { + ListElement { text: "very low"; value: MediaRecorder.VeryLowQuality } + ListElement { text: "low"; value: MediaRecorder.LowQuality } + ListElement { text: "normal"; value: MediaRecorder.NormalQuality } + ListElement { text: "high"; value: MediaRecorder.HighQuality } + ListElement { text: "very high"; value: MediaRecorder.VeryHighQuality } + } + onActivated: (v) => { recorder.quality = v } + } + + StyleParameter { + id: audioCodecSelect + label: "Audio codec" + model: audioCodecModel + onActivated: (v) => { recorder.mediaFormat.audioCodec = v } + + ListModel { + id: audioCodecModel + function populate() { + audioCodecModel.clear() + audioCodecModel.append({"text": "Unspecifed", "value": MediaFormat.AudioCodec.Unspecified}) + var cs = recorder.mediaFormat.supportedAudioCodecs(MediaFormat.Encode) + for (var c of cs) + audioCodecModel.append({"text": recorder.mediaFormat.audioCodecName(c), "value": c}) + audioCodecSelect.currentIndex = cs.indexOf(recorder.mediaFormat.audioCodec) + 1 + } + } + } + + function buildModel() {} + + StyleParameter { + id: videoCodecSelect + label: "Video codec" + model: videoCodecModel + onActivated: (v) => { recorder.mediaFormat.videoCodec = v } + + ListModel { + id: videoCodecModel + function populate() { + videoCodecModel.clear() + videoCodecModel.append({"text": "Unspecifed", "value": MediaFormat.VideoCodec.Unspecified}) + var cs = recorder.mediaFormat.supportedVideoCodecs(MediaFormat.Encode) + for (var c of cs) + videoCodecModel.append({"text": recorder.mediaFormat.videoCodecName(c), "value": c}) + videoCodecSelect.currentIndex = cs.indexOf(recorder.mediaFormat.videoCodec) + 1 + } + } + } + + StyleParameter { + id: fileFormatSelect + label: "File format" + model: fileFormatModel + onActivated: (v) => { recorder.mediaFormat.fileFormat = v } + + ListModel { + id: fileFormatModel + function populate() { + fileFormatModel.clear() + fileFormatModel.append({"text": "Unspecifed", "value": MediaFormat.AudioCodec.Unspecified}) + var cs = recorder.mediaFormat.supportedFileFormats(MediaFormat.Encode) + for (var c of cs) + fileFormatModel.append({"text": recorder.mediaFormat.fileFormatName(c), "value": c}) + fileFormatSelect.currentIndex = cs.indexOf(recorder.mediaFormat.fileFormat) + 1 + } + } + } +} diff --git a/examples/multimedia/video/recorder/SettingsMetaData.qml b/examples/multimedia/video/recorder/SettingsMetaData.qml new file mode 100644 index 000000000..618995022 --- /dev/null +++ b/examples/multimedia/video/recorder/SettingsMetaData.qml @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtMultimedia + +ColumnLayout { + required property MediaRecorder recorder + + Text { text: "Metadata settings" } + + ListModel { id: metaDataModel } + + Connections { + target: recorder + function onMetaDataChanged() { + metaDataModel.clear() + for (var key of recorder.metaData.keys()) { + if (recorder.metaData.stringValue(key)) + metaDataModel.append( + { text: recorder.metaData.metaDataKeyToString(key) + , value: key }) + } + } + } + + Row { + id: metaDataAdd + spacing: Style.intraSpacing + ComboBox { + id: metaDataType + width: (Style.widthLong + Style.widthShort)/2 + height: parent.height + model: ListModel { + ListElement { text: "Title"; value: MetaData.Title } + ListElement { text: "Author"; value: MetaData.Author } + ListElement { text: "Comment"; value: MetaData.Comment } + ListElement { text: "Description"; value: MetaData.Description } + ListElement { text: "Genre"; value: MetaData.Genre } + ListElement { text: "Publisher"; value: MetaData.Publisher } + ListElement { text: "Copyright"; value: MetaData.Copyright } + ListElement { text: "Date"; value: MetaData.Date } + ListElement { text: "Url"; value: MetaData.Url } + ListElement { text: "MediaType"; value: MetaData.MediaType } + ListElement { text: "AlbumTitle"; value: MetaData.AlbumTitle } + ListElement { text: "AlbumArtist"; value: MetaData.AlbumArtist } + ListElement { text: "ContributingArtist"; value: MetaData.ContributingArtist } + ListElement { text: "Composer"; value: MetaData.Composer } + ListElement { text: "LeadPerformer"; value: MetaData.LeadPerformer } + } + textRole: "text" + valueRole: "value" + background: StyleRectangle { width: metaDataType.width } + } + Item { + width: Style.widthMedium + height: Style.height + StyleRectangle { anchors.fill: parent } + TextInput { + id: textInput + anchors.fill: parent + anchors.margins: 4 + clip: true + onAccepted: { + recorder.metaData.insert(metaDataType.currentValue, text) + recorder.metaDataChanged() + text = "" + } + } + } + Button { + width: Style.widthTiny + height: Style.height + text: "add" + background: StyleRectangle { anchors.fill: parent } + onClicked: textInput.accepted() + } + } + + ListView { + id: listView + Layout.fillHeight: true + Layout.minimumWidth: metaDataAdd.width + spacing: Style.intraSpacing + clip: true + model: metaDataModel + + delegate: Row { + id: r + height: Style.height + spacing: Style.intraSpacing + + required property string text + required property string value + + Text { + width: Style.widthShort + height: Style.height + text: r.text + horizontalAlignment: Text.AlignRight + verticalAlignment: Text.AlignVCenter + } + Item { + width: Style.widthMedium + height: Style.height + StyleRectangle { anchors.fill: parent } + TextInput { + anchors.fill: parent + anchors.margins: 4 + clip: true + text: recorder.metaData.stringValue(r.value) + onAccepted: recorder.metaData.insert(r.value, text) + } + } + Button { + width: Style.widthTiny + height: Style.height + text: "del" + background: StyleRectangle { anchors.fill: parent } + onClicked: { recorder.metaData.remove(r.value); recorder.metaDataChanged() } + } + } + } +} diff --git a/examples/multimedia/video/recorder/Style.qml b/examples/multimedia/video/recorder/Style.qml new file mode 100644 index 000000000..8e1136e92 --- /dev/null +++ b/examples/multimedia/video/recorder/Style.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +pragma Singleton +import QtQuick + +QtObject { + property real height: 25 + property real widthTiny: 40 + property real widthShort: 80 + property real widthMedium: 160 + property real widthLong: 240 + property real intraSpacing: 5 + property real interSpacing: 15 +} diff --git a/examples/multimedia/video/recorder/StyleParameter.qml b/examples/multimedia/video/recorder/StyleParameter.qml new file mode 100644 index 000000000..d797a0130 --- /dev/null +++ b/examples/multimedia/video/recorder/StyleParameter.qml @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Row { + id: root + spacing: Style.intraSpacing + + property alias label: label.text + property alias model: comboBox.model + property alias currentIndex: comboBox.currentIndex + property alias currentValue: comboBox.currentValue + property bool enabled: true + signal activated(var currentValue) + + Text { + id: label + height: Style.height + width: Style.widthShort + horizontalAlignment: Text.AlignRight + verticalAlignment: Text.AlignVCenter + color: root.enabled ? "black" : "gray" + } + + ComboBox { + id: comboBox + height: Style.height + width: Style.widthMedium + enabled: root.enabled + + displayText: currentText + textRole: "text" + valueRole: "value" + + background: StyleRectangle { anchors.fill: parent } + onActivated: root.activated(currentValue) + } +} diff --git a/examples/multimedia/video/recorder/StyleRectangle.qml b/examples/multimedia/video/recorder/StyleRectangle.qml new file mode 100644 index 000000000..7e9186fc8 --- /dev/null +++ b/examples/multimedia/video/recorder/StyleRectangle.qml @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +Rectangle { + opacity: 0.5 + border.color: "black" + border.width: 1 + radius: 3 +} diff --git a/examples/multimedia/video/recorder/StyleSlider.qml b/examples/multimedia/video/recorder/StyleSlider.qml new file mode 100644 index 000000000..5f8e12309 --- /dev/null +++ b/examples/multimedia/video/recorder/StyleSlider.qml @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Row { + id: root + spacing: Style.intraSpacing + + property alias label: label.text + property alias from: slider.from + property alias to: slider.to + property alias value: slider.value + property bool enabled: true + + signal moved(real currentValue) + + Text { + id: label + width: Style.valueWidth + height: Style.height + horizontalAlignment: Text.AlignRight + verticalAlignment: Text.AlignVCenter + color: root.enabled ? "black" : "gray" + } + + Slider { + id: slider + anchors.verticalCenter: label.verticalCenter + width: Style.widthMedium + enabled: root.enabled + onMoved: root.moved(value) + } +} diff --git a/examples/multimedia/video/recorder/main.cpp b/examples/multimedia/video/recorder/main.cpp new file mode 100644 index 000000000..21067f50d --- /dev/null +++ b/examples/multimedia/video/recorder/main.cpp @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QGuiApplication> +#include <QQmlApplicationEngine> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + const QUrl url(QStringLiteral("qrc:/main.qml")); + QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, + &app, [url](QObject *obj, const QUrl &objUrl) { + if (!obj && url == objUrl) + QCoreApplication::exit(-1); + }, Qt::QueuedConnection); + engine.load(url); + + return app.exec(); +} diff --git a/examples/multimedia/video/recorder/main.qml b/examples/multimedia/video/recorder/main.qml new file mode 100644 index 000000000..c9c58eaa2 --- /dev/null +++ b/examples/multimedia/video/recorder/main.qml @@ -0,0 +1,183 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls +import QtMultimedia + +Window { + id: root + width: 800 + height: 600 + visible: true + title: "Media recorder" + + VideoOutput { + id: videoOutput + anchors.fill: parent + } + + Popup { + id: recorderError + anchors.centerIn: Overlay.overlay + Text { id: recorderErrorText } + } + + CaptureSession { + id: captureSession + encoder: recorder + audioInput: controls.audioInput + camera: controls.camera + videoOutput: playback.active ? null : videoOutput + } + + MediaRecorder { + id: recorder + onRecorderStateChanged: + (state) => { + if (state === MediaRecorder.StoppedState) + mediaList.append() + else if (state === MediaRecorder.RecordingState && captureSession.camera) + videoOutput.grabToImage(function(res) { mediaList.mediaThumbnail = res.url }) + } + onActualLocationChanged: (url) => { mediaList.mediaUrl = url } + onErrorOccurred: { recorderErrorText.text = recorder.errorString; recorderError.open(); } + } + + Playback { + id: playback + anchors { + top: parent.top + left: parent.left + right: parent.right + bottom: controls.capturesVisible ? mediaListFrame.top : controlsFrame.top + margins: 50 + } + videoOutput: videoOutput + } + + Frame { + id: mediaListFrame + height: 150 + width: parent.width + anchors.bottom: controlsFrame.top + x: controls.capturesVisible ? 0 : parent.width + background: Rectangle { + anchors.fill: parent + color: "white" + opacity: 0.8 + } + + Behavior on x { NumberAnimation { duration: 200 } } + + MediaList { + id: mediaList + anchors.fill: parent + playback: playback + } + } + + Frame { + id: controlsFrame + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + } + height: controlsAndSettings.height + background: Rectangle { + anchors.fill: parent + color: "white" + opacity: 0.8 + } + + Behavior on height { NumberAnimation { duration: 100 } } + + Column { + id: controlsAndSettings + anchors { + left: parent.left + right: parent.right + } + padding: Style.interSpacing + spacing: Style.interSpacing + + property real widthWithPadding: width - padding * 2 + + Controls { + id: controls + width: parent.widthWithPadding + recorder: recorder + } + + StyleRectangle { + visible: controls.settingsVisible + width: parent.widthWithPadding + height: 1 + } + + Row { + visible: controls.settingsVisible + width: parent.widthWithPadding + spacing: Style.interSpacing + + SettingsEncoder { + recorder: recorder + } + + SettingsMetaData { + height: parent.height + recorder: recorder + } + } + } + } +} diff --git a/examples/multimedia/video/recorder/qml.qrc b/examples/multimedia/video/recorder/qml.qrc new file mode 100644 index 000000000..a81fc822a --- /dev/null +++ b/examples/multimedia/video/recorder/qml.qrc @@ -0,0 +1,18 @@ +<RCC> + <qresource prefix="/"> + <file>main.qml</file> + <file>MediaList.qml</file> + <file>AudioInputSelect.qml</file> + <file>CameraSelect.qml</file> + <file>RecordButton.qml</file> + <file>Controls.qml</file> + <file>StyleParameter.qml</file> + <file>StyleRectangle.qml</file> + <file>SettingsMetaData.qml</file> + <file>SettingsEncoder.qml</file> + <file>StyleSlider.qml</file> + <file>Style.qml</file> + <file>qmldir</file> + <file>Playback.qml</file> + </qresource> +</RCC> diff --git a/examples/multimedia/video/recorder/qmldir b/examples/multimedia/video/recorder/qmldir new file mode 100644 index 000000000..400b74be5 --- /dev/null +++ b/examples/multimedia/video/recorder/qmldir @@ -0,0 +1,2 @@ +module CustomStyles +singleton Style 1.0 Style.qml |