diff options
Diffstat (limited to 'examples/multimediawidgets')
57 files changed, 0 insertions, 7636 deletions
diff --git a/examples/multimediawidgets/CMakeLists.txt b/examples/multimediawidgets/CMakeLists.txt deleted file mode 100644 index 8d16458c2..000000000 --- a/examples/multimediawidgets/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -if(TARGET Qt::Widgets) - qt_internal_add_example(camera) - qt_internal_add_example(videographicsitem) - qt_internal_add_example(videowidget) - qt_internal_add_example(player) -endif() diff --git a/examples/multimediawidgets/camera/CMakeLists.txt b/examples/multimediawidgets/camera/CMakeLists.txt deleted file mode 100644 index 530126ba5..000000000 --- a/examples/multimediawidgets/camera/CMakeLists.txt +++ /dev/null @@ -1,78 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project(camera LANGUAGES CXX) - -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTOUIC ON) - -if(NOT DEFINED INSTALL_EXAMPLESDIR) - set(INSTALL_EXAMPLESDIR "examples") -endif() - -set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/multimediawidgets/camera") - -find_package(Qt6 REQUIRED COMPONENTS Core Gui Multimedia MultimediaWidgets Widgets) - -set(camera_form "") -set(videosettings_form "") -if(ANDROID OR IOS) - set(camera_form camera_mobile.ui) - set(videosettings_form videosettings_mobile.ui) -else() - set(camera_form camera.ui) - set(videosettings_form videosettings.ui) -endif() - -qt_add_executable(camera - MANUAL_FINALIZATION - camera.cpp camera.h ${camera_form} - imagesettings.cpp imagesettings.h imagesettings.ui - main.cpp - videosettings.cpp videosettings.h ${videosettings_form} - metadatadialog.cpp metadatadialog.h -) - -set_target_properties(camera PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) - -if(APPLE AND NOT IOS) - set_target_properties(camera PROPERTIES - MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/macos/Info.plist.in" - ) -elseif(IOS) - set_target_properties(camera PROPERTIES - MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/ios/Info.plist.in" - ) -endif() - -set_property(TARGET camera APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR - ${CMAKE_CURRENT_SOURCE_DIR}/android) - -target_link_libraries(camera PUBLIC - Qt::Core - Qt::Gui - Qt::Multimedia - Qt::MultimediaWidgets - Qt::Widgets -) - -# Resources: -set(camera_resource_files - "images/shutter.svg" -) - -qt_add_resources(camera "camera" - PREFIX - "/" - FILES - ${camera_resource_files} -) - -qt_finalize_executable(camera) - -install(TARGETS camera - RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" - BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" - LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" -) diff --git a/examples/multimediawidgets/camera/android/AndroidManifest.xml b/examples/multimediawidgets/camera/android/AndroidManifest.xml deleted file mode 100644 index 29c4672cf..000000000 --- a/examples/multimediawidgets/camera/android/AndroidManifest.xml +++ /dev/null @@ -1,68 +0,0 @@ -<?xml version="1.0"?> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="org.qtproject.example.camera" - android:installLocation="auto" - android:versionCode="-- %%INSERT_VERSION_CODE%% --" - android:versionName="-- %%INSERT_VERSION_NAME%% --"> - <!-- The comment below will be replaced with dependencies permissions upon deployment. - Remove the comment if you do not require these default permissions. --> - <!-- %%INSERT_PERMISSIONS --> - - <!-- The comment below will be replaced with dependencies permissions upon deployment. - Remove the comment if you do not require these default features. --> - <!-- %%INSERT_FEATURES --> - - <supports-screens - android:anyDensity="true" - android:largeScreens="true" - android:normalScreens="true" - android:smallScreens="true" /> - <application - android:name="org.qtproject.qt.android.bindings.QtApplication" - android:extractNativeLibs="true" - android:hardwareAccelerated="true" - android:label="-- %%INSERT_APP_NAME%% --" - android:requestLegacyExternalStorage="true"> - <activity - android:name="org.qtproject.qt.android.bindings.QtActivity" - android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density" - android:label="-- %%INSERT_APP_NAME%% --" - android:launchMode="singleTop" - android:screenOrientation="portrait"> - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - <!-- Application arguments --> - - <meta-data - android:name="android.app.arguments" - android:value="-- %%INSERT_APP_ARGUMENTS%% --" /> - <!-- Application arguments --> - <meta-data - android:name="android.app.lib_name" - android:value="-- %%INSERT_APP_LIB_NAME%% --" /> - - <!-- Background running --> - <!-- Warning: changing this value to true may cause unexpected crashes if the - application still try to draw after - "applicationStateChanged(Qt::ApplicationSuspended)" signal is sent! --> - <meta-data - android:name="android.app.background_running" - android:value="false" /> - <!-- Background running --> - - <!-- extract android style --> - <!-- available android:values : - * default - In most cases this will be the same as "full", but it can also be - * something else if needed, e.g., for compatibility reasons - * full - useful QWidget & Quick Controls 1 apps - * minimal - useful for Quick Controls 2 apps, it is much faster than "full" - * none - useful for apps that don't use any of the above Qt modules --> - <meta-data - android:name="android.app.extract_android_style" - android:value="minimal" /> - <!-- extract android style --> - </activity> - </application> -</manifest> diff --git a/examples/multimediawidgets/camera/camera.cpp b/examples/multimediawidgets/camera/camera.cpp deleted file mode 100644 index e71e209f3..000000000 --- a/examples/multimediawidgets/camera/camera.cpp +++ /dev/null @@ -1,434 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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 "camera.h" -#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) -#include "ui_camera_mobile.h" -#else -#include "ui_camera.h" -#endif -#include "videosettings.h" -#include "imagesettings.h" -#include "metadatadialog.h" - -#include <QMediaRecorder> -#include <QVideoWidget> -#include <QCameraDevice> -#include <QMediaMetaData> -#include <QMediaDevices> -#include <QAudioDevice> -#include <QAudioInput> - -#include <QMessageBox> -#include <QPalette> -#include <QImage> - -#include <QtWidgets> -#include <QMediaDevices> -#include <QMediaFormat> - -Camera::Camera() - : ui(new Ui::Camera) -{ - ui->setupUi(this); - - m_audioInput.reset(new QAudioInput); - m_captureSession.setAudioInput(m_audioInput.get()); - - //Camera devices: - - videoDevicesGroup = new QActionGroup(this); - videoDevicesGroup->setExclusive(true); - updateCameras(); - connect(&m_devices, &QMediaDevices::videoInputsChanged, this, &Camera::updateCameras); - - connect(videoDevicesGroup, &QActionGroup::triggered, this, &Camera::updateCameraDevice); - connect(ui->captureWidget, &QTabWidget::currentChanged, this, &Camera::updateCaptureMode); - - connect(ui->metaDataButton, &QPushButton::clicked, this, &Camera::showMetaDataDialog); - - setCamera(QMediaDevices::defaultVideoInput()); -} - -void Camera::setCamera(const QCameraDevice &cameraDevice) -{ - m_camera.reset(new QCamera(cameraDevice)); - m_captureSession.setCamera(m_camera.data()); - - connect(m_camera.data(), &QCamera::activeChanged, this, &Camera::updateCameraActive); - connect(m_camera.data(), &QCamera::errorOccurred, this, &Camera::displayCameraError); - - if (!m_mediaRecorder) { - m_mediaRecorder.reset(new QMediaRecorder); - m_captureSession.setRecorder(m_mediaRecorder.data()); - connect(m_mediaRecorder.data(), &QMediaRecorder::recorderStateChanged, this, &Camera::updateRecorderState); - } - - m_imageCapture = new QImageCapture; - m_captureSession.setImageCapture(m_imageCapture); - - connect(m_mediaRecorder.data(), &QMediaRecorder::durationChanged, this, &Camera::updateRecordTime); - connect(m_mediaRecorder.data(), &QMediaRecorder::errorChanged, this, &Camera::displayRecorderError); - - connect(ui->exposureCompensation, &QAbstractSlider::valueChanged, this, &Camera::setExposureCompensation); - - m_captureSession.setVideoOutput(ui->viewfinder); - - updateCameraActive(m_camera->isActive()); - updateRecorderState(m_mediaRecorder->recorderState()); - - connect(m_imageCapture, &QImageCapture::readyForCaptureChanged, this, &Camera::readyForCapture); - connect(m_imageCapture, &QImageCapture::imageCaptured, this, &Camera::processCapturedImage); - connect(m_imageCapture, &QImageCapture::imageSaved, this, &Camera::imageSaved); - connect(m_imageCapture, &QImageCapture::errorOccurred, this, &Camera::displayCaptureError); - readyForCapture(m_imageCapture->isReadyForCapture()); - - updateCaptureMode(); - - if (m_camera->cameraFormat().isNull()) { - auto formats = cameraDevice.videoFormats(); - if (!formats.isEmpty()) { - // Choose a decent camera format: Maximum resolution at at least 30 FPS - // we use 29 FPS to compare against as some cameras report 29.97 FPS... - QCameraFormat bestFormat; - for (const auto &fmt : formats) { - if (bestFormat.maxFrameRate() < 29 && fmt.maxFrameRate() > bestFormat.maxFrameRate()) - bestFormat = fmt; - else if (bestFormat.maxFrameRate() == fmt.maxFrameRate() && - bestFormat.resolution().width()*bestFormat.resolution().height() < - fmt.resolution().width()*fmt.resolution().height()) - bestFormat = fmt; - } - - m_camera->setCameraFormat(bestFormat); - m_mediaRecorder->setVideoFrameRate(bestFormat.maxFrameRate()); - } - } - - m_camera->start(); -} - -void Camera::keyPressEvent(QKeyEvent * event) -{ - if (event->isAutoRepeat()) - return; - - switch (event->key()) { - case Qt::Key_CameraFocus: - displayViewfinder(); - event->accept(); - break; - case Qt::Key_Camera: - if (m_doImageCapture) { - takeImage(); - } else { - if (m_mediaRecorder->recorderState() == QMediaRecorder::RecordingState) - stop(); - else - record(); - } - event->accept(); - break; - default: - QMainWindow::keyPressEvent(event); - } -} - -void Camera::keyReleaseEvent(QKeyEvent *event) -{ - QMainWindow::keyReleaseEvent(event); -} - -void Camera::updateRecordTime() -{ - QString str = QString("Recorded %1 sec").arg(m_mediaRecorder->duration()/1000); - ui->statusbar->showMessage(str); -} - -void Camera::processCapturedImage(int requestId, const QImage& img) -{ - Q_UNUSED(requestId); - QImage scaledImage = img.scaled(ui->viewfinder->size(), - Qt::KeepAspectRatio, - Qt::SmoothTransformation); - - ui->lastImagePreviewLabel->setPixmap(QPixmap::fromImage(scaledImage)); - - // Display captured image for 4 seconds. - displayCapturedImage(); - QTimer::singleShot(4000, this, &Camera::displayViewfinder); -} - -void Camera::configureCaptureSettings() -{ - if (m_doImageCapture) - configureImageSettings(); - else - configureVideoSettings(); -} - -void Camera::configureVideoSettings() -{ - VideoSettings settingsDialog(m_mediaRecorder.data()); - settingsDialog.setWindowFlags(settingsDialog.windowFlags() & ~Qt::WindowContextHelpButtonHint); - - if (settingsDialog.exec()) - settingsDialog.applySettings(); -} - -void Camera::configureImageSettings() -{ - ImageSettings settingsDialog(m_imageCapture); - settingsDialog.setWindowFlags(settingsDialog.windowFlags() & ~Qt::WindowContextHelpButtonHint); - - if (settingsDialog.exec()) { - settingsDialog.applyImageSettings(); - } -} - -void Camera::record() -{ - m_mediaRecorder->record(); - updateRecordTime(); -} - -void Camera::pause() -{ - m_mediaRecorder->pause(); -} - -void Camera::stop() -{ - m_mediaRecorder->stop(); -} - -void Camera::setMuted(bool muted) -{ - m_captureSession.audioInput()->setMuted(muted); -} - -void Camera::takeImage() -{ - m_isCapturingImage = true; - m_imageCapture->captureToFile(); -} - -void Camera::displayCaptureError(int id, const QImageCapture::Error error, const QString &errorString) -{ - Q_UNUSED(id); - Q_UNUSED(error); - QMessageBox::warning(this, tr("Image Capture Error"), errorString); - m_isCapturingImage = false; -} - -void Camera::startCamera() -{ - m_camera->start(); -} - -void Camera::stopCamera() -{ - m_camera->stop(); -} - -void Camera::updateCaptureMode() -{ - int tabIndex = ui->captureWidget->currentIndex(); - m_doImageCapture = (tabIndex == 0); -} - -void Camera::updateCameraActive(bool active) -{ - if (active) { - ui->actionStartCamera->setEnabled(false); - ui->actionStopCamera->setEnabled(true); - ui->captureWidget->setEnabled(true); - ui->actionSettings->setEnabled(true); - } else { - ui->actionStartCamera->setEnabled(true); - ui->actionStopCamera->setEnabled(false); - ui->captureWidget->setEnabled(false); - ui->actionSettings->setEnabled(false); - } -} - -void Camera::updateRecorderState(QMediaRecorder::RecorderState state) -{ - switch (state) { - case QMediaRecorder::StoppedState: - ui->recordButton->setEnabled(true); - ui->pauseButton->setEnabled(true); - ui->stopButton->setEnabled(false); - ui->metaDataButton->setEnabled(true); - break; - case QMediaRecorder::PausedState: - ui->recordButton->setEnabled(true); - ui->pauseButton->setEnabled(false); - ui->stopButton->setEnabled(true); - ui->metaDataButton->setEnabled(false); - break; - case QMediaRecorder::RecordingState: - ui->recordButton->setEnabled(false); - ui->pauseButton->setEnabled(true); - ui->stopButton->setEnabled(true); - ui->metaDataButton->setEnabled(false); - break; - } -} - -void Camera::setExposureCompensation(int index) -{ - m_camera->setExposureCompensation(index*0.5); -} - -void Camera::displayRecorderError() -{ - if (m_mediaRecorder->error() != QMediaRecorder::NoError) - QMessageBox::warning(this, tr("Capture Error"), m_mediaRecorder->errorString()); -} - -void Camera::displayCameraError() -{ - if (m_camera->error() != QCamera::NoError) - QMessageBox::warning(this, tr("Camera Error"), m_camera->errorString()); -} - -void Camera::updateCameraDevice(QAction *action) -{ - setCamera(qvariant_cast<QCameraDevice>(action->data())); -} - -void Camera::displayViewfinder() -{ - ui->stackedWidget->setCurrentIndex(0); -} - -void Camera::displayCapturedImage() -{ - ui->stackedWidget->setCurrentIndex(1); -} - -void Camera::readyForCapture(bool ready) -{ - ui->takeImageButton->setEnabled(ready); -} - -void Camera::imageSaved(int id, const QString &fileName) -{ - Q_UNUSED(id); - ui->statusbar->showMessage(tr("Captured \"%1\"").arg(QDir::toNativeSeparators(fileName))); - - m_isCapturingImage = false; - if (m_applicationExiting) - close(); -} - -void Camera::closeEvent(QCloseEvent *event) -{ - if (m_isCapturingImage) { - setEnabled(false); - m_applicationExiting = true; - event->ignore(); - } else { - event->accept(); - } -} - -void Camera::updateCameras() -{ - ui->menuDevices->clear(); - const QList<QCameraDevice> availableCameras = QMediaDevices::videoInputs(); - for (const QCameraDevice &cameraDevice : availableCameras) { - QAction *videoDeviceAction = new QAction(cameraDevice.description(), videoDevicesGroup); - videoDeviceAction->setCheckable(true); - videoDeviceAction->setData(QVariant::fromValue(cameraDevice)); - if (cameraDevice == QMediaDevices::defaultVideoInput()) - videoDeviceAction->setChecked(true); - - ui->menuDevices->addAction(videoDeviceAction); - } -} - -void Camera::showMetaDataDialog() -{ - if (!m_metaDataDialog) - m_metaDataDialog = new MetaDataDialog(this); - m_metaDataDialog->setAttribute(Qt::WA_DeleteOnClose, false); - if (m_metaDataDialog->exec() == QDialog::Accepted) - saveMetaData(); -} - -void Camera::saveMetaData() -{ - QMediaMetaData data; - for (int i = 0; i < QMediaMetaData::NumMetaData; i++) { - QString val = m_metaDataDialog->m_metaDataFields[i]->text(); - if (!val.isEmpty()) { - auto key = static_cast<QMediaMetaData::Key>(i); - if (i == QMediaMetaData::CoverArtImage) { - QImage coverArt(val); - data.insert(key, coverArt); - } - else if (i == QMediaMetaData::ThumbnailImage) { - QImage thumbnail(val); - data.insert(key, thumbnail); - } - else if (i == QMediaMetaData::Date) { - QDateTime date = QDateTime::fromString(val); - data.insert(key, date); - } - else { - data.insert(key, val); - } - } - } - m_mediaRecorder->setMetaData(data); -} - diff --git a/examples/multimediawidgets/camera/camera.h b/examples/multimediawidgets/camera/camera.h deleted file mode 100644 index 786a6f722..000000000 --- a/examples/multimediawidgets/camera/camera.h +++ /dev/null @@ -1,148 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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$ -** -****************************************************************************/ - -#ifndef CAMERA_H -#define CAMERA_H - -#include <QCamera> -#include <QImageCapture> -#include <QMediaRecorder> -#include <QScopedPointer> -#include <QMediaMetaData> -#include <QMediaCaptureSession> -#include <QMediaDevices> -#include <QAudioInput> - -#include <QMainWindow> - -QT_BEGIN_NAMESPACE -namespace Ui { class Camera; } -class QActionGroup; -QT_END_NAMESPACE - -class MetaDataDialog; - -class Camera : public QMainWindow -{ - Q_OBJECT - -public: - Camera(); - -public slots: - void saveMetaData(); - -private slots: - void setCamera(const QCameraDevice &cameraDevice); - - void startCamera(); - void stopCamera(); - - void record(); - void pause(); - void stop(); - void setMuted(bool); - - void takeImage(); - void displayCaptureError(int, QImageCapture::Error, const QString &errorString); - - void configureCaptureSettings(); - void configureVideoSettings(); - void configureImageSettings(); - - void displayRecorderError(); - void displayCameraError(); - - void updateCameraDevice(QAction *action); - - void updateCameraActive(bool active); - void updateCaptureMode(); - void updateRecorderState(QMediaRecorder::RecorderState state); - void setExposureCompensation(int index); - - void updateRecordTime(); - - void processCapturedImage(int requestId, const QImage &img); - - void displayViewfinder(); - void displayCapturedImage(); - - void readyForCapture(bool ready); - void imageSaved(int id, const QString &fileName); - - void updateCameras(); - - void showMetaDataDialog(); - -protected: - void keyPressEvent(QKeyEvent *event) override; - void keyReleaseEvent(QKeyEvent *event) override; - void closeEvent(QCloseEvent *event) override; - -private: - Ui::Camera *ui; - - QActionGroup *videoDevicesGroup = nullptr; - - QMediaDevices m_devices; - QMediaCaptureSession m_captureSession; - QScopedPointer<QCamera> m_camera; - QScopedPointer<QAudioInput> m_audioInput; - QImageCapture *m_imageCapture; - QScopedPointer<QMediaRecorder> m_mediaRecorder; - - bool m_isCapturingImage = false; - bool m_applicationExiting = false; - bool m_doImageCapture = true; - - MetaDataDialog *m_metaDataDialog = nullptr; -}; - -#endif diff --git a/examples/multimediawidgets/camera/camera.pro b/examples/multimediawidgets/camera/camera.pro deleted file mode 100644 index e1d98c06e..000000000 --- a/examples/multimediawidgets/camera/camera.pro +++ /dev/null @@ -1,40 +0,0 @@ -TEMPLATE = app -TARGET = camera - -QT += multimedia multimediawidgets - -HEADERS = \ - camera.h \ - imagesettings.h \ - videosettings.h \ - metadatadialog.h - -SOURCES = \ - main.cpp \ - camera.cpp \ - imagesettings.cpp \ - videosettings.cpp \ - metadatadialog.cpp - -FORMS += \ - imagesettings.ui - -android|ios { - FORMS += \ - camera_mobile.ui \ - videosettings_mobile.ui -} else { - FORMS += \ - camera.ui \ - videosettings.ui -} -RESOURCES += camera.qrc - -target.path = $$[QT_INSTALL_EXAMPLES]/multimediawidgets/camera -INSTALLS += target - -QT += widgets -include(../../multimedia/shared/shared.pri) - -ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android -OTHER_FILES += android/AndroidManifest.xml diff --git a/examples/multimediawidgets/camera/camera.qrc b/examples/multimediawidgets/camera/camera.qrc deleted file mode 100644 index a915eb596..000000000 --- a/examples/multimediawidgets/camera/camera.qrc +++ /dev/null @@ -1,5 +0,0 @@ -<!DOCTYPE RCC><RCC version="1.0"> -<qresource> - <file>images/shutter.svg</file> -</qresource> -</RCC> diff --git a/examples/multimediawidgets/camera/camera.ui b/examples/multimediawidgets/camera/camera.ui deleted file mode 100644 index 560ee7fed..000000000 --- a/examples/multimediawidgets/camera/camera.ui +++ /dev/null @@ -1,488 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>Camera</class> - <widget class="QMainWindow" name="Camera"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>668</width> - <height>429</height> - </rect> - </property> - <property name="windowTitle"> - <string>Camera</string> - </property> - <widget class="QWidget" name="centralwidget"> - <layout class="QGridLayout" name="gridLayout_3"> - <item row="1" column="1" colspan="2"> - <widget class="QTabWidget" name="captureWidget"> - <property name="currentIndex"> - <number>0</number> - </property> - <widget class="QWidget" name="tab_2"> - <attribute name="title"> - <string>Image</string> - </attribute> - <layout class="QGridLayout" name="gridLayout"> - <item row="3" column="0"> - <spacer name="verticalSpacer_2"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>161</height> - </size> - </property> - </spacer> - </item> - <item row="0" column="0"> - <widget class="QPushButton" name="takeImageButton"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="text"> - <string>Capture Photo</string> - </property> - <property name="icon"> - <iconset resource="camera.qrc"> - <normaloff>:/images/shutter.svg</normaloff>:/images/shutter.svg</iconset> - </property> - </widget> - </item> - <item row="5" column="0"> - <widget class="QSlider" name="exposureCompensation"> - <property name="minimum"> - <number>-4</number> - </property> - <property name="maximum"> - <number>4</number> - </property> - <property name="pageStep"> - <number>2</number> - </property> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="tickPosition"> - <enum>QSlider::TicksAbove</enum> - </property> - </widget> - </item> - <item row="4" column="0"> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Exposure Compensation:</string> - </property> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="tab"> - <attribute name="title"> - <string>Video</string> - </attribute> - <layout class="QGridLayout" name="gridLayout_2"> - <item row="0" column="0"> - <widget class="QPushButton" name="recordButton"> - <property name="text"> - <string>Record</string> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QPushButton" name="pauseButton"> - <property name="text"> - <string>Pause</string> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QPushButton" name="stopButton"> - <property name="text"> - <string>Stop</string> - </property> - </widget> - </item> - <item row="3" column="0"> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>76</height> - </size> - </property> - </spacer> - </item> - <item row="4" column="0"> - <widget class="QPushButton" name="muteButton"> - <property name="text"> - <string>Mute</string> - </property> - <property name="checkable"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="5" column="0"> - <widget class="QPushButton" name="metaDataButton"> - <property name="text"> - <string>Set metadata</string> - </property> - <property name="checkable"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </widget> - </widget> - </item> - <item row="0" column="0" rowspan="2"> - <widget class="QStackedWidget" name="stackedWidget"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>1</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="palette"> - <palette> - <active> - <colorrole role="Base"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>255</red> - <green>255</green> - <blue>255</blue> - </color> - </brush> - </colorrole> - <colorrole role="Window"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>145</red> - <green>145</green> - <blue>145</blue> - </color> - </brush> - </colorrole> - </active> - <inactive> - <colorrole role="Base"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>255</red> - <green>255</green> - <blue>255</blue> - </color> - </brush> - </colorrole> - <colorrole role="Window"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>145</red> - <green>145</green> - <blue>145</blue> - </color> - </brush> - </colorrole> - </inactive> - <disabled> - <colorrole role="Base"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>145</red> - <green>145</green> - <blue>145</blue> - </color> - </brush> - </colorrole> - <colorrole role="Window"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>145</red> - <green>145</green> - <blue>145</blue> - </color> - </brush> - </colorrole> - </disabled> - </palette> - </property> - <property name="currentIndex"> - <number>0</number> - </property> - <widget class="QWidget" name="viewfinderPage"> - <layout class="QGridLayout" name="gridLayout_5"> - <item row="0" column="0"> - <widget class="QVideoWidget" name="viewfinder" native="true"/> - </item> - </layout> - </widget> - <widget class="QWidget" name="previewPage"> - <layout class="QGridLayout" name="gridLayout_4"> - <item row="0" column="0"> - <widget class="QLabel" name="lastImagePreviewLabel"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="frameShape"> - <enum>QFrame::Box</enum> - </property> - <property name="text"> - <string/> - </property> - </widget> - </item> - </layout> - </widget> - </widget> - </item> - </layout> - </widget> - <widget class="QMenuBar" name="menubar"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>668</width> - <height>28</height> - </rect> - </property> - <widget class="QMenu" name="menuFile"> - <property name="title"> - <string>File</string> - </property> - <addaction name="actionStartCamera"/> - <addaction name="actionStopCamera"/> - <addaction name="separator"/> - <addaction name="actionSettings"/> - <addaction name="separator"/> - <addaction name="actionExit"/> - </widget> - <widget class="QMenu" name="menuDevices"> - <property name="title"> - <string>Devices</string> - </property> - </widget> - <addaction name="menuFile"/> - <addaction name="menuDevices"/> - </widget> - <widget class="QStatusBar" name="statusbar"/> - <action name="actionExit"> - <property name="text"> - <string>Close</string> - </property> - </action> - <action name="actionStartCamera"> - <property name="text"> - <string>Start Camera</string> - </property> - </action> - <action name="actionStopCamera"> - <property name="text"> - <string>Stop Camera</string> - </property> - </action> - <action name="actionSettings"> - <property name="text"> - <string>Change Settings</string> - </property> - </action> - </widget> - <customwidgets> - <customwidget> - <class>QVideoWidget</class> - <extends>QWidget</extends> - <header>qvideowidget.h</header> - <container>1</container> - </customwidget> - </customwidgets> - <resources> - <include location="camera.qrc"/> - </resources> - <connections> - <connection> - <sender>recordButton</sender> - <signal>clicked()</signal> - <receiver>Camera</receiver> - <slot>record()</slot> - <hints> - <hint type="sourcelabel"> - <x>647</x> - <y>149</y> - </hint> - <hint type="destinationlabel"> - <x>61</x> - <y>238</y> - </hint> - </hints> - </connection> - <connection> - <sender>stopButton</sender> - <signal>clicked()</signal> - <receiver>Camera</receiver> - <slot>stop()</slot> - <hints> - <hint type="sourcelabel"> - <x>647</x> - <y>225</y> - </hint> - <hint type="destinationlabel"> - <x>140</x> - <y>236</y> - </hint> - </hints> - </connection> - <connection> - <sender>pauseButton</sender> - <signal>clicked()</signal> - <receiver>Camera</receiver> - <slot>pause()</slot> - <hints> - <hint type="sourcelabel"> - <x>647</x> - <y>187</y> - </hint> - <hint type="destinationlabel"> - <x>234</x> - <y>237</y> - </hint> - </hints> - </connection> - <connection> - <sender>actionExit</sender> - <signal>triggered()</signal> - <receiver>Camera</receiver> - <slot>close()</slot> - <hints> - <hint type="sourcelabel"> - <x>-1</x> - <y>-1</y> - </hint> - <hint type="destinationlabel"> - <x>154</x> - <y>130</y> - </hint> - </hints> - </connection> - <connection> - <sender>takeImageButton</sender> - <signal>clicked()</signal> - <receiver>Camera</receiver> - <slot>takeImage()</slot> - <hints> - <hint type="sourcelabel"> - <x>625</x> - <y>132</y> - </hint> - <hint type="destinationlabel"> - <x>603</x> - <y>169</y> - </hint> - </hints> - </connection> - <connection> - <sender>muteButton</sender> - <signal>toggled(bool)</signal> - <receiver>Camera</receiver> - <slot>setMuted(bool)</slot> - <hints> - <hint type="sourcelabel"> - <x>647</x> - <y>377</y> - </hint> - <hint type="destinationlabel"> - <x>5</x> - <y>280</y> - </hint> - </hints> - </connection> - <connection> - <sender>exposureCompensation</sender> - <signal>valueChanged(int)</signal> - <receiver>Camera</receiver> - <slot>setExposureCompensation(int)</slot> - <hints> - <hint type="sourcelabel"> - <x>559</x> - <y>367</y> - </hint> - <hint type="destinationlabel"> - <x>665</x> - <y>365</y> - </hint> - </hints> - </connection> - <connection> - <sender>actionSettings</sender> - <signal>triggered()</signal> - <receiver>Camera</receiver> - <slot>configureCaptureSettings()</slot> - <hints> - <hint type="sourcelabel"> - <x>-1</x> - <y>-1</y> - </hint> - <hint type="destinationlabel"> - <x>333</x> - <y>210</y> - </hint> - </hints> - </connection> - <connection> - <sender>actionStartCamera</sender> - <signal>triggered()</signal> - <receiver>Camera</receiver> - <slot>startCamera()</slot> - <hints> - <hint type="sourcelabel"> - <x>-1</x> - <y>-1</y> - </hint> - <hint type="destinationlabel"> - <x>333</x> - <y>210</y> - </hint> - </hints> - </connection> - <connection> - <sender>actionStopCamera</sender> - <signal>triggered()</signal> - <receiver>Camera</receiver> - <slot>stopCamera()</slot> - <hints> - <hint type="sourcelabel"> - <x>-1</x> - <y>-1</y> - </hint> - <hint type="destinationlabel"> - <x>333</x> - <y>210</y> - </hint> - </hints> - </connection> - </connections> - <slots> - <slot>record()</slot> - <slot>pause()</slot> - <slot>stop()</slot> - <slot>enablePreview(bool)</slot> - <slot>configureCaptureSettings()</slot> - <slot>takeImage()</slot> - <slot>startCamera()</slot> - <slot>toggleLock()</slot> - <slot>setMuted(bool)</slot> - <slot>stopCamera()</slot> - <slot>setExposureCompensation(int)</slot> - </slots> -</ui> diff --git a/examples/multimediawidgets/camera/camera_mobile.ui b/examples/multimediawidgets/camera/camera_mobile.ui deleted file mode 100644 index 7f269b17b..000000000 --- a/examples/multimediawidgets/camera/camera_mobile.ui +++ /dev/null @@ -1,504 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>Camera</class> - <widget class="QMainWindow" name="Camera"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>668</width> - <height>429</height> - </rect> - </property> - <property name="windowTitle"> - <string>Camera</string> - </property> - <widget class="QWidget" name="centralwidget"> - <layout class="QGridLayout" name="gridLayout_3"> - <item row="1" column="1" colspan="2"> - <widget class="QTabWidget" name="captureWidget"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="currentIndex"> - <number>0</number> - </property> - <widget class="QWidget" name="tab_2"> - <attribute name="title"> - <string>Image</string> - </attribute> - <layout class="QGridLayout" name="gridLayout"> - <item row="4" column="0"> - <widget class="QSlider" name="exposureCompensation"> - <property name="minimum"> - <number>-4</number> - </property> - <property name="maximum"> - <number>4</number> - </property> - <property name="pageStep"> - <number>2</number> - </property> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="tickPosition"> - <enum>QSlider::TicksAbove</enum> - </property> - </widget> - </item> - <item row="3" column="0"> - <widget class="QLabel" name="label"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Exposure Compensation:</string> - </property> - </widget> - </item> - <item row="0" column="0"> - <widget class="QPushButton" name="takeImageButton"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="text"> - <string>Capture Photo</string> - </property> - <property name="icon"> - <iconset> - <normaloff>:/images/shutter.svg</normaloff>:/images/shutter.svg</iconset> - </property> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="tab"> - <attribute name="title"> - <string>Video</string> - </attribute> - <layout class="QGridLayout" name="gridLayout_2"> - <item row="0" column="0"> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QPushButton" name="recordButton"> - <property name="text"> - <string>Record</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pauseButton"> - <property name="text"> - <string>Pause</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="stopButton"> - <property name="text"> - <string>Stop</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>10</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="muteButton"> - <property name="text"> - <string>Mute</string> - </property> - <property name="checkable"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="metaDataButton"> - <property name="text"> - <string>Set metadata</string> - </property> - <property name="checkable"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </item> - </layout> - </widget> - </widget> - </item> - <item row="0" column="2"> - <widget class="QStackedWidget" name="stackedWidget"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> - <horstretch>1</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="palette"> - <palette> - <active> - <colorrole role="Base"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>255</red> - <green>255</green> - <blue>255</blue> - </color> - </brush> - </colorrole> - <colorrole role="Window"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>145</red> - <green>145</green> - <blue>145</blue> - </color> - </brush> - </colorrole> - </active> - <inactive> - <colorrole role="Base"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>255</red> - <green>255</green> - <blue>255</blue> - </color> - </brush> - </colorrole> - <colorrole role="Window"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>145</red> - <green>145</green> - <blue>145</blue> - </color> - </brush> - </colorrole> - </inactive> - <disabled> - <colorrole role="Base"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>145</red> - <green>145</green> - <blue>145</blue> - </color> - </brush> - </colorrole> - <colorrole role="Window"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>145</red> - <green>145</green> - <blue>145</blue> - </color> - </brush> - </colorrole> - </disabled> - </palette> - </property> - <property name="currentIndex"> - <number>0</number> - </property> - <widget class="QWidget" name="viewfinderPage"> - <layout class="QGridLayout" name="gridLayout_5"> - <item row="0" column="0"> - <widget class="QVideoWidget" name="viewfinder" native="true"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="previewPage"> - <layout class="QGridLayout" name="gridLayout_4"> - <item row="0" column="0"> - <widget class="QLabel" name="lastImagePreviewLabel"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="frameShape"> - <enum>QFrame::Box</enum> - </property> - <property name="text"> - <string/> - </property> - </widget> - </item> - </layout> - </widget> - </widget> - </item> - </layout> - </widget> - <widget class="QMenuBar" name="menubar"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>668</width> - <height>22</height> - </rect> - </property> - <widget class="QMenu" name="menuFile"> - <property name="title"> - <string>File</string> - </property> - <addaction name="actionStartCamera"/> - <addaction name="actionStopCamera"/> - <addaction name="separator"/> - <addaction name="actionSettings"/> - <addaction name="separator"/> - <addaction name="actionExit"/> - </widget> - <widget class="QMenu" name="menuDevices"> - <property name="title"> - <string>Devices</string> - </property> - </widget> - <addaction name="menuFile"/> - <addaction name="menuDevices"/> - </widget> - <widget class="QStatusBar" name="statusbar"/> - <action name="actionExit"> - <property name="text"> - <string>Close</string> - </property> - </action> - <action name="actionStartCamera"> - <property name="text"> - <string>Start Camera</string> - </property> - </action> - <action name="actionStopCamera"> - <property name="text"> - <string>Stop Camera</string> - </property> - </action> - <action name="actionSettings"> - <property name="text"> - <string>Change Settings</string> - </property> - </action> - </widget> - <customwidgets> - <customwidget> - <class>QVideoWidget</class> - <extends>QWidget</extends> - <header>qvideowidget.h</header> - <container>1</container> - </customwidget> - </customwidgets> - <resources/> - <connections> - <connection> - <sender>recordButton</sender> - <signal>clicked()</signal> - <receiver>Camera</receiver> - <slot>record()</slot> - <hints> - <hint type="sourcelabel"> - <x>647</x> - <y>149</y> - </hint> - <hint type="destinationlabel"> - <x>61</x> - <y>238</y> - </hint> - </hints> - </connection> - <connection> - <sender>stopButton</sender> - <signal>clicked()</signal> - <receiver>Camera</receiver> - <slot>stop()</slot> - <hints> - <hint type="sourcelabel"> - <x>647</x> - <y>225</y> - </hint> - <hint type="destinationlabel"> - <x>140</x> - <y>236</y> - </hint> - </hints> - </connection> - <connection> - <sender>pauseButton</sender> - <signal>clicked()</signal> - <receiver>Camera</receiver> - <slot>pause()</slot> - <hints> - <hint type="sourcelabel"> - <x>647</x> - <y>187</y> - </hint> - <hint type="destinationlabel"> - <x>234</x> - <y>237</y> - </hint> - </hints> - </connection> - <connection> - <sender>actionExit</sender> - <signal>triggered()</signal> - <receiver>Camera</receiver> - <slot>close()</slot> - <hints> - <hint type="sourcelabel"> - <x>-1</x> - <y>-1</y> - </hint> - <hint type="destinationlabel"> - <x>154</x> - <y>130</y> - </hint> - </hints> - </connection> - <connection> - <sender>takeImageButton</sender> - <signal>clicked()</signal> - <receiver>Camera</receiver> - <slot>takeImage()</slot> - <hints> - <hint type="sourcelabel"> - <x>625</x> - <y>132</y> - </hint> - <hint type="destinationlabel"> - <x>603</x> - <y>169</y> - </hint> - </hints> - </connection> - <connection> - <sender>muteButton</sender> - <signal>toggled(bool)</signal> - <receiver>Camera</receiver> - <slot>setMuted(bool)</slot> - <hints> - <hint type="sourcelabel"> - <x>647</x> - <y>377</y> - </hint> - <hint type="destinationlabel"> - <x>5</x> - <y>280</y> - </hint> - </hints> - </connection> - <connection> - <sender>exposureCompensation</sender> - <signal>valueChanged(int)</signal> - <receiver>Camera</receiver> - <slot>setExposureCompensation(int)</slot> - <hints> - <hint type="sourcelabel"> - <x>559</x> - <y>367</y> - </hint> - <hint type="destinationlabel"> - <x>665</x> - <y>365</y> - </hint> - </hints> - </connection> - <connection> - <sender>actionSettings</sender> - <signal>triggered()</signal> - <receiver>Camera</receiver> - <slot>configureCaptureSettings()</slot> - <hints> - <hint type="sourcelabel"> - <x>-1</x> - <y>-1</y> - </hint> - <hint type="destinationlabel"> - <x>333</x> - <y>210</y> - </hint> - </hints> - </connection> - <connection> - <sender>actionStartCamera</sender> - <signal>triggered()</signal> - <receiver>Camera</receiver> - <slot>startCamera()</slot> - <hints> - <hint type="sourcelabel"> - <x>-1</x> - <y>-1</y> - </hint> - <hint type="destinationlabel"> - <x>333</x> - <y>210</y> - </hint> - </hints> - </connection> - <connection> - <sender>actionStopCamera</sender> - <signal>triggered()</signal> - <receiver>Camera</receiver> - <slot>stopCamera()</slot> - <hints> - <hint type="sourcelabel"> - <x>-1</x> - <y>-1</y> - </hint> - <hint type="destinationlabel"> - <x>333</x> - <y>210</y> - </hint> - </hints> - </connection> - </connections> - <slots> - <slot>record()</slot> - <slot>pause()</slot> - <slot>stop()</slot> - <slot>enablePreview(bool)</slot> - <slot>configureCaptureSettings()</slot> - <slot>takeImage()</slot> - <slot>startCamera()</slot> - <slot>toggleLock()</slot> - <slot>setMuted(bool)</slot> - <slot>stopCamera()</slot> - <slot>setExposureCompensation(int)</slot> - </slots> -</ui> diff --git a/examples/multimediawidgets/camera/doc/images/camera-example.png b/examples/multimediawidgets/camera/doc/images/camera-example.png Binary files differdeleted file mode 100644 index 12e1b5728..000000000 --- a/examples/multimediawidgets/camera/doc/images/camera-example.png +++ /dev/null diff --git a/examples/multimediawidgets/camera/doc/src/camera.qdoc b/examples/multimediawidgets/camera/doc/src/camera.qdoc deleted file mode 100644 index 4db430fc3..000000000 --- a/examples/multimediawidgets/camera/doc/src/camera.qdoc +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2021 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** 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. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ -/*! - -\example multimediawidgets/camera -\title Camera Example -\ingroup multimedia_examples -\ingroup video_examples -\ingroup camera_examples -\meta {tag} {widgets} -\brief Shows how to capture a still image or record video. -or video. - -The Camera Example demonstrates how you can use \l{Qt Multimedia} to implement -some basic Camera functionality to take still images and record video clips -with audio. - -\include examples-run.qdocinc - -The example implements a \c Camera class that acts as our camera interface. It -has a user interface, control functions, setting values and a means of defining -the location where the image or video clip is to be saved. It will also store -the image and video settings. - -The Camera class uses: -\list - \li An instance of \l {QCamera}, the API class interface to the hardware. - \li An instance of \l {QImageCapture} to take still images. - \li An instance of \l {QMediaRecorder} to record video. It also contains - the user interface object. -\endlist - -The Camera constructor does some basic initialization: -\list - \li The user interface is initialized. - \li UI signals are connected to slots that react to the triggering event. -\endlist -However, most of the work is done when the \e{setCamera()} function is called, -passing in a \l QCameraDevice. - -\e{setCamera()} sets up various connections between the user interface and the -functionality of the Camera class using signals and slots. It also instantiates -and initializes the \l {QCamera}, \l {QImageCapture}, and \l {QMediaRecorder} -objects mentioned above. The still and video recording visual tabs are enabled -and finally the \l {QCamera::start}{start()} function of the \l{QCamera} -object is called. - -Now that the camera is ready for user commands it waits for a suitable event. -Such an event can be a key press of either the \l {Qt::Key_CameraFocus} or -\l {Qt::Key_Camera} buttons on the application window. Camera focus will -simply display the preview and lock the camera settings. \c Key_Camera will -either call \e{takeImage()} if doing an image capture, or call -\c record() or \c stop() (if already recording) on the QMediaRecorder instance -when recording video. - -\image camera-example.png - -*/ diff --git a/examples/multimediawidgets/camera/images/shutter.svg b/examples/multimediawidgets/camera/images/shutter.svg deleted file mode 100644 index 18493361d..000000000 --- a/examples/multimediawidgets/camera/images/shutter.svg +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Generator: Adobe Illustrator 20.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> -<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" - viewBox="0 0 23.3 19.4" style="enable-background:new 0 0 23.3 19.4;" xml:space="preserve"> -<style type="text/css"> - .st0{fill:none;} -</style> -<g> - <path class="st0" d="M6.2,4.8H2.4c-0.2,0-0.1-0.1-0.1,0.1V17c0,0.2-0.1,0.8,0.1,0.8h3.9V4.8z"/> - <circle class="st0" cx="14" cy="11" r="4.5"/> - <path class="st0" d="M20.9,4.8h-1.8c-0.3,0-0.6-0.4-0.8-0.6l-1.7-2.4h-5.3L9.7,4.2C9.5,4.4,9.2,4.8,8.9,4.8H7.2v13h13.7 - c0.2,0,0.3-0.6,0.3-0.8V4.9C21.2,4.7,21.1,4.8,20.9,4.8z M14,16.4c-3,0-5.5-2.4-5.5-5.5c0-3,2.4-5.5,5.5-5.5c3,0,5.5,2.4,5.5,5.5 - C19.5,14,17,16.4,14,16.4z"/> - <path d="M14,5.5C11,5.5,8.6,8,8.6,11c0,3,2.4,5.5,5.5,5.5c3,0,5.5-2.4,5.5-5.5C19.5,8,17,5.5,14,5.5z M14,15.4 - c-2.5,0-4.5-2-4.5-4.5c0-2.5,2-4.5,4.5-4.5c2.5,0,4.5,2,4.5,4.5C18.5,13.4,16.5,15.4,14,15.4z"/> - <path d="M20.9,2.8h-1.3l-1.7-2.4c-0.2-0.2-0.5-0.6-0.8-0.6h-6.3c-0.3,0-0.6,0.4-0.8,0.6L8.4,2.8h-6c-1.3,0-2.1,0.8-2.1,2.1V17 - c0,1.3,0.8,2.8,2.1,2.8h18.5c1.3,0,2.3-1.5,2.3-2.8V4.9C23.2,3.6,22.2,2.8,20.9,2.8z M2.2,17V4.9c0-0.2-0.1-0.1,0.1-0.1h3.9v13H2.4 - C2.2,17.8,2.2,17.2,2.2,17z M21.2,17c0,0.2-0.1,0.8-0.3,0.8H7.2v-13h1.7c0.3,0,0.6-0.4,0.8-0.6l1.7-2.4h5.3l1.7,2.4 - c0.2,0.2,0.5,0.6,0.8,0.6h1.8c0.2,0,0.3-0.1,0.3,0.1V17z"/> -</g> -</svg> diff --git a/examples/multimediawidgets/camera/imagesettings.cpp b/examples/multimediawidgets/camera/imagesettings.cpp deleted file mode 100644 index a14e519e7..000000000 --- a/examples/multimediawidgets/camera/imagesettings.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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 "imagesettings.h" -#include "ui_imagesettings.h" - -#include <QComboBox> -#include <QDebug> -#include <QImageCapture> -#include <QCamera> -#include <QMediaCaptureSession> - -ImageSettings::ImageSettings(QImageCapture *imageCapture, QWidget *parent) : - QDialog(parent), - ui(new Ui::ImageSettingsUi), - imagecapture(imageCapture) -{ - ui->setupUi(this); - - //image codecs - ui->imageCodecBox->addItem(tr("Default image format"), QVariant(QString())); - const auto supportedImageFormats = QImageCapture::supportedFormats(); - for (const auto &f : supportedImageFormats) { - QString description = QImageCapture::fileFormatDescription(f); - ui->imageCodecBox->addItem(QImageCapture::fileFormatName(f) + ": " + description, QVariant::fromValue(f)); - } - - ui->imageQualitySlider->setRange(0, int(QImageCapture::VeryHighQuality)); - - ui->imageResolutionBox->addItem(tr("Default Resolution")); - const QList<QSize> supportedResolutions = imagecapture->captureSession()->camera()->cameraDevice().photoResolutions(); - for (const QSize &resolution : supportedResolutions) { - ui->imageResolutionBox->addItem(QString("%1x%2").arg(resolution.width()).arg(resolution.height()), - QVariant(resolution)); - } - - selectComboBoxItem(ui->imageCodecBox, QVariant::fromValue(imagecapture->fileFormat())); - selectComboBoxItem(ui->imageResolutionBox, QVariant(imagecapture->resolution())); - ui->imageQualitySlider->setValue(imagecapture->quality()); -} - -ImageSettings::~ImageSettings() -{ - delete ui; -} - -void ImageSettings::changeEvent(QEvent *e) -{ - QDialog::changeEvent(e); - switch (e->type()) { - case QEvent::LanguageChange: - ui->retranslateUi(this); - break; - default: - break; - } -} - -void ImageSettings::applyImageSettings() const -{ - imagecapture->setFileFormat(boxValue(ui->imageCodecBox).value<QImageCapture::FileFormat>()); - imagecapture->setQuality(QImageCapture::Quality(ui->imageQualitySlider->value())); - imagecapture->setResolution(boxValue(ui->imageResolutionBox).toSize()); -} - -QVariant ImageSettings::boxValue(const QComboBox *box) const -{ - int idx = box->currentIndex(); - if (idx == -1) - return QVariant(); - - return box->itemData(idx); -} - -void ImageSettings::selectComboBoxItem(QComboBox *box, const QVariant &value) -{ - for (int i = 0; i < box->count(); ++i) { - if (box->itemData(i) == value) { - box->setCurrentIndex(i); - break; - } - } -} diff --git a/examples/multimediawidgets/camera/imagesettings.h b/examples/multimediawidgets/camera/imagesettings.h deleted file mode 100644 index 6564bd91c..000000000 --- a/examples/multimediawidgets/camera/imagesettings.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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$ -** -****************************************************************************/ - -#ifndef IMAGESETTINGS_H -#define IMAGESETTINGS_H - -#include <QDialog> - -QT_BEGIN_NAMESPACE -class QComboBox; -class QImageCapture; -namespace Ui { class ImageSettingsUi; } -QT_END_NAMESPACE - -class ImageSettings : public QDialog -{ - Q_OBJECT - -public: - explicit ImageSettings(QImageCapture *imageCapture, QWidget *parent = nullptr); - ~ImageSettings(); - - void applyImageSettings() const; - - QString format() const; - void setFormat(const QString &format); - -protected: - void changeEvent(QEvent *e) override; - -private: - QVariant boxValue(const QComboBox *box) const; - void selectComboBoxItem(QComboBox *box, const QVariant &value); - - Ui::ImageSettingsUi *ui; - QImageCapture *imagecapture; -}; - -#endif // IMAGESETTINGS_H diff --git a/examples/multimediawidgets/camera/imagesettings.ui b/examples/multimediawidgets/camera/imagesettings.ui deleted file mode 100644 index 8c59ca01d..000000000 --- a/examples/multimediawidgets/camera/imagesettings.ui +++ /dev/null @@ -1,123 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>ImageSettingsUi</class> - <widget class="QDialog" name="ImageSettingsUi"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>332</width> - <height>270</height> - </rect> - </property> - <property name="windowTitle"> - <string>Image Settings</string> - </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0"> - <widget class="QGroupBox" name="groupBox_2"> - <property name="title"> - <string>Image</string> - </property> - <layout class="QGridLayout" name="gridLayout_2"> - <item row="0" column="0" colspan="2"> - <widget class="QLabel" name="label_8"> - <property name="text"> - <string>Resolution:</string> - </property> - </widget> - </item> - <item row="1" column="0" colspan="2"> - <widget class="QComboBox" name="imageResolutionBox"/> - </item> - <item row="2" column="0" colspan="2"> - <widget class="QLabel" name="label_6"> - <property name="text"> - <string>Image Format:</string> - </property> - </widget> - </item> - <item row="3" column="0" colspan="2"> - <widget class="QComboBox" name="imageCodecBox"/> - </item> - <item row="4" column="0"> - <widget class="QLabel" name="label_7"> - <property name="text"> - <string>Quality:</string> - </property> - </widget> - </item> - <item row="4" column="1"> - <widget class="QSlider" name="imageQualitySlider"> - <property name="maximum"> - <number>4</number> - </property> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item row="1" column="0"> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>14</height> - </size> - </property> - </spacer> - </item> - <item row="2" column="0"> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> - </property> - </widget> - </item> - </layout> - </widget> - <resources/> - <connections> - <connection> - <sender>buttonBox</sender> - <signal>accepted()</signal> - <receiver>ImageSettingsUi</receiver> - <slot>accept()</slot> - <hints> - <hint type="sourcelabel"> - <x>322</x> - <y>272</y> - </hint> - <hint type="destinationlabel"> - <x>44</x> - <y>230</y> - </hint> - </hints> - </connection> - <connection> - <sender>buttonBox</sender> - <signal>rejected()</signal> - <receiver>ImageSettingsUi</receiver> - <slot>reject()</slot> - <hints> - <hint type="sourcelabel"> - <x>405</x> - <y>262</y> - </hint> - <hint type="destinationlabel"> - <x>364</x> - <y>227</y> - </hint> - </hints> - </connection> - </connections> -</ui> diff --git a/examples/multimediawidgets/camera/ios/Info.plist.in b/examples/multimediawidgets/camera/ios/Info.plist.in deleted file mode 100644 index 6a6b8db11..000000000 --- a/examples/multimediawidgets/camera/ios/Info.plist.in +++ /dev/null @@ -1,50 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundlePackageType</key> - <string>APPL</string> - - <key>CFBundleName</key> - <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string> - <key>CFBundleIdentifier</key> - <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string> - <key>CFBundleExecutable</key> - <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string> - - <key>CFBundleVersion</key> - <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string> - <key>CFBundleShortVersionString</key> - <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string> - - <key>CFBundleGetInfoString</key> - <string>${MACOSX_BUNDLE_INFO_STRING}</string> - <key>NSHumanReadableCopyright</key> - <string>${MACOSX_BUNDLE_COPYRIGHT}</string> - - <key>CFBundleIconFile</key> - <string>${MACOSX_BUNDLE_ICON_FILE}</string> - - <key>CFBundleDevelopmentRegion</key> - <string>English</string> - - <key>LSRequiresIPhoneOS</key> - <true/> - - <key>UISupportedInterfaceOrientations</key> - <array> - <string>UIInterfaceOrientationPortrait</string> - <string>UIInterfaceOrientationPortraitUpsideDown</string> - <string>UIInterfaceOrientationLandscapeLeft</string> - <string>UIInterfaceOrientationLandscapeRight</string> - </array> - - <key>NSCameraUsageDescription</key> - <string>Qt Multimedia Example</string> - <key>NSMicrophoneUsageDescription</key> - <string>Qt Multimedia Example</string> -</dict> -</plist> - diff --git a/examples/multimediawidgets/camera/macos/Info.plist.in b/examples/multimediawidgets/camera/macos/Info.plist.in deleted file mode 100644 index ae2d945f1..000000000 --- a/examples/multimediawidgets/camera/macos/Info.plist.in +++ /dev/null @@ -1,49 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundlePackageType</key> - <string>APPL</string> - - <key>CFBundleName</key> - <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string> - <key>CFBundleIdentifier</key> - <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string> - <key>CFBundleExecutable</key> - <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string> - - <key>CFBundleVersion</key> - <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string> - <key>CFBundleShortVersionString</key> - <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string> - <key>CFBundleLongVersionString</key> - <string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string> - - <key>LSMinimumSystemVersion</key> - <string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string> - - <key>CFBundleGetInfoString</key> - <string>${MACOSX_BUNDLE_INFO_STRING}</string> - <key>NSHumanReadableCopyright</key> - <string>${MACOSX_BUNDLE_COPYRIGHT}</string> - - <key>CFBundleIconFile</key> - <string>${MACOSX_BUNDLE_ICON_FILE}</string> - - <key>CFBundleDevelopmentRegion</key> - <string>English</string> - - <key>NSPrincipalClass</key> - <string>NSApplication</string> - - <key>NSCameraUsageDescription</key> - <string>Qt Multimedia Example</string> - <key>NSMicrophoneUsageDescription</key> - <string>Qt Multimedia Example</string> - - <key>NSSupportsAutomaticGraphicsSwitching</key> - <true/> -</dict> -</plist> diff --git a/examples/multimediawidgets/camera/main.cpp b/examples/multimediawidgets/camera/main.cpp deleted file mode 100644 index 04982a725..000000000 --- a/examples/multimediawidgets/camera/main.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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 "camera.h" - -#include <QtWidgets> - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - - Camera camera; - camera.show(); - - return app.exec(); -}; diff --git a/examples/multimediawidgets/camera/metadatadialog.cpp b/examples/multimediawidgets/camera/metadatadialog.cpp deleted file mode 100644 index 28d8db035..000000000 --- a/examples/multimediawidgets/camera/metadatadialog.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 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 "metadatadialog.h" -#include "camera.h" - -#include <QtWidgets> -#include <QFormLayout> -#include <QMediaMetaData> - -MetaDataDialog::MetaDataDialog(QWidget *parent) - : QDialog(parent) -{ - QFormLayout *metaDataLayout = new QFormLayout; - for (int key = 0; key < QMediaMetaData::NumMetaData; key++) { - QString label = QMediaMetaData::metaDataKeyToString(static_cast<QMediaMetaData::Key>(key)); - m_metaDataFields[key] = new QLineEdit; - if (key == QMediaMetaData::ThumbnailImage) { - QPushButton *openThumbnail = new QPushButton(tr("Open")); - connect(openThumbnail, &QPushButton::clicked, this, &MetaDataDialog::openThumbnailImage); - QHBoxLayout *layout = new QHBoxLayout; - layout->addWidget(m_metaDataFields[key]); - layout->addWidget(openThumbnail); - metaDataLayout->addRow(label, layout); - } - else if (key == QMediaMetaData::CoverArtImage) { - QPushButton *openCoverArt = new QPushButton(tr("Open")); - connect(openCoverArt, &QPushButton::clicked, this, &MetaDataDialog::openCoverArtImage); - QHBoxLayout *layout = new QHBoxLayout; - layout->addWidget(m_metaDataFields[key]); - layout->addWidget(openCoverArt); - metaDataLayout->addRow(label, layout); - } - else { - if (key == QMediaMetaData::Title) - m_metaDataFields[key]->setText(tr("Qt Camera Example")); - else if (key == QMediaMetaData::Author) - m_metaDataFields[key]->setText(tr("The Qt Company")); - else if (key == QMediaMetaData::Date) - m_metaDataFields[key]->setText(QDateTime::currentDateTime().toString()); - else if (key == QMediaMetaData::Date) - m_metaDataFields[key]->setText(QDate::currentDate().toString()); - metaDataLayout->addRow(label, m_metaDataFields[key]); - } - } - - QWidget *viewport = new QWidget; - viewport->setLayout(metaDataLayout); - QScrollArea *scrollArea = new QScrollArea; - scrollArea->setWidget(viewport); - QVBoxLayout *dialogLayout = new QVBoxLayout(); - this->setLayout(dialogLayout); - this->layout()->addWidget(scrollArea); - - auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok - | QDialogButtonBox::Cancel); - this->layout()->addWidget(buttonBox); - - this->setWindowTitle(tr("Set Metadata")); - this->resize(400, 300); - - connect(buttonBox, &QDialogButtonBox::accepted, this, &MetaDataDialog::accept); - connect(buttonBox, &QDialogButtonBox::rejected, this, &MetaDataDialog::reject); -} - -void MetaDataDialog::openThumbnailImage() -{ - QString fileName = QFileDialog::getOpenFileName(this, - tr("Open Image"), QDir::currentPath(), tr("Image Files (*.png *.jpg *.bmp)")); - if (!fileName.isEmpty()) - m_metaDataFields[QMediaMetaData::ThumbnailImage]->setText(fileName); -} - -void MetaDataDialog::openCoverArtImage() -{ - QString fileName = QFileDialog::getOpenFileName(this, - tr("Open Image"), QDir::currentPath(), tr("Image Files (*.png *.jpg *.bmp)")); - if (!fileName.isEmpty()) - m_metaDataFields[QMediaMetaData::CoverArtImage]->setText(fileName); -} diff --git a/examples/multimediawidgets/camera/metadatadialog.h b/examples/multimediawidgets/camera/metadatadialog.h deleted file mode 100644 index 0269e3479..000000000 --- a/examples/multimediawidgets/camera/metadatadialog.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 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$ -** -****************************************************************************/ - -#ifndef DIALOG_H -#define DIALOG_H - -#include <QDialog> -#include <QMediaMetaData> - -QT_BEGIN_NAMESPACE -class QLabel; -class QLineEdit; -QT_END_NAMESPACE - -//! [0] -class MetaDataDialog : public QDialog -{ - Q_OBJECT - -public: - explicit MetaDataDialog(QWidget *parent = nullptr); - - QLineEdit *m_metaDataFields[QMediaMetaData::NumMetaData] = {}; - -private slots: - void openThumbnailImage(); - void openCoverArtImage(); -}; -//! [0] - -#endif diff --git a/examples/multimediawidgets/camera/videosettings.cpp b/examples/multimediawidgets/camera/videosettings.cpp deleted file mode 100644 index f515d1bca..000000000 --- a/examples/multimediawidgets/camera/videosettings.cpp +++ /dev/null @@ -1,248 +0,0 @@ -/**************************************************************************** -** -** 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 "videosettings.h" -#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) -#include "ui_videosettings_mobile.h" -#else -#include "ui_videosettings.h" -#endif - -#include <QComboBox> -#include <QSpinBox> -#include <QDebug> -#include <QMediaRecorder> -#include <QMediaFormat> -#include <QAudioDevice> -#include <QMediaCaptureSession> -#include <QCameraDevice> -#include <QCamera> -#include <QAudioInput> - -QString toFormattedString(const QCameraFormat &cameraFormat) -{ - QString string; - const auto &separator = QStringLiteral(" "); - - string.append(QVideoFrameFormat::pixelFormatToString(cameraFormat.pixelFormat())); - string.append(separator); - - string.append(QString::number(cameraFormat.resolution().width())); - string.append(QStringLiteral("x")); - string.append(QString::number(cameraFormat.resolution().height())); - string.append(separator); - - string.append(QString::number(cameraFormat.minFrameRate())); - string.append(QStringLiteral("-")); - string.append(QString::number(cameraFormat.maxFrameRate())); - string.append(QStringLiteral("FPS")); - - return string; -} - -VideoSettings::VideoSettings(QMediaRecorder *mediaRecorder, QWidget *parent) - : QDialog(parent), - ui(new Ui::VideoSettingsUi), - mediaRecorder(mediaRecorder) -{ - ui->setupUi(this); - - //sample rate: - auto audioDevice = mediaRecorder->captureSession()->audioInput()->device(); - ui->audioSampleRateBox->setRange(audioDevice.minimumSampleRate(), - audioDevice.maximumSampleRate()); - - // camera format - ui->videoFormatBox->addItem(tr("Default camera format")); - - const QList<QCameraFormat> videoFormats = - mediaRecorder->captureSession()->camera()->cameraDevice().videoFormats(); - - for (const QCameraFormat &format : videoFormats) { - ui->videoFormatBox->addItem(toFormattedString(format), QVariant::fromValue(format)); - } - - connect(ui->videoFormatBox, &QComboBox::currentIndexChanged, [this](int /*index*/) { - const auto &cameraFormat = boxValue(ui->videoFormatBox).value<QCameraFormat>(); - ui->fpsSlider->setRange(cameraFormat.minFrameRate(), cameraFormat.maxFrameRate()); - ui->fpsSpinBox->setRange(cameraFormat.minFrameRate(), cameraFormat.maxFrameRate()); - }); - - auto currentCameraFormat = mediaRecorder->captureSession()->camera()->cameraFormat(); - ui->fpsSlider->setRange(currentCameraFormat.minFrameRate(), currentCameraFormat.maxFrameRate()); - ui->fpsSpinBox->setRange(currentCameraFormat.minFrameRate(), - currentCameraFormat.maxFrameRate()); - - connect(ui->fpsSlider, &QSlider::valueChanged, ui->fpsSpinBox, &QSpinBox::setValue); - connect(ui->fpsSpinBox, &QSpinBox::valueChanged, ui->fpsSlider, &QSlider::setValue); - - updateFormatsAndCodecs(); - connect(ui->audioCodecBox, &QComboBox::currentIndexChanged, this, &VideoSettings::updateFormatsAndCodecs); - connect(ui->videoCodecBox, &QComboBox::currentIndexChanged, this, &VideoSettings::updateFormatsAndCodecs); - connect(ui->containerFormatBox, &QComboBox::currentIndexChanged, this, &VideoSettings::updateFormatsAndCodecs); - - ui->qualitySlider->setRange(0, int(QMediaRecorder::VeryHighQuality)); - - QMediaFormat format = mediaRecorder->mediaFormat(); - selectComboBoxItem(ui->containerFormatBox, QVariant::fromValue(format.fileFormat())); - selectComboBoxItem(ui->audioCodecBox, QVariant::fromValue(format.audioCodec())); - selectComboBoxItem(ui->videoCodecBox, QVariant::fromValue(format.videoCodec())); - - ui->qualitySlider->setValue(mediaRecorder->quality()); - ui->audioSampleRateBox->setValue(mediaRecorder->audioSampleRate()); - selectComboBoxItem( - ui->videoFormatBox, - QVariant::fromValue(mediaRecorder->captureSession()->camera()->cameraFormat())); - - ui->fpsSlider->setValue(mediaRecorder->videoFrameRate()); - ui->fpsSpinBox->setValue(mediaRecorder->videoFrameRate()); -} - -VideoSettings::~VideoSettings() -{ - delete ui; -} - -void VideoSettings::changeEvent(QEvent *e) -{ - QDialog::changeEvent(e); - switch (e->type()) { - case QEvent::LanguageChange: - ui->retranslateUi(this); - break; - default: - break; - } -} - -void VideoSettings::applySettings() -{ - QMediaFormat format; - format.setFileFormat(boxValue(ui->containerFormatBox).value<QMediaFormat::FileFormat>()); - format.setAudioCodec(boxValue(ui->audioCodecBox).value<QMediaFormat::AudioCodec>()); - format.setVideoCodec(boxValue(ui->videoCodecBox).value<QMediaFormat::VideoCodec>()); - - mediaRecorder->setMediaFormat(format); - mediaRecorder->setQuality(QMediaRecorder::Quality(ui->qualitySlider->value())); - mediaRecorder->setAudioSampleRate(ui->audioSampleRateBox->value()); - - const auto &cameraFormat = boxValue(ui->videoFormatBox).value<QCameraFormat>(); - mediaRecorder->setVideoResolution(cameraFormat.resolution()); - mediaRecorder->setVideoFrameRate(ui->fpsSlider->value()); - - mediaRecorder->captureSession()->camera()->setCameraFormat(cameraFormat); -} - -void VideoSettings::updateFormatsAndCodecs() -{ - if (m_updatingFormats) - return; - m_updatingFormats = true; - - QMediaFormat format; - if (ui->containerFormatBox->count()) - format.setFileFormat(boxValue(ui->containerFormatBox).value<QMediaFormat::FileFormat>()); - if (ui->audioCodecBox->count()) - format.setAudioCodec(boxValue(ui->audioCodecBox).value<QMediaFormat::AudioCodec>()); - if (ui->videoCodecBox->count()) - format.setVideoCodec(boxValue(ui->videoCodecBox).value<QMediaFormat::VideoCodec>()); - - int currentIndex = 0; - ui->audioCodecBox->clear(); - ui->audioCodecBox->addItem(tr("Default audio codec"), QVariant::fromValue(QMediaFormat::AudioCodec::Unspecified)); - for (auto codec : format.supportedAudioCodecs(QMediaFormat::Encode)) { - if (codec == format.audioCodec()) - currentIndex = ui->audioCodecBox->count(); - ui->audioCodecBox->addItem(QMediaFormat::audioCodecDescription(codec), QVariant::fromValue(codec)); - } - ui->audioCodecBox->setCurrentIndex(currentIndex); - - currentIndex = 0; - ui->videoCodecBox->clear(); - ui->videoCodecBox->addItem(tr("Default video codec"), QVariant::fromValue(QMediaFormat::VideoCodec::Unspecified)); - for (auto codec : format.supportedVideoCodecs(QMediaFormat::Encode)) { - if (codec == format.videoCodec()) - currentIndex = ui->videoCodecBox->count(); - ui->videoCodecBox->addItem(QMediaFormat::videoCodecDescription(codec), QVariant::fromValue(codec)); - } - ui->videoCodecBox->setCurrentIndex(currentIndex); - - currentIndex = 0; - ui->containerFormatBox->clear(); - ui->containerFormatBox->addItem(tr("Default file format"), QVariant::fromValue(QMediaFormat::UnspecifiedFormat)); - for (auto container : format.supportedFileFormats(QMediaFormat::Encode)) { - if (container == format.fileFormat()) - currentIndex = ui->containerFormatBox->count(); - ui->containerFormatBox->addItem(QMediaFormat::fileFormatDescription(container), QVariant::fromValue(container)); - } - ui->containerFormatBox->setCurrentIndex(currentIndex); - - m_updatingFormats = false; - -} - -QVariant VideoSettings::boxValue(const QComboBox *box) const -{ - int idx = box->currentIndex(); - if (idx == -1) - return QVariant(); - - return box->itemData(idx); -} - -void VideoSettings::selectComboBoxItem(QComboBox *box, const QVariant &value) -{ - for (int i = 0; i < box->count(); ++i) { - if (box->itemData(i) == value) { - box->setCurrentIndex(i); - break; - } - } -} diff --git a/examples/multimediawidgets/camera/videosettings.h b/examples/multimediawidgets/camera/videosettings.h deleted file mode 100644 index 14e00bc25..000000000 --- a/examples/multimediawidgets/camera/videosettings.h +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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$ -** -****************************************************************************/ - -#ifndef VIDEOSETTINGS_H -#define VIDEOSETTINGS_H - -#include <QDialog> - -QT_BEGIN_NAMESPACE -class QComboBox; -class QMediaRecorder; -namespace Ui { class VideoSettingsUi; } -QT_END_NAMESPACE - -class VideoSettings : public QDialog -{ - Q_OBJECT - -public: - explicit VideoSettings(QMediaRecorder *mediaRecorder, QWidget *parent = nullptr); - ~VideoSettings(); - - void applySettings(); - void updateFormatsAndCodecs(); - -protected: - void changeEvent(QEvent *e) override; - -private: - QVariant boxValue(const QComboBox*) const; - void selectComboBoxItem(QComboBox *box, const QVariant &value); - - Ui::VideoSettingsUi *ui; - QMediaRecorder *mediaRecorder; - bool m_updatingFormats = false; -}; - -#endif // VIDEOSETTINGS_H diff --git a/examples/multimediawidgets/camera/videosettings.ui b/examples/multimediawidgets/camera/videosettings.ui deleted file mode 100644 index 3c1f71f11..000000000 --- a/examples/multimediawidgets/camera/videosettings.ui +++ /dev/null @@ -1,213 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>VideoSettingsUi</class> - <widget class="QDialog" name="VideoSettingsUi"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>686</width> - <height>499</height> - </rect> - </property> - <property name="windowTitle"> - <string>Video Settings</string> - </property> - <layout class="QGridLayout" name="gridLayout_3"> - <item row="4" column="1"> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QGroupBox" name="groupBox_2"> - <property name="title"> - <string>Video</string> - </property> - <layout class="QGridLayout" name="gridLayout_2"> - <item row="0" column="0" colspan="2"> - <widget class="QLabel" name="label_8"> - <property name="text"> - <string>Camera Format</string> - </property> - </widget> - </item> - <item row="5" column="0" colspan="2"> - <widget class="QComboBox" name="videoCodecBox"/> - </item> - <item row="2" column="0" colspan="2"> - <widget class="QLabel" name="label_9"> - <property name="text"> - <string>Framerate:</string> - </property> - </widget> - </item> - <item row="4" column="0" colspan="2"> - <widget class="QLabel" name="label_6"> - <property name="text"> - <string>Video Codec:</string> - </property> - </widget> - </item> - <item row="1" column="0" colspan="2"> - <widget class="QComboBox" name="videoFormatBox"/> - </item> - <item row="3" column="0" colspan="2"> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QSpinBox" name="fpsSpinBox"/> - </item> - <item> - <widget class="QSlider" name="fpsSlider"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - </item> - <item row="2" column="0"> - <widget class="QWidget" name="widget" native="true"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <layout class="QVBoxLayout" name="verticalLayout_3"> - <property name="leftMargin"> - <number>0</number> - </property> - <property name="topMargin"> - <number>0</number> - </property> - <property name="rightMargin"> - <number>0</number> - </property> - <property name="bottomMargin"> - <number>0</number> - </property> - <item> - <widget class="QGroupBox" name="groupBox_3"> - <property name="title"> - <string>Audio</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>Audio Codec:</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="audioCodecBox"/> - </item> - <item> - <widget class="QLabel" name="label_5"> - <property name="text"> - <string>Sample Rate:</string> - </property> - </widget> - </item> - <item> - <widget class="QSpinBox" name="audioSampleRateBox"/> - </item> - </layout> - </widget> - </item> - <item> - <widget class="QGroupBox" name="groupBox"> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QLabel" name="label_3"> - <property name="text"> - <string>Quality:</string> - </property> - </widget> - </item> - <item> - <widget class="QSlider" name="qualitySlider"> - <property name="maximum"> - <number>4</number> - </property> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_4"> - <property name="text"> - <string>File Format:</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="containerFormatBox"/> - </item> - </layout> - </widget> - </item> - </layout> - </widget> - </item> - <item row="3" column="0"> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - </layout> - </widget> - <resources/> - <connections> - <connection> - <sender>buttonBox</sender> - <signal>accepted()</signal> - <receiver>VideoSettingsUi</receiver> - <slot>accept()</slot> - <hints> - <hint type="sourcelabel"> - <x>322</x> - <y>272</y> - </hint> - <hint type="destinationlabel"> - <x>44</x> - <y>230</y> - </hint> - </hints> - </connection> - <connection> - <sender>buttonBox</sender> - <signal>rejected()</signal> - <receiver>VideoSettingsUi</receiver> - <slot>reject()</slot> - <hints> - <hint type="sourcelabel"> - <x>405</x> - <y>262</y> - </hint> - <hint type="destinationlabel"> - <x>364</x> - <y>227</y> - </hint> - </hints> - </connection> - </connections> -</ui> diff --git a/examples/multimediawidgets/camera/videosettings_mobile.ui b/examples/multimediawidgets/camera/videosettings_mobile.ui deleted file mode 100644 index 6584f07f9..000000000 --- a/examples/multimediawidgets/camera/videosettings_mobile.ui +++ /dev/null @@ -1,207 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>VideoSettingsUi</class> - <widget class="QDialog" name="VideoSettingsUi"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>329</width> - <height>591</height> - </rect> - </property> - <property name="windowTitle"> - <string>Video Settings</string> - </property> - <layout class="QGridLayout" name="gridLayout_3"> - <item row="2" column="0"> - <widget class="QWidget" name="widget" native="true"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <layout class="QVBoxLayout" name="verticalLayout_3"> - <property name="leftMargin"> - <number>0</number> - </property> - <property name="topMargin"> - <number>0</number> - </property> - <property name="rightMargin"> - <number>0</number> - </property> - <property name="bottomMargin"> - <number>0</number> - </property> - <item> - <widget class="QGroupBox" name="groupBox_3"> - <property name="title"> - <string>Audio</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>Audio Codec:</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="audioCodecBox"/> - </item> - <item> - <widget class="QLabel" name="label_5"> - <property name="text"> - <string>Sample Rate:</string> - </property> - </widget> - </item> - <item> - <widget class="QSpinBox" name="audioSampleRateBox"/> - </item> - </layout> - </widget> - </item> - <item> - <widget class="QGroupBox" name="groupBox"> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QLabel" name="label_3"> - <property name="text"> - <string>Quality:</string> - </property> - </widget> - </item> - <item> - <widget class="QSlider" name="qualitySlider"> - <property name="maximum"> - <number>4</number> - </property> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_4"> - <property name="text"> - <string>File Format:</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="containerFormatBox"/> - </item> - </layout> - </widget> - </item> - </layout> - </widget> - </item> - <item row="3" column="0"> - <widget class="QGroupBox" name="groupBox_2"> - <property name="title"> - <string>Video</string> - </property> - <layout class="QGridLayout" name="gridLayout_2"> - <item row="2" column="0"> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Frames per second:</string> - </property> - </widget> - </item> - <item row="6" column="0" colspan="2"> - <widget class="QComboBox" name="videoCodecBox"/> - </item> - <item row="0" column="0" colspan="2"> - <widget class="QLabel" name="label_8"> - <property name="text"> - <string>Camera Format:</string> - </property> - </widget> - </item> - <item row="5" column="0" colspan="2"> - <widget class="QLabel" name="label_6"> - <property name="text"> - <string>Video Codec:</string> - </property> - </widget> - </item> - <item row="1" column="0" colspan="2"> - <widget class="QComboBox" name="videoFormatBox"/> - </item> - <item row="7" column="0"> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> - </property> - </widget> - </item> - <item row="3" column="0"> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QSpinBox" name="fpsSpinBox"> - <property name="minimum"> - <number>8</number> - </property> - <property name="maximum"> - <number>30</number> - </property> - </widget> - </item> - <item> - <widget class="QSlider" name="fpsSlider"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - </item> - </layout> - </widget> - <resources/> - <connections> - <connection> - <sender>buttonBox</sender> - <signal>accepted()</signal> - <receiver>VideoSettingsUi</receiver> - <slot>accept()</slot> - <hints> - <hint type="sourcelabel"> - <x>322</x> - <y>272</y> - </hint> - <hint type="destinationlabel"> - <x>44</x> - <y>230</y> - </hint> - </hints> - </connection> - <connection> - <sender>buttonBox</sender> - <signal>rejected()</signal> - <receiver>VideoSettingsUi</receiver> - <slot>reject()</slot> - <hints> - <hint type="sourcelabel"> - <x>405</x> - <y>262</y> - </hint> - <hint type="destinationlabel"> - <x>364</x> - <y>227</y> - </hint> - </hints> - </connection> - </connections> -</ui> diff --git a/examples/multimediawidgets/multimediawidgets.pro b/examples/multimediawidgets/multimediawidgets.pro deleted file mode 100644 index aa74b00f0..000000000 --- a/examples/multimediawidgets/multimediawidgets.pro +++ /dev/null @@ -1,10 +0,0 @@ -TEMPLATE = subdirs - -# These examples all need widgets for now (using creator templates that use widgets) -qtHaveModule(widgets) { - SUBDIRS += \ - camera \ - videographicsitem \ - videowidget \ - player -} diff --git a/examples/multimediawidgets/player/CMakeLists.txt b/examples/multimediawidgets/player/CMakeLists.txt deleted file mode 100644 index 7c0304eaf..000000000 --- a/examples/multimediawidgets/player/CMakeLists.txt +++ /dev/null @@ -1,38 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project(player LANGUAGES CXX) - -set(CMAKE_AUTOMOC ON) - -if(NOT DEFINED INSTALL_EXAMPLESDIR) - set(INSTALL_EXAMPLESDIR "examples") -endif() - -set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/multimediawidgets/player") - -find_package(Qt6 REQUIRED COMPONENTS MultimediaWidgets Network) - -qt_add_executable(player - main.cpp - player.cpp player.h - playercontrols.cpp playercontrols.h - playlistmodel.cpp playlistmodel.h - videowidget.cpp videowidget.h - qmediaplaylist.cpp qmediaplaylist.h qmediaplaylist_p.h - qplaylistfileparser.cpp qplaylistfileparser_p.h -) - -set_target_properties(player PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) - -target_link_libraries(player PUBLIC - Qt::MultimediaWidgets - Qt::Network -) - -install(TARGETS player - RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" - BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" - LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" -) diff --git a/examples/multimediawidgets/player/doc/images/mediaplayerex.jpg b/examples/multimediawidgets/player/doc/images/mediaplayerex.jpg Binary files differdeleted file mode 100644 index e875bd134..000000000 --- a/examples/multimediawidgets/player/doc/images/mediaplayerex.jpg +++ /dev/null diff --git a/examples/multimediawidgets/player/doc/src/player.qdoc b/examples/multimediawidgets/player/doc/src/player.qdoc deleted file mode 100644 index dad969375..000000000 --- a/examples/multimediawidgets/player/doc/src/player.qdoc +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2021 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** 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. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example multimediawidgets/player - \title Media Player Example - \ingroup multimedia_examples - \ingroup video_examples - \brief Playing audio and video. - \meta {tag} {widgets} - - \image mediaplayerex.jpg - - \e{Media Player} demonstrates a simple multimedia player that can play - audio and or video files using various codecs. - - \include examples-run.qdocinc - - The example uses a QMediaPlayer object passed into a QVideoWidget to - control the video output. To give the application playlist capability - we also use a QPlayList object. - - To activate the various functions such as play and stop on the dialog, - the button clicked events emit the play() and stop() signals, which - are connected to the play() and stop() slots of QMediaPlayer. - - \code - connect(controls, SIGNAL(play()), player, SLOT(play())); - connect(controls, SIGNAL(pause()), player, SLOT(pause())); - connect(controls, SIGNAL(stop()), player, SLOT(stop())); - \endcode - - We can get the volume (and set our user interface representation) - - \code - controls->setVolume(player->volume()); - \endcode - - and we can make widget 'volume' changes change the volume - - \code - connect(controls, SIGNAL(changeVolume(int)), player, SLOT(setVolume(int))); - \endcode - - The example also allows us to change video properties by means - of the QVideoWidget object. We can go to Full Screen mode with a single - button click, and back again. -*/ diff --git a/examples/multimediawidgets/player/main.cpp b/examples/multimediawidgets/player/main.cpp deleted file mode 100644 index 49c82d877..000000000 --- a/examples/multimediawidgets/player/main.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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 "player.h" - -#include <QApplication> -#include <QCommandLineParser> -#include <QCommandLineOption> -#include <QDir> -#include <QUrl> - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - - QCoreApplication::setApplicationName("Player Example"); - QCoreApplication::setOrganizationName("QtProject"); - QCoreApplication::setApplicationVersion(QT_VERSION_STR); - QCommandLineParser parser; - parser.setApplicationDescription("Qt MultiMedia Player Example"); - parser.addHelpOption(); - parser.addVersionOption(); - parser.addPositionalArgument("url", "The URL(s) to open."); - parser.process(app); - - Player player; - - if (!parser.positionalArguments().isEmpty() && player.isPlayerAvailable()) { - QList<QUrl> urls; - for (auto &a: parser.positionalArguments()) - urls.append(QUrl::fromUserInput(a, QDir::currentPath())); - player.addToPlaylist(urls); - } - - player.show(); - return app.exec(); -} diff --git a/examples/multimediawidgets/player/player.cpp b/examples/multimediawidgets/player/player.cpp deleted file mode 100644 index 25722673d..000000000 --- a/examples/multimediawidgets/player/player.cpp +++ /dev/null @@ -1,553 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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 "player.h" - -#include "playercontrols.h" -#include "playlistmodel.h" -#include "qmediaplaylist.h" -#include "videowidget.h" - -#include <QMediaMetaData> -#include <QMediaDevices> -#include <QAudioDevice> -#include <QAudioOutput> -#include <QMediaFormat> -#include <QtWidgets> - -Player::Player(QWidget *parent) - : QWidget(parent) -{ -//! [create-objs] - m_player = new QMediaPlayer(this); - m_audioOutput = new QAudioOutput(this); - m_player->setAudioOutput(m_audioOutput); -//! [create-objs] - connect(m_player, &QMediaPlayer::durationChanged, this, &Player::durationChanged); - connect(m_player, &QMediaPlayer::positionChanged, this, &Player::positionChanged); - connect(m_player, QOverload<>::of(&QMediaPlayer::metaDataChanged), this, &Player::metaDataChanged); - connect(m_player, &QMediaPlayer::mediaStatusChanged, this, &Player::statusChanged); - connect(m_player, &QMediaPlayer::bufferProgressChanged, this, &Player::bufferingProgress); - connect(m_player, &QMediaPlayer::hasVideoChanged, this, &Player::videoAvailableChanged); - connect(m_player, &QMediaPlayer::errorChanged, this, &Player::displayErrorMessage); - connect(m_player, &QMediaPlayer::tracksChanged, this, &Player::tracksChanged); - -//! [2] - m_videoWidget = new VideoWidget(this); - m_videoWidget->resize(1280, 720); - m_player->setVideoOutput(m_videoWidget); - - m_playlistModel = new PlaylistModel(this); - m_playlist = m_playlistModel->playlist(); -//! [2] - connect(m_playlist, &QMediaPlaylist::currentIndexChanged, this, &Player::playlistPositionChanged); - - // player layout - QBoxLayout *layout = new QVBoxLayout(this); - - // display - QBoxLayout *displayLayout = new QHBoxLayout; - displayLayout->addWidget(m_videoWidget, 2); -#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) - m_playlistView = new QListView(); - m_playlistView->setModel(m_playlistModel); - m_playlistView->setCurrentIndex(m_playlistModel->index(m_playlist->currentIndex(), 0)); - connect(m_playlistView, &QAbstractItemView::activated, this, &Player::jump); - displayLayout->addWidget(m_playlistView); -#endif - layout->addLayout(displayLayout); - - // duration slider and label - QHBoxLayout *hLayout = new QHBoxLayout; - - m_slider = new QSlider(Qt::Horizontal, this); - m_slider->setRange(0, m_player->duration()); - connect(m_slider, &QSlider::sliderMoved, this, &Player::seek); - hLayout->addWidget(m_slider); - - m_labelDuration = new QLabel(); - m_labelDuration->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); - hLayout->addWidget(m_labelDuration); - layout->addLayout(hLayout); - - // controls - QBoxLayout *controlLayout = new QHBoxLayout; - controlLayout->setContentsMargins(0, 0, 0, 0); - - QPushButton *openButton = new QPushButton(tr("Open"), this); - connect(openButton, &QPushButton::clicked, this, &Player::open); - controlLayout->addWidget(openButton); - controlLayout->addStretch(1); - - PlayerControls *controls = new PlayerControls(); - controls->setState(m_player->playbackState()); - controls->setVolume(m_audioOutput->volume()); - controls->setMuted(controls->isMuted()); - - connect(controls, &PlayerControls::play, m_player, &QMediaPlayer::play); - connect(controls, &PlayerControls::pause, m_player, &QMediaPlayer::pause); - connect(controls, &PlayerControls::stop, m_player, &QMediaPlayer::stop); - connect(controls, &PlayerControls::next, m_playlist, &QMediaPlaylist::next); - connect(controls, &PlayerControls::previous, this, &Player::previousClicked); - connect(controls, &PlayerControls::changeVolume, m_audioOutput, &QAudioOutput::setVolume); - connect(controls, &PlayerControls::changeMuting, m_audioOutput, &QAudioOutput::setMuted); - connect(controls, &PlayerControls::changeRate, m_player, &QMediaPlayer::setPlaybackRate); - connect(controls, &PlayerControls::stop, m_videoWidget, QOverload<>::of(&QVideoWidget::update)); - - connect(m_player, &QMediaPlayer::playbackStateChanged, controls, &PlayerControls::setState); - connect(m_audioOutput, &QAudioOutput::volumeChanged, controls, &PlayerControls::setVolume); - connect(m_audioOutput, &QAudioOutput::mutedChanged, controls, &PlayerControls::setMuted); - - controlLayout->addWidget(controls); - controlLayout->addStretch(1); - - m_fullScreenButton = new QPushButton(tr("FullScreen"), this); - m_fullScreenButton->setCheckable(true); - controlLayout->addWidget(m_fullScreenButton); - -#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) - m_audioOutputCombo = new QComboBox(this); - m_audioOutputCombo->addItem(QString::fromUtf8("Default"), QVariant::fromValue(QAudioDevice())); - for (auto &deviceInfo: QMediaDevices::audioOutputs()) - m_audioOutputCombo->addItem(deviceInfo.description(), QVariant::fromValue(deviceInfo)); - connect(m_audioOutputCombo, QOverload<int>::of(&QComboBox::activated), this, - &Player::audioOutputChanged); - controlLayout->addWidget(m_audioOutputCombo); -#endif - - layout->addLayout(controlLayout); - - // tracks - QGridLayout *tracksLayout = new QGridLayout; - - m_audioTracks = new QComboBox(this); - connect(m_audioTracks, &QComboBox::activated, this, &Player::selectAudioStream); - tracksLayout->addWidget(new QLabel(tr("Audio Tracks:")), 0, 0); - tracksLayout->addWidget(m_audioTracks, 0, 1); - - m_videoTracks = new QComboBox(this); - connect(m_videoTracks, &QComboBox::activated, this, &Player::selectVideoStream); - tracksLayout->addWidget(new QLabel(tr("Video Tracks:")), 1, 0); - tracksLayout->addWidget(m_videoTracks, 1, 1); - - m_subtitleTracks = new QComboBox(this); - connect(m_subtitleTracks, &QComboBox::activated, this, &Player::selectSubtitleStream); - tracksLayout->addWidget(new QLabel(tr("Subtitle Tracks:")), 2, 0); - tracksLayout->addWidget(m_subtitleTracks, 2, 1); - - layout->addLayout(tracksLayout); - -#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) - // metadata - - QLabel *metaDataLabel = new QLabel(tr("Metadata for file:")); - layout->addWidget(metaDataLabel); - - QGridLayout *metaDataLayout = new QGridLayout; - int key = QMediaMetaData::Title; - for (int i = 0; i < (QMediaMetaData::NumMetaData + 2) / 3; i++) { - for (int j = 0; j < 6; j += 2) { - m_metaDataLabels[key] = new QLabel( - QMediaMetaData::metaDataKeyToString(static_cast<QMediaMetaData::Key>(key))); - if (key == QMediaMetaData::ThumbnailImage || key == QMediaMetaData::CoverArtImage) - m_metaDataFields[key] = new QLabel; - else - m_metaDataFields[key] = new QLineEdit; - m_metaDataLabels[key]->setDisabled(true); - m_metaDataFields[key]->setDisabled(true); - metaDataLayout->addWidget(m_metaDataLabels[key], i, j); - metaDataLayout->addWidget(m_metaDataFields[key], i, j + 1); - key++; - if (key == QMediaMetaData::NumMetaData) - break; - } - } - - layout->addLayout(metaDataLayout); -#endif - -#if defined(Q_OS_QNX) - // On QNX, the main window doesn't have a title bar (or any other decorations). - // Create a status bar for the status information instead. - m_statusLabel = new QLabel; - m_statusBar = new QStatusBar; - m_statusBar->addPermanentWidget(m_statusLabel); - m_statusBar->setSizeGripEnabled(false); // Without mouse grabbing, it doesn't work very well. - layout->addWidget(m_statusBar); -#endif - - setLayout(layout); - - if (!isPlayerAvailable()) { - QMessageBox::warning(this, tr("Service not available"), - tr("The QMediaPlayer object does not have a valid service.\n"\ - "Please check the media service plugins are installed.")); - - controls->setEnabled(false); - if (m_playlistView) - m_playlistView->setEnabled(false); - openButton->setEnabled(false); - m_fullScreenButton->setEnabled(false); - } - - metaDataChanged(); -} - -bool Player::isPlayerAvailable() const -{ - return m_player->isAvailable(); -} - -void Player::open() -{ - QFileDialog fileDialog(this); - fileDialog.setAcceptMode(QFileDialog::AcceptOpen); - fileDialog.setWindowTitle(tr("Open Files")); - fileDialog.setDirectory(QStandardPaths::standardLocations(QStandardPaths::MoviesLocation).value(0, QDir::homePath())); - if (fileDialog.exec() == QDialog::Accepted) - addToPlaylist(fileDialog.selectedUrls()); -} - -static bool isPlaylist(const QUrl &url) // Check for ".m3u" playlists. -{ - if (!url.isLocalFile()) - return false; - const QFileInfo fileInfo(url.toLocalFile()); - return fileInfo.exists() && !fileInfo.suffix().compare(QLatin1String("m3u"), Qt::CaseInsensitive); -} - -void Player::addToPlaylist(const QList<QUrl> &urls) -{ - const int previousMediaCount = m_playlist->mediaCount(); - for (auto &url: urls) { - if (isPlaylist(url)) - m_playlist->load(url); - else - m_playlist->addMedia(url); - } - if (m_playlist->mediaCount() > previousMediaCount) { - auto index = m_playlistModel->index(previousMediaCount, 0); - if (m_playlistView) - m_playlistView->setCurrentIndex(index); - jump(index); - } -} - -void Player::durationChanged(qint64 duration) -{ - m_duration = duration / 1000; - m_slider->setMaximum(duration); -} - -void Player::positionChanged(qint64 progress) -{ - if (!m_slider->isSliderDown()) - m_slider->setValue(progress); - - updateDurationInfo(progress / 1000); -} - -void Player::metaDataChanged() -{ - auto metaData = m_player->metaData(); - setTrackInfo(QString("%1 - %2") - .arg(metaData.value(QMediaMetaData::AlbumArtist).toString()) - .arg(metaData.value(QMediaMetaData::Title).toString())); - -#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) - for (int i = 0; i < QMediaMetaData::NumMetaData; i++) { - if (QLineEdit* field = qobject_cast<QLineEdit*>(m_metaDataFields[i])) - field->clear(); - else if (QLabel* label = qobject_cast<QLabel*>(m_metaDataFields[i])) - label->clear(); - m_metaDataFields[i]->setDisabled(true); - m_metaDataLabels[i]->setDisabled(true); - } - - for (auto &key : metaData.keys()) { - int i = int(key); - if (key == QMediaMetaData::CoverArtImage) { - QVariant v = metaData.value(key); - if (QLabel *cover = qobject_cast<QLabel*>(m_metaDataFields[key])) { - QImage coverImage = v.value<QImage>(); - cover->setPixmap(QPixmap::fromImage(coverImage)); - } - } else if (key == QMediaMetaData::ThumbnailImage) { - QVariant v = metaData.value(key); - if (QLabel *thumbnail = qobject_cast<QLabel*>(m_metaDataFields[key])) { - QImage thumbnailImage = v.value<QImage>(); - thumbnail->setPixmap(QPixmap::fromImage(thumbnailImage)); - } - } else if (QLineEdit *field = qobject_cast<QLineEdit*>(m_metaDataFields[key])) { - QString stringValue = metaData.stringValue(key); - field->setText(stringValue); - } - m_metaDataFields[i]->setDisabled(false); - m_metaDataLabels[i]->setDisabled(false); - } -#endif -} - -QString Player::trackName(const QMediaMetaData &metaData, int index) -{ - QString name; - QString title = metaData.stringValue(QMediaMetaData::Title); - QLocale::Language lang = metaData.value(QMediaMetaData::Language).value<QLocale::Language>(); - - if (title.isEmpty()) { - if (lang == QLocale::Language::AnyLanguage) - name = tr("Track %1").arg(index+1); - else - name = QLocale::languageToString(lang); - } else { - if (lang == QLocale::Language::AnyLanguage) - name = title; - else - name = QString("%1 - [%2]").arg(title).arg(QLocale::languageToString(lang)); - } - return name; -} - -void Player::tracksChanged() -{ - m_audioTracks->clear(); - m_videoTracks->clear(); - m_subtitleTracks->clear(); - - const auto audioTracks = m_player->audioTracks(); - m_audioTracks->addItem(QString::fromUtf8("No audio"), -1); - for (int i = 0; i < audioTracks.size(); ++i) - m_audioTracks->addItem(trackName(audioTracks.at(i), i), i); - m_audioTracks->setCurrentIndex(m_player->activeAudioTrack() + 1); - - const auto videoTracks = m_player->videoTracks(); - m_videoTracks->addItem(QString::fromUtf8("No video"), -1); - for (int i = 0; i < videoTracks.size(); ++i) - m_videoTracks->addItem(trackName(videoTracks.at(i), i), i); - m_videoTracks->setCurrentIndex(m_player->activeVideoTrack() + 1); - - m_subtitleTracks->addItem(QString::fromUtf8("No subtitles"), -1); - const auto subtitleTracks = m_player->subtitleTracks(); - for (int i = 0; i < subtitleTracks.size(); ++i) - m_subtitleTracks->addItem(trackName(subtitleTracks.at(i), i), i); - m_subtitleTracks->setCurrentIndex(m_player->activeSubtitleTrack() + 1); -} - -void Player::previousClicked() -{ - // Go to previous track if we are within the first 5 seconds of playback - // Otherwise, seek to the beginning. - if (m_player->position() <= 5000) { - m_playlist->previous(); - } else { - m_player->setPosition(0); - } -} - -void Player::jump(const QModelIndex &index) -{ - if (index.isValid()) { - m_playlist->setCurrentIndex(index.row()); - } -} - -void Player::playlistPositionChanged(int currentItem) -{ - if (m_playlistView) - m_playlistView->setCurrentIndex(m_playlistModel->index(currentItem, 0)); - m_player->setSource(m_playlist->currentMedia()); -} - -void Player::seek(int mseconds) -{ - m_player->setPosition(mseconds); -} - -void Player::statusChanged(QMediaPlayer::MediaStatus status) -{ - handleCursor(status); - - // handle status message - switch (status) { - case QMediaPlayer::NoMedia: - case QMediaPlayer::LoadedMedia: - setStatusInfo(QString()); - break; - case QMediaPlayer::LoadingMedia: - setStatusInfo(tr("Loading...")); - break; - case QMediaPlayer::BufferingMedia: - case QMediaPlayer::BufferedMedia: - setStatusInfo(tr("Buffering %1%").arg(qRound(m_player->bufferProgress()*100.))); - break; - case QMediaPlayer::StalledMedia: - setStatusInfo(tr("Stalled %1%").arg(qRound(m_player->bufferProgress()*100.))); - break; - case QMediaPlayer::EndOfMedia: - QApplication::alert(this); - m_playlist->next(); - break; - case QMediaPlayer::InvalidMedia: - displayErrorMessage(); - break; - } -} - -void Player::handleCursor(QMediaPlayer::MediaStatus status) -{ -#ifndef QT_NO_CURSOR - if (status == QMediaPlayer::LoadingMedia || - status == QMediaPlayer::BufferingMedia || - status == QMediaPlayer::StalledMedia) - setCursor(QCursor(Qt::BusyCursor)); - else - unsetCursor(); -#endif -} - -void Player::bufferingProgress(float progress) -{ - if (m_player->mediaStatus() == QMediaPlayer::StalledMedia) - setStatusInfo(tr("Stalled %1%").arg(qRound(progress*100.))); - else - setStatusInfo(tr("Buffering %1%").arg(qRound(progress*100.))); -} - -void Player::videoAvailableChanged(bool available) -{ - if (!available) { - disconnect(m_fullScreenButton, &QPushButton::clicked, m_videoWidget, &QVideoWidget::setFullScreen); - disconnect(m_videoWidget, &QVideoWidget::fullScreenChanged, m_fullScreenButton, &QPushButton::setChecked); - m_videoWidget->setFullScreen(false); - } else { - connect(m_fullScreenButton, &QPushButton::clicked, m_videoWidget, &QVideoWidget::setFullScreen); - connect(m_videoWidget, &QVideoWidget::fullScreenChanged, m_fullScreenButton, &QPushButton::setChecked); - - if (m_fullScreenButton->isChecked()) - m_videoWidget->setFullScreen(true); - } -} - -void Player::selectAudioStream() -{ - int stream = m_audioTracks->currentData().toInt(); - m_player->setActiveAudioTrack(stream); -} - -void Player::selectVideoStream() -{ - int stream = m_videoTracks->currentData().toInt(); - m_player->setActiveVideoTrack(stream); -} - -void Player::selectSubtitleStream() -{ - int stream = m_subtitleTracks->currentData().toInt(); - m_player->setActiveSubtitleTrack(stream); -} - -void Player::setTrackInfo(const QString &info) -{ - m_trackInfo = info; - - if (m_statusBar) { - m_statusBar->showMessage(m_trackInfo); - m_statusLabel->setText(m_statusInfo); - } else { - if (!m_statusInfo.isEmpty()) - setWindowTitle(QString("%1 | %2").arg(m_trackInfo).arg(m_statusInfo)); - else - setWindowTitle(m_trackInfo); - } -} - -void Player::setStatusInfo(const QString &info) -{ - m_statusInfo = info; - - if (m_statusBar) { - m_statusBar->showMessage(m_trackInfo); - m_statusLabel->setText(m_statusInfo); - } else { - if (!m_statusInfo.isEmpty()) - setWindowTitle(QString("%1 | %2").arg(m_trackInfo).arg(m_statusInfo)); - else - setWindowTitle(m_trackInfo); - } -} - -void Player::displayErrorMessage() -{ - if (m_player->error() == QMediaPlayer::NoError) - return; - setStatusInfo(m_player->errorString()); -} - -void Player::updateDurationInfo(qint64 currentInfo) -{ - QString tStr; - if (currentInfo || m_duration) { - QTime currentTime((currentInfo / 3600) % 60, (currentInfo / 60) % 60, - currentInfo % 60, (currentInfo * 1000) % 1000); - QTime totalTime((m_duration / 3600) % 60, (m_duration / 60) % 60, - m_duration % 60, (m_duration * 1000) % 1000); - QString format = "mm:ss"; - if (m_duration > 3600) - format = "hh:mm:ss"; - tStr = currentTime.toString(format) + " / " + totalTime.toString(format); - } - m_labelDuration->setText(tStr); -} - -void Player::audioOutputChanged(int index) -{ - auto device = m_audioOutputCombo->itemData(index).value<QAudioDevice>(); - m_player->audioOutput()->setDevice(device); -} diff --git a/examples/multimediawidgets/player/player.h b/examples/multimediawidgets/player/player.h deleted file mode 100644 index 3f1c51795..000000000 --- a/examples/multimediawidgets/player/player.h +++ /dev/null @@ -1,146 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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$ -** -****************************************************************************/ - -#ifndef PLAYER_H -#define PLAYER_H - -#include "qmediaplaylist.h" - -#include <QWidget> -#include <QMediaPlayer> -#include <QMediaMetaData> - -QT_BEGIN_NAMESPACE -class QAbstractItemView; -class QLabel; -class QMediaPlayer; -class QModelIndex; -class QPushButton; -class QComboBox; -class QSlider; -class QStatusBar; -class QVideoWidget; -QT_END_NAMESPACE - -class PlaylistModel; - -class Player : public QWidget -{ - Q_OBJECT - -public: - explicit Player(QWidget *parent = nullptr); - ~Player() = default; - - bool isPlayerAvailable() const; - - void addToPlaylist(const QList<QUrl> &urls); - -signals: - void fullScreenChanged(bool fullScreen); - -private slots: - void open(); - void durationChanged(qint64 duration); - void positionChanged(qint64 progress); - void metaDataChanged(); - void tracksChanged(); - - void previousClicked(); - - void seek(int mseconds); - void jump(const QModelIndex &index); - void playlistPositionChanged(int); - - void statusChanged(QMediaPlayer::MediaStatus status); - void bufferingProgress(float progress); - void videoAvailableChanged(bool available); - - void selectAudioStream(); - void selectVideoStream(); - void selectSubtitleStream(); - - void displayErrorMessage(); - - void audioOutputChanged(int); - -private: - void setTrackInfo(const QString &info); - void setStatusInfo(const QString &info); - void handleCursor(QMediaPlayer::MediaStatus status); - void updateDurationInfo(qint64 currentInfo); - QString trackName(const QMediaMetaData &metaData, int index); - - QMediaPlayer *m_player = nullptr; - QAudioOutput *m_audioOutput = nullptr; - QMediaPlaylist *m_playlist = nullptr; - QVideoWidget *m_videoWidget = nullptr; - QSlider *m_slider = nullptr; - QLabel *m_labelDuration = nullptr; - QPushButton *m_fullScreenButton = nullptr; - QComboBox *m_audioOutputCombo = nullptr; - QLabel *m_statusLabel = nullptr; - QStatusBar *m_statusBar = nullptr; - - QComboBox *m_audioTracks = nullptr; - QComboBox *m_videoTracks = nullptr; - QComboBox *m_subtitleTracks = nullptr; - - PlaylistModel *m_playlistModel = nullptr; - QAbstractItemView *m_playlistView = nullptr; - QString m_trackInfo; - QString m_statusInfo; - qint64 m_duration; - - QWidget *m_metaDataFields[QMediaMetaData::NumMetaData] = {}; - QLabel *m_metaDataLabels[QMediaMetaData::NumMetaData] = {}; -}; - -#endif // PLAYER_H diff --git a/examples/multimediawidgets/player/player.pro b/examples/multimediawidgets/player/player.pro deleted file mode 100644 index 950fe8e0d..000000000 --- a/examples/multimediawidgets/player/player.pro +++ /dev/null @@ -1,27 +0,0 @@ -TEMPLATE = app -TARGET = player - -QT += network \ - multimedia \ - multimediawidgets \ - widgets - -HEADERS = \ - player.h \ - playercontrols.h \ - playlistmodel.h \ - videowidget.h \ - qmediaplaylist.h \ - qmediaplaylist_p.h \ - qplaylistfileparser_p.h - -SOURCES = main.cpp \ - player.cpp \ - playercontrols.cpp \ - playlistmodel.cpp \ - videowidget.cpp \ - qmediaplaylist.cpp \ - qplaylistfileparser.cpp - -target.path = $$[QT_INSTALL_EXAMPLES]/multimediawidgets/player -INSTALLS += target diff --git a/examples/multimediawidgets/player/playercontrols.cpp b/examples/multimediawidgets/player/playercontrols.cpp deleted file mode 100644 index 73cf9ae21..000000000 --- a/examples/multimediawidgets/player/playercontrols.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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 "playercontrols.h" - -#include <QBoxLayout> -#include <QSlider> -#include <QStyle> -#include <QToolButton> -#include <QComboBox> -#include <QAudio> - -PlayerControls::PlayerControls(QWidget *parent) - : QWidget(parent) -{ - m_playButton = new QToolButton(this); - m_playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay)); - - connect(m_playButton, &QAbstractButton::clicked, this, &PlayerControls::playClicked); - - m_stopButton = new QToolButton(this); - m_stopButton->setIcon(style()->standardIcon(QStyle::SP_MediaStop)); - m_stopButton->setEnabled(false); - - connect(m_stopButton, &QAbstractButton::clicked, this, &PlayerControls::stop); - - m_nextButton = new QToolButton(this); - m_nextButton->setIcon(style()->standardIcon(QStyle::SP_MediaSkipForward)); - - connect(m_nextButton, &QAbstractButton::clicked, this, &PlayerControls::next); - - m_previousButton = new QToolButton(this); - m_previousButton->setIcon(style()->standardIcon(QStyle::SP_MediaSkipBackward)); - - connect(m_previousButton, &QAbstractButton::clicked, this, &PlayerControls::previous); - - m_muteButton = new QToolButton(this); - m_muteButton->setIcon(style()->standardIcon(QStyle::SP_MediaVolume)); - - connect(m_muteButton, &QAbstractButton::clicked, this, &PlayerControls::muteClicked); - - m_volumeSlider = new QSlider(Qt::Horizontal, this); - m_volumeSlider->setRange(0, 100); - - connect(m_volumeSlider, &QSlider::valueChanged, this, &PlayerControls::onVolumeSliderValueChanged); - - m_rateBox = new QComboBox(this); - m_rateBox->addItem("0.5x", QVariant(0.5)); - m_rateBox->addItem("1.0x", QVariant(1.0)); - m_rateBox->addItem("2.0x", QVariant(2.0)); - m_rateBox->setCurrentIndex(1); - - connect(m_rateBox, QOverload<int>::of(&QComboBox::activated), this, &PlayerControls::updateRate); - - QBoxLayout *layout = new QHBoxLayout; - layout->setContentsMargins(0, 0, 0, 0); - layout->addWidget(m_stopButton); - layout->addWidget(m_previousButton); - layout->addWidget(m_playButton); - layout->addWidget(m_nextButton); - layout->addWidget(m_muteButton); - layout->addWidget(m_volumeSlider); - layout->addWidget(m_rateBox); - setLayout(layout); -} - -QMediaPlayer::PlaybackState PlayerControls::state() const -{ - return m_playerState; -} - -void PlayerControls::setState(QMediaPlayer::PlaybackState state) -{ - if (state != m_playerState) { - m_playerState = state; - - switch (state) { - case QMediaPlayer::StoppedState: - m_stopButton->setEnabled(false); - m_playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay)); - break; - case QMediaPlayer::PlayingState: - m_stopButton->setEnabled(true); - m_playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPause)); - break; - case QMediaPlayer::PausedState: - m_stopButton->setEnabled(true); - m_playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay)); - break; - } - } -} - -float PlayerControls::volume() const -{ - qreal linearVolume = QAudio::convertVolume(m_volumeSlider->value() / qreal(100), - QAudio::LogarithmicVolumeScale, - QAudio::LinearVolumeScale); - - return linearVolume; -} - -void PlayerControls::setVolume(float volume) -{ - qreal logarithmicVolume = QAudio::convertVolume(volume, - QAudio::LinearVolumeScale, - QAudio::LogarithmicVolumeScale); - - m_volumeSlider->setValue(qRound(logarithmicVolume * 100)); -} - -bool PlayerControls::isMuted() const -{ - return m_playerMuted; -} - -void PlayerControls::setMuted(bool muted) -{ - if (muted != m_playerMuted) { - m_playerMuted = muted; - - m_muteButton->setIcon(style()->standardIcon(muted - ? QStyle::SP_MediaVolumeMuted - : QStyle::SP_MediaVolume)); - } -} - -void PlayerControls::playClicked() -{ - switch (m_playerState) { - case QMediaPlayer::StoppedState: - case QMediaPlayer::PausedState: - emit play(); - break; - case QMediaPlayer::PlayingState: - emit pause(); - break; - } -} - -void PlayerControls::muteClicked() -{ - emit changeMuting(!m_playerMuted); -} - -qreal PlayerControls::playbackRate() const -{ - return m_rateBox->itemData(m_rateBox->currentIndex()).toDouble(); -} - -void PlayerControls::setPlaybackRate(float rate) -{ - for (int i = 0; i < m_rateBox->count(); ++i) { - if (qFuzzyCompare(rate, float(m_rateBox->itemData(i).toDouble()))) { - m_rateBox->setCurrentIndex(i); - return; - } - } - - m_rateBox->addItem(QString("%1x").arg(rate), QVariant(rate)); - m_rateBox->setCurrentIndex(m_rateBox->count() - 1); -} - -void PlayerControls::updateRate() -{ - emit changeRate(playbackRate()); -} - -void PlayerControls::onVolumeSliderValueChanged() -{ - emit changeVolume(volume()); -} diff --git a/examples/multimediawidgets/player/playercontrols.h b/examples/multimediawidgets/player/playercontrols.h deleted file mode 100644 index 927f72608..000000000 --- a/examples/multimediawidgets/player/playercontrols.h +++ /dev/null @@ -1,109 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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$ -** -****************************************************************************/ - -#ifndef PLAYERCONTROLS_H -#define PLAYERCONTROLS_H - -#include <QMediaPlayer> -#include <QWidget> - -QT_BEGIN_NAMESPACE -class QAbstractButton; -class QAbstractSlider; -class QComboBox; -QT_END_NAMESPACE - -class PlayerControls : public QWidget -{ - Q_OBJECT - -public: - explicit PlayerControls(QWidget *parent = nullptr); - - QMediaPlayer::PlaybackState state() const; - float volume() const; - bool isMuted() const; - qreal playbackRate() const; - -public slots: - void setState(QMediaPlayer::PlaybackState state); - void setVolume(float volume); - void setMuted(bool muted); - void setPlaybackRate(float rate); - -signals: - void play(); - void pause(); - void stop(); - void next(); - void previous(); - void changeVolume(float volume); - void changeMuting(bool muting); - void changeRate(qreal rate); - -private slots: - void playClicked(); - void muteClicked(); - void updateRate(); - void onVolumeSliderValueChanged(); - -private: - QMediaPlayer::PlaybackState m_playerState = QMediaPlayer::StoppedState; - bool m_playerMuted = false; - QAbstractButton *m_playButton = nullptr; - QAbstractButton *m_stopButton = nullptr; - QAbstractButton *m_nextButton = nullptr; - QAbstractButton *m_previousButton = nullptr; - QAbstractButton *m_muteButton = nullptr; - QAbstractSlider *m_volumeSlider = nullptr; - QComboBox *m_rateBox = nullptr; -}; - -#endif // PLAYERCONTROLS_H diff --git a/examples/multimediawidgets/player/playlistmodel.cpp b/examples/multimediawidgets/player/playlistmodel.cpp deleted file mode 100644 index 28fc58a83..000000000 --- a/examples/multimediawidgets/player/playlistmodel.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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 "playlistmodel.h" -#include "qmediaplaylist.h" - -#include <QFileInfo> -#include <QUrl> - -PlaylistModel::PlaylistModel(QObject *parent) - : QAbstractItemModel(parent) -{ - m_playlist.reset(new QMediaPlaylist); - connect(m_playlist.data(), &QMediaPlaylist::mediaAboutToBeInserted, this, &PlaylistModel::beginInsertItems); - connect(m_playlist.data(), &QMediaPlaylist::mediaInserted, this, &PlaylistModel::endInsertItems); - connect(m_playlist.data(), &QMediaPlaylist::mediaAboutToBeRemoved, this, &PlaylistModel::beginRemoveItems); - connect(m_playlist.data(), &QMediaPlaylist::mediaRemoved, this, &PlaylistModel::endRemoveItems); - connect(m_playlist.data(), &QMediaPlaylist::mediaChanged, this, &PlaylistModel::changeItems); -} - -PlaylistModel::~PlaylistModel() = default; - -int PlaylistModel::rowCount(const QModelIndex &parent) const -{ - return m_playlist && !parent.isValid() ? m_playlist->mediaCount() : 0; -} - -int PlaylistModel::columnCount(const QModelIndex &parent) const -{ - return !parent.isValid() ? ColumnCount : 0; -} - -QModelIndex PlaylistModel::index(int row, int column, const QModelIndex &parent) const -{ - return m_playlist && !parent.isValid() - && row >= 0 && row < m_playlist->mediaCount() - && column >= 0 && column < ColumnCount - ? createIndex(row, column) - : QModelIndex(); -} - -QModelIndex PlaylistModel::parent(const QModelIndex &child) const -{ - Q_UNUSED(child); - - return QModelIndex(); -} - -QVariant PlaylistModel::data(const QModelIndex &index, int role) const -{ - if (index.isValid() && role == Qt::DisplayRole) { - QVariant value = m_data[index]; - if (!value.isValid() && index.column() == Title) { - QUrl location = m_playlist->media(index.row()); - return QFileInfo(location.path()).fileName(); - } - - return value; - } - return QVariant(); -} - -QMediaPlaylist *PlaylistModel::playlist() const -{ - return m_playlist.data(); -} - -bool PlaylistModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - Q_UNUSED(role); - m_data[index] = value; - emit dataChanged(index, index); - return true; -} - -void PlaylistModel::beginInsertItems(int start, int end) -{ - m_data.clear(); - beginInsertRows(QModelIndex(), start, end); -} - -void PlaylistModel::endInsertItems() -{ - endInsertRows(); -} - -void PlaylistModel::beginRemoveItems(int start, int end) -{ - m_data.clear(); - beginRemoveRows(QModelIndex(), start, end); -} - -void PlaylistModel::endRemoveItems() -{ - endInsertRows(); -} - -void PlaylistModel::changeItems(int start, int end) -{ - m_data.clear(); - emit dataChanged(index(start,0), index(end,ColumnCount)); -} diff --git a/examples/multimediawidgets/player/playlistmodel.h b/examples/multimediawidgets/player/playlistmodel.h deleted file mode 100644 index c2bc8319a..000000000 --- a/examples/multimediawidgets/player/playlistmodel.h +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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$ -** -****************************************************************************/ - -#ifndef PLAYLISTMODEL_H -#define PLAYLISTMODEL_H - -#include <QAbstractItemModel> -#include <QScopedPointer> - -QT_BEGIN_NAMESPACE -class QMediaPlaylist; -QT_END_NAMESPACE - -class PlaylistModel : public QAbstractItemModel -{ - Q_OBJECT - -public: - enum Column - { - Title = 0, - ColumnCount - }; - - explicit PlaylistModel(QObject *parent = nullptr); - ~PlaylistModel(); - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; - QModelIndex parent(const QModelIndex &child) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - - QMediaPlaylist *playlist() const; - - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole) override; - -private slots: - void beginInsertItems(int start, int end); - void endInsertItems(); - void beginRemoveItems(int start, int end); - void endRemoveItems(); - void changeItems(int start, int end); - -private: - QScopedPointer<QMediaPlaylist> m_playlist; - QMap<QModelIndex, QVariant> m_data; -}; - -#endif // PLAYLISTMODEL_H diff --git a/examples/multimediawidgets/player/qmediaplaylist.cpp b/examples/multimediawidgets/player/qmediaplaylist.cpp deleted file mode 100644 index d2fbe3753..000000000 --- a/examples/multimediawidgets/player/qmediaplaylist.cpp +++ /dev/null @@ -1,689 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qmediaplaylist.h" -#include "qmediaplaylist_p.h" -#include "qplaylistfileparser_p.h" - -#include <QtCore/qlist.h> -#include <QtCore/qfile.h> -#include <QtCore/qurl.h> -#include <QtCore/qcoreevent.h> -#include <QtCore/qcoreapplication.h> -#include <QRandomGenerator> - -QT_BEGIN_NAMESPACE - -class QM3uPlaylistWriter -{ -public: - QM3uPlaylistWriter(QIODevice *device) - :m_device(device), m_textStream(new QTextStream(m_device)) - { - } - - ~QM3uPlaylistWriter() - { - delete m_textStream; - } - - bool writeItem(const QUrl& item) - { - *m_textStream << item.toString() << Qt::endl; - return true; - } - -private: - QIODevice *m_device; - QTextStream *m_textStream; -}; - - -int QMediaPlaylistPrivate::nextPosition(int steps) const -{ - if (playlist.count() == 0) - return -1; - - int next = currentPos + steps; - - switch (playbackMode) { - case QMediaPlaylist::CurrentItemOnce: - return steps != 0 ? -1 : currentPos; - case QMediaPlaylist::CurrentItemInLoop: - return currentPos; - case QMediaPlaylist::Sequential: - if (next >= playlist.size()) - next = -1; - break; - case QMediaPlaylist::Loop: - next %= playlist.count(); - break; - } - - return next; -} - -int QMediaPlaylistPrivate::prevPosition(int steps) const -{ - if (playlist.count() == 0) - return -1; - - int next = currentPos; - if (next < 0) - next = playlist.size(); - next -= steps; - - switch (playbackMode) { - case QMediaPlaylist::CurrentItemOnce: - return steps != 0 ? -1 : currentPos; - case QMediaPlaylist::CurrentItemInLoop: - return currentPos; - case QMediaPlaylist::Sequential: - if (next < 0) - next = -1; - break; - case QMediaPlaylist::Loop: - next %= playlist.size(); - if (next < 0) - next += playlist.size(); - break; - } - - return next; -} - -/*! - \class QMediaPlaylist - \inmodule QtMultimedia - \ingroup multimedia - \ingroup multimedia_playback - - - \brief The QMediaPlaylist class provides a list of media content to play. - - QMediaPlaylist is intended to be used with other media objects, - like QMediaPlayer. - - QMediaPlaylist allows to access the service intrinsic playlist functionality - if available, otherwise it provides the local memory playlist implementation. - - \snippet multimedia-snippets/media.cpp Movie playlist - - Depending on playlist source implementation, most of the playlist mutating - operations can be asynchronous. - - QMediaPlayList currently supports M3U playlists (file extension .m3u and .m3u8). - - \sa QUrl -*/ - - -/*! - \enum QMediaPlaylist::PlaybackMode - - The QMediaPlaylist::PlaybackMode describes the order items in playlist are played. - - \value CurrentItemOnce The current item is played only once. - - \value CurrentItemInLoop The current item is played repeatedly in a loop. - - \value Sequential Playback starts from the current and moves through each successive item until the last is reached and then stops. - The next item is a null item when the last one is currently playing. - - \value Loop Playback restarts at the first item after the last has finished playing. - - \value Random Play items in random order. -*/ - - - -/*! - Create a new playlist object with the given \a parent. -*/ - -QMediaPlaylist::QMediaPlaylist(QObject *parent) - : QObject(parent) - , d_ptr(new QMediaPlaylistPrivate) -{ - Q_D(QMediaPlaylist); - - d->q_ptr = this; -} - -/*! - Destroys the playlist. - */ - -QMediaPlaylist::~QMediaPlaylist() -{ - delete d_ptr; -} - -/*! - \property QMediaPlaylist::playbackMode - - This property defines the order that items in the playlist are played. - - \sa QMediaPlaylist::PlaybackMode -*/ - -QMediaPlaylist::PlaybackMode QMediaPlaylist::playbackMode() const -{ - return d_func()->playbackMode; -} - -void QMediaPlaylist::setPlaybackMode(QMediaPlaylist::PlaybackMode mode) -{ - Q_D(QMediaPlaylist); - - if (mode == d->playbackMode) - return; - - d->playbackMode = mode; - - emit playbackModeChanged(mode); -} - -/*! - Returns position of the current media content in the playlist. -*/ -int QMediaPlaylist::currentIndex() const -{ - return d_func()->currentPos; -} - -/*! - Returns the current media content. -*/ - -QUrl QMediaPlaylist::currentMedia() const -{ - Q_D(const QMediaPlaylist); - if (d->currentPos < 0 || d->currentPos >= d->playlist.size()) - return QUrl(); - return d_func()->playlist.at(d_func()->currentPos); -} - -/*! - Returns the index of the item, which would be current after calling next() - \a steps times. - - Returned value depends on the size of playlist, current position - and playback mode. - - \sa QMediaPlaylist::playbackMode(), previousIndex() -*/ -int QMediaPlaylist::nextIndex(int steps) const -{ - return d_func()->nextPosition(steps); -} - -/*! - Returns the index of the item, which would be current after calling previous() - \a steps times. - - \sa QMediaPlaylist::playbackMode(), nextIndex() -*/ - -int QMediaPlaylist::previousIndex(int steps) const -{ - return d_func()->prevPosition(steps); -} - - -/*! - Returns the number of items in the playlist. - - \sa isEmpty() - */ -int QMediaPlaylist::mediaCount() const -{ - return d_func()->playlist.count(); -} - -/*! - Returns true if the playlist contains no items, otherwise returns false. - - \sa mediaCount() - */ -bool QMediaPlaylist::isEmpty() const -{ - return mediaCount() == 0; -} - -/*! - Returns the media content at \a index in the playlist. -*/ - -QUrl QMediaPlaylist::media(int index) const -{ - Q_D(const QMediaPlaylist); - if (index < 0 || index >= d->playlist.size()) - return QUrl(); - return d->playlist.at(index); -} - -/*! - Append the media \a content to the playlist. - - Returns true if the operation is successful, otherwise returns false. - */ -void QMediaPlaylist::addMedia(const QUrl &content) -{ - Q_D(QMediaPlaylist); - int pos = d->playlist.size(); - emit mediaAboutToBeInserted(pos, pos); - d->playlist.append(content); - emit mediaInserted(pos, pos); -} - -/*! - Append multiple media content \a items to the playlist. - - Returns true if the operation is successful, otherwise returns false. - */ -void QMediaPlaylist::addMedia(const QList<QUrl> &items) -{ - if (!items.size()) - return; - - Q_D(QMediaPlaylist); - int first = d->playlist.size(); - int last = first + items.size() - 1; - emit mediaAboutToBeInserted(first, last); - d_func()->playlist.append(items); - emit mediaInserted(first, last); -} - -/*! - Insert the media \a content to the playlist at position \a pos. - - Returns true if the operation is successful, otherwise returns false. -*/ - -bool QMediaPlaylist::insertMedia(int pos, const QUrl &content) -{ - Q_D(QMediaPlaylist); - pos = qBound(0, pos, d->playlist.size()); - emit mediaAboutToBeInserted(pos, pos); - d->playlist.insert(pos, content); - emit mediaInserted(pos, pos); - return true; -} - -/*! - Insert multiple media content \a items to the playlist at position \a pos. - - Returns true if the operation is successful, otherwise returns false. -*/ - -bool QMediaPlaylist::insertMedia(int pos, const QList<QUrl> &items) -{ - if (!items.size()) - return true; - - Q_D(QMediaPlaylist); - pos = qBound(0, pos, d->playlist.size()); - int last = pos + items.size() - 1; - emit mediaAboutToBeInserted(pos, last); - auto newList = d->playlist.mid(0, pos); - newList += items; - newList += d->playlist.mid(pos); - d->playlist = newList; - emit mediaInserted(pos, last); - return true; -} - -/*! - Move the item from position \a from to position \a to. - - Returns true if the operation is successful, otherwise false. - - \since 5.7 -*/ -bool QMediaPlaylist::moveMedia(int from, int to) -{ - Q_D(QMediaPlaylist); - if (from < 0 || from > d->playlist.count() || - to < 0 || to > d->playlist.count()) - return false; - - d->playlist.move(from, to); - emit mediaChanged(from, to); - return true; -} - -/*! - Remove the item from the playlist at position \a pos. - - Returns true if the operation is successful, otherwise return false. - */ -bool QMediaPlaylist::removeMedia(int pos) -{ - return removeMedia(pos, pos); -} - -/*! - Remove items in the playlist from \a start to \a end inclusive. - - Returns true if the operation is successful, otherwise return false. - */ -bool QMediaPlaylist::removeMedia(int start, int end) -{ - Q_D(QMediaPlaylist); - if (end < start || end < 0 || start >= d->playlist.count()) - return false; - start = qBound(0, start, d->playlist.size() - 1); - end = qBound(0, end, d->playlist.size() - 1); - - emit mediaAboutToBeRemoved(start, end); - d->playlist.remove(start, end - start + 1); - emit mediaRemoved(start, end); - return true; -} - -/*! - Remove all the items from the playlist. - - Returns true if the operation is successful, otherwise return false. - */ -void QMediaPlaylist::clear() -{ - Q_D(QMediaPlaylist); - int size = d->playlist.size(); - emit mediaAboutToBeRemoved(0, size - 1); - d->playlist.clear(); - emit mediaRemoved(0, size - 1); -} - -/*! - Load playlist from \a location. If \a format is specified, it is used, - otherwise format is guessed from location name and data. - - New items are appended to playlist. - - QMediaPlaylist::loaded() signal is emitted if playlist was loaded successfully, - otherwise the playlist emits loadFailed(). -*/ - -void QMediaPlaylist::load(const QUrl &location, const char *format) -{ - Q_D(QMediaPlaylist); - - d->error = NoError; - d->errorString.clear(); - - d->ensureParser(); - d->parser->start(location, QString::fromUtf8(format)); -} - -/*! - Load playlist from QIODevice \a device. If \a format is specified, it is used, - otherwise format is guessed from device data. - - New items are appended to playlist. - - QMediaPlaylist::loaded() signal is emitted if playlist was loaded successfully, - otherwise the playlist emits loadFailed(). -*/ -void QMediaPlaylist::load(QIODevice *device, const char *format) -{ - Q_D(QMediaPlaylist); - - d->error = NoError; - d->errorString.clear(); - - d->ensureParser(); - d->parser->start(device, QString::fromUtf8(format)); -} - -/*! - Save playlist to \a location. If \a format is specified, it is used, - otherwise format is guessed from location name. - - Returns true if playlist was saved successfully, otherwise returns false. - */ -bool QMediaPlaylist::save(const QUrl &location, const char *format) const -{ - Q_D(const QMediaPlaylist); - - d->error = NoError; - d->errorString.clear(); - - if (!d->checkFormat(format)) - return false; - - QFile file(location.toLocalFile()); - - if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { - d->error = AccessDeniedError; - d->errorString = tr("The file could not be accessed."); - return false; - } - - return save(&file, format); -} - -/*! - Save playlist to QIODevice \a device using format \a format. - - Returns true if playlist was saved successfully, otherwise returns false. -*/ -bool QMediaPlaylist::save(QIODevice *device, const char *format) const -{ - Q_D(const QMediaPlaylist); - - d->error = NoError; - d->errorString.clear(); - - if (!d->checkFormat(format)) - return false; - - QM3uPlaylistWriter writer(device); - for (const auto &entry : d->playlist) - writer.writeItem(entry); - return true; -} - -/*! - Returns the last error condition. -*/ -QMediaPlaylist::Error QMediaPlaylist::error() const -{ - return d_func()->error; -} - -/*! - Returns the string describing the last error condition. -*/ -QString QMediaPlaylist::errorString() const -{ - return d_func()->errorString; -} - -/*! - Shuffle items in the playlist. -*/ -void QMediaPlaylist::shuffle() -{ - Q_D(QMediaPlaylist); - QList<QUrl> playlist; - - // keep the current item when shuffling - QUrl current; - if (d->currentPos != -1) - current = d->playlist.takeAt(d->currentPos); - - while (!d->playlist.isEmpty()) - playlist.append(d->playlist.takeAt(QRandomGenerator::global()->bounded(int(d->playlist.size())))); - - if (d->currentPos != -1) - playlist.insert(d->currentPos, current); - d->playlist = playlist; - emit mediaChanged(0, d->playlist.count()); -} - - -/*! - Advance to the next media content in playlist. -*/ -void QMediaPlaylist::next() -{ - Q_D(QMediaPlaylist); - d->currentPos = d->nextPosition(1); - - emit currentIndexChanged(d->currentPos); - emit currentMediaChanged(currentMedia()); -} - -/*! - Return to the previous media content in playlist. -*/ -void QMediaPlaylist::previous() -{ - Q_D(QMediaPlaylist); - d->currentPos = d->prevPosition(1); - - emit currentIndexChanged(d->currentPos); - emit currentMediaChanged(currentMedia()); -} - -/*! - Activate media content from playlist at position \a playlistPosition. -*/ - -void QMediaPlaylist::setCurrentIndex(int playlistPosition) -{ - Q_D(QMediaPlaylist); - if (playlistPosition < 0 || playlistPosition >= d->playlist.size()) - playlistPosition = -1; - d->currentPos = playlistPosition; - - emit currentIndexChanged(d->currentPos); - emit currentMediaChanged(currentMedia()); -} - -/*! - \fn void QMediaPlaylist::mediaInserted(int start, int end) - - This signal is emitted after media has been inserted into the playlist. - The new items are those between \a start and \a end inclusive. - */ - -/*! - \fn void QMediaPlaylist::mediaRemoved(int start, int end) - - This signal is emitted after media has been removed from the playlist. - The removed items are those between \a start and \a end inclusive. - */ - -/*! - \fn void QMediaPlaylist::mediaChanged(int start, int end) - - This signal is emitted after media has been changed in the playlist - between \a start and \a end positions inclusive. - */ - -/*! - \fn void QMediaPlaylist::currentIndexChanged(int position) - - Signal emitted when playlist position changed to \a position. -*/ - -/*! - \fn void QMediaPlaylist::playbackModeChanged(QMediaPlaylist::PlaybackMode mode) - - Signal emitted when playback mode changed to \a mode. -*/ - -/*! - \fn void QMediaPlaylist::mediaAboutToBeInserted(int start, int end) - - Signal emitted when items are to be inserted at \a start and ending at \a end. -*/ - -/*! - \fn void QMediaPlaylist::mediaAboutToBeRemoved(int start, int end) - - Signal emitted when item are to be deleted at \a start and ending at \a end. -*/ - -/*! - \fn void QMediaPlaylist::currentMediaChanged(const QUrl &content) - - Signal emitted when current media changes to \a content. -*/ - -/*! - \property QMediaPlaylist::currentIndex - \brief Current position. -*/ - -/*! - \property QMediaPlaylist::currentMedia - \brief Current media content. -*/ - -/*! - \fn QMediaPlaylist::loaded() - - Signal emitted when playlist finished loading. -*/ - -/*! - \fn QMediaPlaylist::loadFailed() - - Signal emitted if failed to load playlist. -*/ - -/*! - \enum QMediaPlaylist::Error - - This enum describes the QMediaPlaylist error codes. - - \value NoError No errors. - \value FormatError Format error. - \value FormatNotSupportedError Format not supported. - \value NetworkError Network error. - \value AccessDeniedError Access denied error. -*/ - -QT_END_NAMESPACE - -#include "moc_qmediaplaylist.cpp" diff --git a/examples/multimediawidgets/player/qmediaplaylist.h b/examples/multimediawidgets/player/qmediaplaylist.h deleted file mode 100644 index 163ef93fe..000000000 --- a/examples/multimediawidgets/player/qmediaplaylist.h +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QMEDIAPLAYLIST_H -#define QMEDIAPLAYLIST_H - -#include <QtCore/qobject.h> - -#include <QtMultimedia/qtmultimediaglobal.h> -#include <QtMultimedia/qmediaenumdebug.h> - - -QT_BEGIN_NAMESPACE - -class QMediaPlaylistPrivate; -class QMediaPlaylist : public QObject -{ - Q_OBJECT - Q_PROPERTY(QMediaPlaylist::PlaybackMode playbackMode READ playbackMode WRITE setPlaybackMode NOTIFY playbackModeChanged) - Q_PROPERTY(QUrl currentMedia READ currentMedia NOTIFY currentMediaChanged) - Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged) - -public: - enum PlaybackMode { CurrentItemOnce, CurrentItemInLoop, Sequential, Loop }; - Q_ENUM(PlaybackMode) - enum Error { NoError, FormatError, FormatNotSupportedError, NetworkError, AccessDeniedError }; - Q_ENUM(Error) - - explicit QMediaPlaylist(QObject *parent = nullptr); - virtual ~QMediaPlaylist(); - - PlaybackMode playbackMode() const; - void setPlaybackMode(PlaybackMode mode); - - int currentIndex() const; - QUrl currentMedia() const; - - int nextIndex(int steps = 1) const; - int previousIndex(int steps = 1) const; - - QUrl media(int index) const; - - int mediaCount() const; - bool isEmpty() const; - - void addMedia(const QUrl &content); - void addMedia(const QList<QUrl> &items); - bool insertMedia(int index, const QUrl &content); - bool insertMedia(int index, const QList<QUrl> &items); - bool moveMedia(int from, int to); - bool removeMedia(int pos); - bool removeMedia(int start, int end); - void clear(); - - void load(const QUrl &location, const char *format = nullptr); - void load(QIODevice *device, const char *format = nullptr); - - bool save(const QUrl &location, const char *format = nullptr) const; - bool save(QIODevice *device, const char *format) const; - - Error error() const; - QString errorString() const; - -public Q_SLOTS: - void shuffle(); - - void next(); - void previous(); - - void setCurrentIndex(int index); - -Q_SIGNALS: - void currentIndexChanged(int index); - void playbackModeChanged(QMediaPlaylist::PlaybackMode mode); - void currentMediaChanged(const QUrl&); - - void mediaAboutToBeInserted(int start, int end); - void mediaInserted(int start, int end); - void mediaAboutToBeRemoved(int start, int end); - void mediaRemoved(int start, int end); - void mediaChanged(int start, int end); - - void loaded(); - void loadFailed(); - -private: - QMediaPlaylistPrivate *d_ptr; - Q_DECLARE_PRIVATE(QMediaPlaylist) -}; - -QT_END_NAMESPACE - -Q_MEDIA_ENUM_DEBUG(QMediaPlaylist, PlaybackMode) -Q_MEDIA_ENUM_DEBUG(QMediaPlaylist, Error) - -#endif // QMEDIAPLAYLIST_H diff --git a/examples/multimediawidgets/player/qmediaplaylist_p.h b/examples/multimediawidgets/player/qmediaplaylist_p.h deleted file mode 100644 index a09831377..000000000 --- a/examples/multimediawidgets/player/qmediaplaylist_p.h +++ /dev/null @@ -1,148 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QMEDIAPLAYLIST_P_H -#define QMEDIAPLAYLIST_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qmediaplaylist.h" -#include "qplaylistfileparser_p.h" - -#include <QtCore/qdebug.h> - -#ifdef Q_MOC_RUN -# pragma Q_MOC_EXPAND_MACROS -#endif - -QT_BEGIN_NAMESPACE - - -class QMediaPlaylistControl; - -class QMediaPlaylistPrivate -{ - Q_DECLARE_PUBLIC(QMediaPlaylist) -public: - QMediaPlaylistPrivate() - : error(QMediaPlaylist::NoError) - { - } - - virtual ~QMediaPlaylistPrivate() - { - if (parser) - delete parser; - } - - void loadFailed(QMediaPlaylist::Error error, const QString &errorString) - { - this->error = error; - this->errorString = errorString; - - emit q_ptr->loadFailed(); - } - - void loadFinished() - { - q_ptr->addMedia(parser->playlist); - - emit q_ptr->loaded(); - } - - bool checkFormat(const char *format) const - { - QLatin1String f(format); - QPlaylistFileParser::FileType type = format ? QPlaylistFileParser::UNKNOWN : QPlaylistFileParser::M3U8; - if (format) { - if (f == QLatin1String("m3u") || f == QLatin1String("text/uri-list") || - f == QLatin1String("audio/x-mpegurl") || f == QLatin1String("audio/mpegurl")) - type = QPlaylistFileParser::M3U; - else if (f == QLatin1String("m3u8") || f == QLatin1String("application/x-mpegURL") || - f == QLatin1String("application/vnd.apple.mpegurl")) - type = QPlaylistFileParser::M3U8; - } - - if (type == QPlaylistFileParser::UNKNOWN || type == QPlaylistFileParser::PLS) { - error = QMediaPlaylist::FormatNotSupportedError; - errorString = QMediaPlaylist::tr("This file format is not supported."); - return false; - } - return true; - } - - void ensureParser() - { - if (parser) - return; - - parser = new QPlaylistFileParser(q_ptr); - QObject::connect(parser, &QPlaylistFileParser::finished, [this]() { loadFinished(); }); - QObject::connect(parser, &QPlaylistFileParser::error, - [this](QMediaPlaylist::Error err, const QString& errorMsg) { loadFailed(err, errorMsg); }); - } - - int nextPosition(int steps) const; - int prevPosition(int steps) const; - - QList<QUrl> playlist; - - int currentPos = -1; - QMediaPlaylist::PlaybackMode playbackMode = QMediaPlaylist::Sequential; - - QPlaylistFileParser *parser = nullptr; - mutable QMediaPlaylist::Error error; - mutable QString errorString; - - QMediaPlaylist *q_ptr; -}; - -QT_END_NAMESPACE - - -#endif // QMEDIAPLAYLIST_P_H diff --git a/examples/multimediawidgets/player/qplaylistfileparser.cpp b/examples/multimediawidgets/player/qplaylistfileparser.cpp deleted file mode 100644 index d684a9853..000000000 --- a/examples/multimediawidgets/player/qplaylistfileparser.cpp +++ /dev/null @@ -1,641 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qplaylistfileparser_p.h" -#include <qfileinfo.h> -#include <QtCore/QDebug> -#include <QtCore/qiodevice.h> -#include <QtCore/qpointer.h> -#include <QtNetwork/QNetworkReply> -#include <QtNetwork/QNetworkRequest> -#include "qmediaplayer.h" -#include "qmediametadata.h" - -QT_BEGIN_NAMESPACE - -namespace { - -class ParserBase -{ -public: - explicit ParserBase(QPlaylistFileParser *parent) - : m_parent(parent) - , m_aborted(false) - { - Q_ASSERT(m_parent); - } - - bool parseLine(int lineIndex, const QString& line, const QUrl& root) - { - if (m_aborted) - return false; - - const bool ok = parseLineImpl(lineIndex, line, root); - return ok && !m_aborted; - } - - virtual void abort() { m_aborted = true; } - virtual ~ParserBase() = default; - -protected: - virtual bool parseLineImpl(int lineIndex, const QString& line, const QUrl& root) = 0; - - static QUrl expandToFullPath(const QUrl &root, const QString &line) - { - // On Linux, backslashes are not converted to forward slashes :/ - if (line.startsWith(QLatin1String("//")) || line.startsWith(QLatin1String("\\\\"))) { - // Network share paths are not resolved - return QUrl::fromLocalFile(line); - } - - QUrl url(line); - if (url.scheme().isEmpty()) { - // Resolve it relative to root - if (root.isLocalFile()) - return QUrl::fromUserInput(line, root.adjusted(QUrl::RemoveFilename).toLocalFile(), QUrl::AssumeLocalFile); - return root.resolved(url); - } - if (url.scheme().length() == 1) - // Assume it's a drive letter for a Windows path - url = QUrl::fromLocalFile(line); - - return url; - } - - void newItemFound(const QVariant& content) { Q_EMIT m_parent->newItem(content); } - - - QPlaylistFileParser *m_parent; - bool m_aborted; -}; - -class M3UParser : public ParserBase -{ -public: - explicit M3UParser(QPlaylistFileParser *q) - : ParserBase(q) - , m_extendedFormat(false) - { - } - - /* - * - Extended M3U directives - - #EXTM3U - header - must be first line of file - #EXTINF - extra info - length (seconds), title - #EXTINF - extra info - length (seconds), artist '-' title - - Example - - #EXTM3U - #EXTINF:123, Sample artist - Sample title - C:\Documents and Settings\I\My Music\Sample.mp3 - #EXTINF:321,Example Artist - Example title - C:\Documents and Settings\I\My Music\Greatest Hits\Example.ogg - - */ - bool parseLineImpl(int lineIndex, const QString& line, const QUrl& root) override - { - if (line[0] == u'#' ) { - if (m_extendedFormat) { - if (line.startsWith(QLatin1String("#EXTINF:"))) { - m_extraInfo.clear(); - int artistStart = line.indexOf(QLatin1String(","), 8); - bool ok = false; - QStringView lineView { line }; - int length = lineView.mid(8, artistStart < 8 ? -1 : artistStart - 8).trimmed().toInt(&ok); - if (ok && length > 0) { - //convert from second to milisecond - m_extraInfo[QMediaMetaData::Duration] = QVariant(length * 1000); - } - if (artistStart > 0) { - int titleStart = getSplitIndex(line, artistStart); - if (titleStart > artistStart) { - m_extraInfo[QMediaMetaData::Author] = lineView.mid(artistStart + 1, - titleStart - artistStart - 1).trimmed().toString(). - replace(QLatin1String("--"), QLatin1String("-")); - m_extraInfo[QMediaMetaData::Title] = lineView.mid(titleStart + 1).trimmed().toString(). - replace(QLatin1String("--"), QLatin1String("-")); - } else { - m_extraInfo[QMediaMetaData::Title] = lineView.mid(artistStart + 1).trimmed().toString(). - replace(QLatin1String("--"), QLatin1String("-")); - } - } - } - } else if (lineIndex == 0 && line.startsWith(QLatin1String("#EXTM3U"))) { - m_extendedFormat = true; - } - } else { - QUrl url = expandToFullPath(root, line); - m_extraInfo[QMediaMetaData::Url] = url; - m_parent->playlist.append(url); - newItemFound(QVariant::fromValue(m_extraInfo)); - m_extraInfo.clear(); - } - - return true; - } - - int getSplitIndex(const QString& line, int startPos) - { - if (startPos < 0) - startPos = 0; - const QChar* buf = line.data(); - for (int i = startPos; i < line.length(); ++i) { - if (buf[i] == u'-') { - if (i == line.length() - 1) - return i; - ++i; - if (buf[i] != u'-') - return i - 1; - } - } - return -1; - } - -private: - QMediaMetaData m_extraInfo; - bool m_extendedFormat; -}; - -class PLSParser : public ParserBase -{ -public: - explicit PLSParser(QPlaylistFileParser *q) - : ParserBase(q) - { - } - -/* - * -The format is essentially that of an INI file structured as follows: - -Header - - * [playlist] : This tag indicates that it is a Playlist File - -Track Entry -Assuming track entry #X - - * FileX : Variable defining location of stream. - * TitleX : Defines track title. - * LengthX : Length in seconds of track. Value of -1 indicates indefinite. - -Footer - - * NumberOfEntries : This variable indicates the number of tracks. - * Version : Playlist version. Currently only a value of 2 is valid. - -[playlist] - -File1=Alternative\everclear - SMFTA.mp3 - -Title1=Everclear - So Much For The Afterglow - -Length1=233 - -File2=http://www.site.com:8000/listen.pls - -Title2=My Cool Stream - -Length5=-1 - -NumberOfEntries=2 - -Version=2 -*/ - bool parseLineImpl(int, const QString &line, const QUrl &root) override - { - // We ignore everything but 'File' entries, since that's the only thing we care about. - if (!line.startsWith(QLatin1String("File"))) - return true; - - QString value = getValue(line); - if (value.isEmpty()) - return true; - - QUrl path = expandToFullPath(root, value); - m_parent->playlist.append(path); - newItemFound(path); - - return true; - } - - QString getValue(QStringView line) { - int start = line.indexOf(u'='); - if (start < 0) - return QString(); - return line.mid(start + 1).trimmed().toString(); - } -}; -} - -///////////////////////////////////////////////////////////////////////////////////////////////// - -class QPlaylistFileParserPrivate -{ - Q_DECLARE_PUBLIC(QPlaylistFileParser) -public: - QPlaylistFileParserPrivate(QPlaylistFileParser *q) - : q_ptr(q) - , m_stream(nullptr) - , m_type(QPlaylistFileParser::UNKNOWN) - , m_scanIndex(0) - , m_lineIndex(-1) - , m_utf8(false) - , m_aborted(false) - { - } - - void handleData(); - void handleParserFinished(); - void abort(); - void reset(); - - QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> m_source; - QScopedPointer<ParserBase> m_currentParser; - QByteArray m_buffer; - QUrl m_root; - QNetworkAccessManager m_mgr; - QString m_mimeType; - QPlaylistFileParser *q_ptr; - QPointer<QIODevice> m_stream; - QPlaylistFileParser::FileType m_type; - struct ParserJob - { - QIODevice *m_stream; - QUrl m_media; - QString m_mimeType; - [[nodiscard]] bool isValid() const { return m_stream || !m_media.isEmpty(); } - void reset() { m_stream = nullptr; m_media = QUrl(); m_mimeType = QString(); } - } m_pendingJob; - int m_scanIndex; - int m_lineIndex; - bool m_utf8; - bool m_aborted; - -private: - bool processLine(int startIndex, int length); -}; - -#define LINE_LIMIT 4096 -#define READ_LIMIT 64 - -bool QPlaylistFileParserPrivate::processLine(int startIndex, int length) -{ - Q_Q(QPlaylistFileParser); - m_lineIndex++; - - if (!m_currentParser) { - const QString urlString = m_root.toString(); - const QString &suffix = !urlString.isEmpty() ? QFileInfo(urlString).suffix() : urlString; - QString mimeType; - if (m_source) - mimeType = m_source->header(QNetworkRequest::ContentTypeHeader).toString(); - m_type = QPlaylistFileParser::findPlaylistType(suffix, !mimeType.isEmpty() ? mimeType : m_mimeType, m_buffer.constData(), quint32(m_buffer.size())); - - switch (m_type) { - case QPlaylistFileParser::UNKNOWN: - emit q->error(QMediaPlaylist::FormatError, - QMediaPlaylist::tr("%1 playlist type is unknown").arg(m_root.toString())); - q->abort(); - return false; - case QPlaylistFileParser::M3U: - m_currentParser.reset(new M3UParser(q)); - break; - case QPlaylistFileParser::M3U8: - m_currentParser.reset(new M3UParser(q)); - m_utf8 = true; - break; - case QPlaylistFileParser::PLS: - m_currentParser.reset(new PLSParser(q)); - break; - } - - Q_ASSERT(!m_currentParser.isNull()); - } - - QString line; - - if (m_utf8) { - line = QString::fromUtf8(m_buffer.constData() + startIndex, length).trimmed(); - } else { - line = QString::fromLatin1(m_buffer.constData() + startIndex, length).trimmed(); - } - if (line.isEmpty()) - return true; - - Q_ASSERT(m_currentParser); - return m_currentParser->parseLine(m_lineIndex, line, m_root); -} - -void QPlaylistFileParserPrivate::handleData() -{ - Q_Q(QPlaylistFileParser); - while (m_stream->bytesAvailable() && !m_aborted) { - int expectedBytes = qMin(READ_LIMIT, int(qMin(m_stream->bytesAvailable(), - qint64(LINE_LIMIT - m_buffer.size())))); - m_buffer.push_back(m_stream->read(expectedBytes)); - int processedBytes = 0; - while (m_scanIndex < m_buffer.length() && !m_aborted) { - char s = m_buffer[m_scanIndex]; - if (s == '\r' || s == '\n') { - int l = m_scanIndex - processedBytes; - if (l > 0) { - if (!processLine(processedBytes, l)) - break; - } - processedBytes = m_scanIndex + 1; - if (!m_stream) { - //some error happened, so exit parsing - return; - } - } - m_scanIndex++; - } - - if (m_aborted) - break; - - if (m_buffer.length() - processedBytes >= LINE_LIMIT) { - emit q->error(QMediaPlaylist::FormatError, QMediaPlaylist::tr("invalid line in playlist file")); - q->abort(); - break; - } - - if (!m_stream->bytesAvailable() && (!m_source || !m_source->isFinished())) { - //last line - processLine(processedBytes, -1); - break; - } - - Q_ASSERT(m_buffer.length() == m_scanIndex); - if (processedBytes == 0) - continue; - - int copyLength = m_buffer.length() - processedBytes; - if (copyLength > 0) { - Q_ASSERT(copyLength <= READ_LIMIT); - m_buffer = m_buffer.right(copyLength); - } else { - m_buffer.clear(); - } - m_scanIndex = 0; - } - - handleParserFinished(); -} - -QPlaylistFileParser::QPlaylistFileParser(QObject *parent) - : QObject(parent) - , d_ptr(new QPlaylistFileParserPrivate(this)) -{ - -} - -QPlaylistFileParser::~QPlaylistFileParser() = default; - -QPlaylistFileParser::FileType QPlaylistFileParser::findByMimeType(const QString &mime) -{ - if (mime == QLatin1String("text/uri-list") || mime == QLatin1String("audio/x-mpegurl") || mime == QLatin1String("audio/mpegurl")) - return QPlaylistFileParser::M3U; - - if (mime == QLatin1String("application/x-mpegURL") || mime == QLatin1String("application/vnd.apple.mpegurl")) - return QPlaylistFileParser::M3U8; - - if (mime == QLatin1String("audio/x-scpls")) - return QPlaylistFileParser::PLS; - - return QPlaylistFileParser::UNKNOWN; -} - -QPlaylistFileParser::FileType QPlaylistFileParser::findBySuffixType(const QString &suffix) -{ - const QString &s = suffix.toLower(); - - if (s == QLatin1String("m3u")) - return QPlaylistFileParser::M3U; - - if (s == QLatin1String("m3u8")) - return QPlaylistFileParser::M3U8; - - if (s == QLatin1String("pls")) - return QPlaylistFileParser::PLS; - - return QPlaylistFileParser::UNKNOWN; -} - -QPlaylistFileParser::FileType QPlaylistFileParser::findByDataHeader(const char *data, quint32 size) -{ - if (!data || size == 0) - return QPlaylistFileParser::UNKNOWN; - - if (size >= 7 && strncmp(data, "#EXTM3U", 7) == 0) - return QPlaylistFileParser::M3U; - - if (size >= 10 && strncmp(data, "[playlist]", 10) == 0) - return QPlaylistFileParser::PLS; - - return QPlaylistFileParser::UNKNOWN; -} - -QPlaylistFileParser::FileType QPlaylistFileParser::findPlaylistType(const QString& suffix, - const QString& mime, - const char *data, - quint32 size) -{ - - FileType dataHeaderType = findByDataHeader(data, size); - if (dataHeaderType != UNKNOWN) - return dataHeaderType; - - FileType mimeType = findByMimeType(mime); - if (mimeType != UNKNOWN) - return mimeType; - - mimeType = findBySuffixType(mime); - if (mimeType != UNKNOWN) - return mimeType; - - FileType suffixType = findBySuffixType(suffix); - if (suffixType != UNKNOWN) - return suffixType; - - return UNKNOWN; -} - -/* - * Delegating - */ -void QPlaylistFileParser::start(const QUrl &media, QIODevice *stream, const QString &mimeType) -{ - if (stream) - start(stream, mimeType); - else - start(media, mimeType); -} - -void QPlaylistFileParser::start(QIODevice *stream, const QString &mimeType) -{ - Q_D(QPlaylistFileParser); - const bool validStream = stream ? (stream->isOpen() && stream->isReadable()) : false; - - if (!validStream) { - Q_EMIT error(QMediaPlaylist::AccessDeniedError, QMediaPlaylist::tr("Invalid stream")); - return; - } - - if (!d->m_currentParser.isNull()) { - abort(); - d->m_pendingJob = { stream, QUrl(), mimeType }; - return; - } - - playlist.clear(); - d->reset(); - d->m_mimeType = mimeType; - d->m_stream = stream; - connect(d->m_stream, SIGNAL(readyRead()), this, SLOT(handleData())); - d->handleData(); -} - -void QPlaylistFileParser::start(const QUrl& request, const QString &mimeType) -{ - Q_D(QPlaylistFileParser); - const QUrl &url = request.url(); - - if (url.isLocalFile() && !QFile::exists(url.toLocalFile())) { - emit error(QMediaPlaylist::AccessDeniedError, QString(QMediaPlaylist::tr("%1 does not exist")).arg(url.toString())); - return; - } - - if (!d->m_currentParser.isNull()) { - abort(); - d->m_pendingJob = { nullptr, request, mimeType }; - return; - } - - d->reset(); - d->m_root = url; - d->m_mimeType = mimeType; - d->m_source.reset(d->m_mgr.get(QNetworkRequest(request))); - d->m_stream = d->m_source.get(); - connect(d->m_source.data(), SIGNAL(readyRead()), this, SLOT(handleData())); - connect(d->m_source.data(), SIGNAL(finished()), this, SLOT(handleData())); - connect(d->m_source.data(), SIGNAL(errorOccurred(QNetworkReply::NetworkError)), this, SLOT(handleError())); - - if (url.isLocalFile()) - d->handleData(); -} - -void QPlaylistFileParser::abort() -{ - Q_D(QPlaylistFileParser); - d->abort(); - - if (d->m_source) - d->m_source->disconnect(); - - if (d->m_stream) - disconnect(d->m_stream, SIGNAL(readyRead()), this, SLOT(handleData())); - - playlist.clear(); -} - -void QPlaylistFileParser::handleData() -{ - Q_D(QPlaylistFileParser); - d->handleData(); -} - -void QPlaylistFileParserPrivate::handleParserFinished() -{ - Q_Q(QPlaylistFileParser); - const bool isParserValid = !m_currentParser.isNull(); - if (!isParserValid && !m_aborted) - emit q->error(QMediaPlaylist::FormatNotSupportedError, QMediaPlaylist::tr("Empty file provided")); - - if (isParserValid && !m_aborted) { - m_currentParser.reset(); - emit q->finished(); - } - - if (!m_aborted) - q->abort(); - - if (!m_source.isNull()) - m_source.reset(); - - if (m_pendingJob.isValid()) - q->start(m_pendingJob.m_media, m_pendingJob.m_stream, m_pendingJob.m_mimeType); -} - -void QPlaylistFileParserPrivate::abort() -{ - m_aborted = true; - if (!m_currentParser.isNull()) - m_currentParser->abort(); -} - -void QPlaylistFileParserPrivate::reset() -{ - Q_ASSERT(m_currentParser.isNull()); - Q_ASSERT(m_source.isNull()); - m_buffer.clear(); - m_root.clear(); - m_mimeType.clear(); - m_stream = nullptr; - m_type = QPlaylistFileParser::UNKNOWN; - m_scanIndex = 0; - m_lineIndex = -1; - m_utf8 = false; - m_aborted = false; - m_pendingJob.reset(); -} - -void QPlaylistFileParser::handleError() -{ - Q_D(QPlaylistFileParser); - const QString &errorString = d->m_source->errorString(); - Q_EMIT error(QMediaPlaylist::NetworkError, errorString); - abort(); -} - -QT_END_NAMESPACE diff --git a/examples/multimediawidgets/player/qplaylistfileparser_p.h b/examples/multimediawidgets/player/qplaylistfileparser_p.h deleted file mode 100644 index 98011fce0..000000000 --- a/examples/multimediawidgets/player/qplaylistfileparser_p.h +++ /dev/null @@ -1,116 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PLAYLISTFILEPARSER_P_H -#define PLAYLISTFILEPARSER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qtmultimediaglobal.h" -#include "qmediaplaylist.h" -#include <QtCore/qobject.h> - -QT_BEGIN_NAMESPACE - -class QIODevice; -class QUrl; -class QNetworkRequest; - -class QPlaylistFileParserPrivate; - -class QPlaylistFileParser : public QObject -{ - Q_OBJECT -public: - QPlaylistFileParser(QObject *parent = nullptr); - ~QPlaylistFileParser(); - - enum FileType - { - UNKNOWN, - M3U, - M3U8, // UTF-8 version of M3U - PLS - }; - - void start(const QUrl &media, QIODevice *stream = nullptr, const QString &mimeType = QString()); - void start(const QUrl &request, const QString &mimeType = QString()); - void start(QIODevice *stream, const QString &mimeType = QString()); - void abort(); - - QList<QUrl> playlist; - -Q_SIGNALS: - void newItem(const QVariant& content); - void finished(); - void error(QMediaPlaylist::Error err, const QString& errorMsg); - -private Q_SLOTS: - void handleData(); - void handleError(); - -private: - - static FileType findByMimeType(const QString &mime); - static FileType findBySuffixType(const QString &suffix); - static FileType findByDataHeader(const char *data, quint32 size); - static FileType findPlaylistType(QIODevice *device, - const QString& mime); - static FileType findPlaylistType(const QString &suffix, - const QString& mime, - const char *data = nullptr, - quint32 size = 0); - - Q_DISABLE_COPY(QPlaylistFileParser) - Q_DECLARE_PRIVATE(QPlaylistFileParser) - QScopedPointer<QPlaylistFileParserPrivate> d_ptr; -}; - -QT_END_NAMESPACE - -#endif // PLAYLISTFILEPARSER_P_H diff --git a/examples/multimediawidgets/player/videowidget.cpp b/examples/multimediawidgets/player/videowidget.cpp deleted file mode 100644 index a97e1d940..000000000 --- a/examples/multimediawidgets/player/videowidget.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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 "videowidget.h" - -#include <QKeyEvent> -#include <QMouseEvent> - -VideoWidget::VideoWidget(QWidget *parent) - : QVideoWidget(parent) -{ - setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); - - QPalette p = palette(); - p.setColor(QPalette::Window, Qt::black); - setPalette(p); - -#ifndef Q_OS_ANDROID // QTBUG-95723 - setAttribute(Qt::WA_OpaquePaintEvent); -#endif -} - -void VideoWidget::keyPressEvent(QKeyEvent *event) -{ - if ((event->key() == Qt::Key_Escape || event->key() == Qt::Key_Back) && isFullScreen()) { - setFullScreen(false); - event->accept(); - } else if (event->key() == Qt::Key_Enter && event->modifiers() & Qt::Key_Alt) { - setFullScreen(!isFullScreen()); - event->accept(); - } else { - QVideoWidget::keyPressEvent(event); - } -} - -void VideoWidget::mouseDoubleClickEvent(QMouseEvent *event) -{ - setFullScreen(!isFullScreen()); - event->accept(); -} - -void VideoWidget::mousePressEvent(QMouseEvent *event) -{ - QVideoWidget::mousePressEvent(event); -} - diff --git a/examples/multimediawidgets/player/videowidget.h b/examples/multimediawidgets/player/videowidget.h deleted file mode 100644 index c01632e7b..000000000 --- a/examples/multimediawidgets/player/videowidget.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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$ -** -****************************************************************************/ - -#ifndef VIDEOWIDGET_H -#define VIDEOWIDGET_H - -#include <QVideoWidget> - -class VideoWidget : public QVideoWidget -{ - Q_OBJECT - -public: - explicit VideoWidget(QWidget *parent = nullptr); - -protected: - void keyPressEvent(QKeyEvent *event) override; - void mouseDoubleClickEvent(QMouseEvent *event) override; - void mousePressEvent(QMouseEvent *event) override; -}; - -#endif // VIDEOWIDGET_H diff --git a/examples/multimediawidgets/videographicsitem/CMakeLists.txt b/examples/multimediawidgets/videographicsitem/CMakeLists.txt deleted file mode 100644 index fb8f4d857..000000000 --- a/examples/multimediawidgets/videographicsitem/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project(videographicsitem LANGUAGES CXX) - -set(CMAKE_AUTOMOC ON) - -if(NOT DEFINED INSTALL_EXAMPLESDIR) - set(INSTALL_EXAMPLESDIR "examples") -endif() - -set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/multimediawidgets/videographicsitem") - -find_package(Qt6 REQUIRED COMPONENTS Core Gui Multimedia MultimediaWidgets Widgets) - -qt_add_executable(videographicsitem - main.cpp - videoplayer.cpp videoplayer.h -) - -set_target_properties(videographicsitem PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) - -target_link_libraries(videographicsitem PUBLIC - Qt::Core - Qt::Gui - Qt::Multimedia - Qt::MultimediaWidgets - Qt::Widgets -) - -install(TARGETS videographicsitem - RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" - BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" - LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" -) diff --git a/examples/multimediawidgets/videographicsitem/doc/images/video-videographicsitem.png b/examples/multimediawidgets/videographicsitem/doc/images/video-videographicsitem.png Binary files differdeleted file mode 100644 index e333c54a2..000000000 --- a/examples/multimediawidgets/videographicsitem/doc/images/video-videographicsitem.png +++ /dev/null diff --git a/examples/multimediawidgets/videographicsitem/doc/src/videographicsitem.qdoc b/examples/multimediawidgets/videographicsitem/doc/src/videographicsitem.qdoc deleted file mode 100644 index 74fbf65cf..000000000 --- a/examples/multimediawidgets/videographicsitem/doc/src/videographicsitem.qdoc +++ /dev/null @@ -1,43 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** 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. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example multimediawidgets/videographicsitem - \title Video Graphics Item Example - \ingroup multimedia_examples - \brief Streaming video on a graphics scene. - \meta {tag} {widgets} - - \e{Video Graphics Item} demonstrates how to implement a QGraphicsItem that - displays video on a graphics scene using QVideoSink. - - \image video-videographicsitem.png - - \sa {Video Widget Example} - - \include examples-run.qdocinc -*/ diff --git a/examples/multimediawidgets/videographicsitem/main.cpp b/examples/multimediawidgets/videographicsitem/main.cpp deleted file mode 100644 index e262c3908..000000000 --- a/examples/multimediawidgets/videographicsitem/main.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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 "videoplayer.h" - -#include <QApplication> -#include <QCommandLineParser> -#include <QCommandLineOption> -#include <QDir> -#include <QUrl> - -int main(int argc, char **argv) -{ - QApplication app(argc, argv); - - QCoreApplication::setApplicationName("Player Example"); - QCoreApplication::setOrganizationName("QtProject"); - QCoreApplication::setApplicationVersion(QT_VERSION_STR); - QCommandLineParser parser; - parser.setApplicationDescription("Qt MultiMedia Player QGraphicsView Example"); - parser.addHelpOption(); - parser.addVersionOption(); - parser.addPositionalArgument("url", "The URL to open."); - parser.process(app); - - VideoPlayer player; - - if (!parser.positionalArguments().isEmpty() && player.isPlayerAvailable()) { - const QUrl url = - QUrl::fromUserInput(parser.positionalArguments().constFirst(), - QDir::currentPath(), QUrl::AssumeLocalFile); - player.load(url); - } - - player.show(); - - return app.exec(); -} - diff --git a/examples/multimediawidgets/videographicsitem/videographicsitem.pro b/examples/multimediawidgets/videographicsitem/videographicsitem.pro deleted file mode 100644 index 30a9b6f21..000000000 --- a/examples/multimediawidgets/videographicsitem/videographicsitem.pro +++ /dev/null @@ -1,14 +0,0 @@ -TEMPLATE = app -TARGET = videographicsitem - -QT += multimedia multimediawidgets - -HEADERS += videoplayer.h - -SOURCES += main.cpp \ - videoplayer.cpp - -target.path = $$[QT_INSTALL_EXAMPLES]/multimediawidgets/videographicsitem -INSTALLS += target - -QT+=widgets diff --git a/examples/multimediawidgets/videographicsitem/videoplayer.cpp b/examples/multimediawidgets/videographicsitem/videoplayer.cpp deleted file mode 100644 index 2f76f2be3..000000000 --- a/examples/multimediawidgets/videographicsitem/videoplayer.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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 "videoplayer.h" - -#include <QtWidgets> -#include <QGraphicsVideoItem> - -VideoPlayer::VideoPlayer(QWidget *parent) - : QWidget(parent) -{ - m_mediaPlayer = new QMediaPlayer(this); - const QSize screenGeometry = screen()->availableSize(); - m_videoItem = new QGraphicsVideoItem; - m_videoItem->setSize(QSizeF(screenGeometry.width() / 3, screenGeometry.height() / 2)); - - QGraphicsScene *scene = new QGraphicsScene(this); - QGraphicsView *graphicsView = new QGraphicsView(scene); - - scene->addItem(m_videoItem); - - QSlider *rotateSlider = new QSlider(Qt::Horizontal); - rotateSlider->setToolTip(tr("Rotate Video")); - rotateSlider->setRange(-180, 180); - rotateSlider->setValue(0); - - connect(rotateSlider, &QAbstractSlider::valueChanged, - this, &VideoPlayer::rotateVideo); - - QAbstractButton *openButton = new QPushButton(tr("Open...")); - connect(openButton, &QAbstractButton::clicked, this, &VideoPlayer::openFile); - - m_playButton = new QPushButton; - m_playButton->setEnabled(false); - m_playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay)); - - connect(m_playButton, &QAbstractButton::clicked, this, &VideoPlayer::play); - - m_positionSlider = new QSlider(Qt::Horizontal); - m_positionSlider->setRange(0, 0); - - connect(m_positionSlider, &QAbstractSlider::sliderMoved, - this, &VideoPlayer::setPosition); - - QBoxLayout *controlLayout = new QHBoxLayout; - controlLayout->setContentsMargins(0, 0, 0, 0); - controlLayout->addWidget(openButton); - controlLayout->addWidget(m_playButton); - controlLayout->addWidget(m_positionSlider); - - QBoxLayout *layout = new QVBoxLayout(this); - layout->addWidget(graphicsView); - layout->addWidget(rotateSlider); - layout->addLayout(controlLayout); - - m_mediaPlayer->setVideoOutput(m_videoItem); - connect(m_mediaPlayer, &QMediaPlayer::playbackStateChanged, - this, &VideoPlayer::mediaStateChanged); - connect(m_mediaPlayer, &QMediaPlayer::positionChanged, this, &VideoPlayer::positionChanged); - connect(m_mediaPlayer, &QMediaPlayer::durationChanged, this, &VideoPlayer::durationChanged); -} - -VideoPlayer::~VideoPlayer() -{ -} - -QSize VideoPlayer::sizeHint() const -{ - return (m_videoItem->size() * qreal(3) / qreal(2)).toSize(); -} - -bool VideoPlayer::isPlayerAvailable() const -{ - return m_mediaPlayer->isAvailable(); -} - -void VideoPlayer::openFile() -{ - QFileDialog fileDialog(this); - fileDialog.setAcceptMode(QFileDialog::AcceptOpen); - fileDialog.setWindowTitle(tr("Open Movie")); - fileDialog.setDirectory(QStandardPaths::standardLocations(QStandardPaths::MoviesLocation).value(0, QDir::homePath())); - if (fileDialog.exec() == QDialog::Accepted) - load(fileDialog.selectedUrls().constFirst()); -} - -void VideoPlayer::load(const QUrl &url) -{ - m_mediaPlayer->setSource(url); - m_playButton->setEnabled(true); -} - -void VideoPlayer::play() -{ - switch (m_mediaPlayer->playbackState()) { - case QMediaPlayer::PlayingState: - m_mediaPlayer->pause(); - break; - default: - m_mediaPlayer->play(); - break; - } -} - -void VideoPlayer::mediaStateChanged(QMediaPlayer::PlaybackState state) -{ - switch(state) { - case QMediaPlayer::PlayingState: - m_playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPause)); - break; - default: - m_playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay)); - break; - } -} - -void VideoPlayer::positionChanged(qint64 position) -{ - m_positionSlider->setValue(position); -} - -void VideoPlayer::durationChanged(qint64 duration) -{ - m_positionSlider->setRange(0, duration); -} - -void VideoPlayer::setPosition(int position) -{ - m_mediaPlayer->setPosition(position); -} - - -void VideoPlayer::rotateVideo(int angle) -{ - //rotate around the center of video element - qreal x = m_videoItem->boundingRect().width() / 2.0; - qreal y = m_videoItem->boundingRect().height() / 2.0; - m_videoItem->setTransform(QTransform().translate(x, y).rotate(angle).translate(-x, -y)); -} diff --git a/examples/multimediawidgets/videographicsitem/videoplayer.h b/examples/multimediawidgets/videographicsitem/videoplayer.h deleted file mode 100644 index 9f01e8790..000000000 --- a/examples/multimediawidgets/videographicsitem/videoplayer.h +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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$ -** -****************************************************************************/ - -#ifndef VIDEOPLAYER_H -#define VIDEOPLAYER_H - -#include <QMediaPlayer> -#include <QWidget> - -QT_BEGIN_NAMESPACE -class QAbstractButton; -class QSlider; -class QGraphicsVideoItem; -QT_END_NAMESPACE - -class VideoPlayer : public QWidget -{ - Q_OBJECT - -public: - VideoPlayer(QWidget *parent = nullptr); - ~VideoPlayer(); - - void load(const QUrl &url); - bool isPlayerAvailable() const; - - QSize sizeHint() const override; - -public slots: - void openFile(); - void play(); - -private slots: - void mediaStateChanged(QMediaPlayer::PlaybackState state); - void positionChanged(qint64 position); - void durationChanged(qint64 duration); - void setPosition(int position); - void rotateVideo(int angle); - -private: - QMediaPlayer *m_mediaPlayer = nullptr; - QGraphicsVideoItem *m_videoItem = nullptr; - QAbstractButton *m_playButton = nullptr; - QSlider *m_positionSlider = nullptr; -}; - -#endif - diff --git a/examples/multimediawidgets/videowidget/CMakeLists.txt b/examples/multimediawidgets/videowidget/CMakeLists.txt deleted file mode 100644 index fbfaba50b..000000000 --- a/examples/multimediawidgets/videowidget/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project(videowidget LANGUAGES CXX) - -set(CMAKE_AUTOMOC ON) - -if(NOT DEFINED INSTALL_EXAMPLESDIR) - set(INSTALL_EXAMPLESDIR "examples") -endif() - -set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/multimediawidgets/videowidget") - -find_package(Qt6 REQUIRED COMPONENTS Core Gui Multimedia MultimediaWidgets Widgets) - -qt_add_executable(videowidget - main.cpp - videoplayer.cpp videoplayer.h -) - -set_target_properties(videowidget PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) - -target_link_libraries(videowidget PUBLIC - Qt::Core - Qt::Gui - Qt::Multimedia - Qt::MultimediaWidgets - Qt::Widgets -) - -install(TARGETS videowidget - RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" - BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" - LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" -) diff --git a/examples/multimediawidgets/videowidget/doc/images/video-videowidget.png b/examples/multimediawidgets/videowidget/doc/images/video-videowidget.png Binary files differdeleted file mode 100644 index a3c7bcb44..000000000 --- a/examples/multimediawidgets/videowidget/doc/images/video-videowidget.png +++ /dev/null diff --git a/examples/multimediawidgets/videowidget/doc/src/videowidget.qdoc b/examples/multimediawidgets/videowidget/doc/src/videowidget.qdoc deleted file mode 100644 index 25bf7b2e3..000000000 --- a/examples/multimediawidgets/videowidget/doc/src/videowidget.qdoc +++ /dev/null @@ -1,41 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** 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. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example multimediawidgets/videowidget - \title Video Widget Example - \ingroup multimedia_examples - \brief Implementing a video player widget. - \meta {tag} {widgets,QVideoWidget} - - \e{Video Widget} demonstrates how to implement a simple video player using - QVideoWidget. - - \image video-videowidget.png - - \include examples-run.qdocinc -*/ diff --git a/examples/multimediawidgets/videowidget/main.cpp b/examples/multimediawidgets/videowidget/main.cpp deleted file mode 100644 index 3cf7e7989..000000000 --- a/examples/multimediawidgets/videowidget/main.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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 "videoplayer.h" - -#include <QtWidgets/QApplication> -#include <QtCore/QCommandLineParser> -#include <QtCore/QCommandLineOption> -#include <QtCore/QDir> -#include <QtCore/QUrl> -#include <QScreen> - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - - QCoreApplication::setApplicationName("Video Widget Example"); - QCoreApplication::setOrganizationName("QtProject"); - QGuiApplication::setApplicationDisplayName(QCoreApplication::applicationName()); - QCoreApplication::setApplicationVersion(QT_VERSION_STR); - QCommandLineParser parser; - parser.setApplicationDescription("Qt Video Widget Example"); - parser.addHelpOption(); - parser.addVersionOption(); - parser.addPositionalArgument("url", "The URL to open."); - parser.process(app); - - VideoPlayer player; - if (!parser.positionalArguments().isEmpty()) { - const QUrl url = - QUrl::fromUserInput(parser.positionalArguments().constFirst(), - QDir::currentPath(), QUrl::AssumeLocalFile); - player.setUrl(url); - } - - const QSize availableGeometry = player.screen()->availableSize(); - player.resize(availableGeometry.width() / 6, availableGeometry.height() / 4); - player.show(); - - return app.exec(); -} diff --git a/examples/multimediawidgets/videowidget/videoplayer.cpp b/examples/multimediawidgets/videowidget/videoplayer.cpp deleted file mode 100644 index ded52499c..000000000 --- a/examples/multimediawidgets/videowidget/videoplayer.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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 "videoplayer.h" - -#include <QtWidgets> -#include <QVideoWidget> - -VideoPlayer::VideoPlayer(QWidget *parent) - : QWidget(parent) -{ - m_mediaPlayer = new QMediaPlayer(this); - QVideoWidget *videoWidget = new QVideoWidget; - - QAbstractButton *openButton = new QPushButton(tr("Open...")); - connect(openButton, &QAbstractButton::clicked, this, &VideoPlayer::openFile); - - m_playButton = new QPushButton; - m_playButton->setEnabled(false); - m_playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay)); - - connect(m_playButton, &QAbstractButton::clicked, - this, &VideoPlayer::play); - - m_positionSlider = new QSlider(Qt::Horizontal); - m_positionSlider->setRange(0, 0); - - connect(m_positionSlider, &QAbstractSlider::sliderMoved, - this, &VideoPlayer::setPosition); - - m_errorLabel = new QLabel; - m_errorLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); - - QBoxLayout *controlLayout = new QHBoxLayout; - controlLayout->setContentsMargins(0, 0, 0, 0); - controlLayout->addWidget(openButton); - controlLayout->addWidget(m_playButton); - controlLayout->addWidget(m_positionSlider); - - QBoxLayout *layout = new QVBoxLayout; - layout->addWidget(videoWidget); - layout->addLayout(controlLayout); - layout->addWidget(m_errorLabel); - - setLayout(layout); - - m_mediaPlayer->setVideoOutput(videoWidget); - connect(m_mediaPlayer, &QMediaPlayer::playbackStateChanged, - this, &VideoPlayer::mediaStateChanged); - connect(m_mediaPlayer, &QMediaPlayer::positionChanged, this, &VideoPlayer::positionChanged); - connect(m_mediaPlayer, &QMediaPlayer::durationChanged, this, &VideoPlayer::durationChanged); - connect(m_mediaPlayer, &QMediaPlayer::errorChanged, - this, &VideoPlayer::handleError); -} - -VideoPlayer::~VideoPlayer() -{ -} - -void VideoPlayer::openFile() -{ - QFileDialog fileDialog(this); - fileDialog.setAcceptMode(QFileDialog::AcceptOpen); - fileDialog.setWindowTitle(tr("Open Movie")); - fileDialog.setDirectory(QStandardPaths::standardLocations(QStandardPaths::MoviesLocation).value(0, QDir::homePath())); - if (fileDialog.exec() == QDialog::Accepted) - setUrl(fileDialog.selectedUrls().constFirst()); -} - -void VideoPlayer::setUrl(const QUrl &url) -{ - m_errorLabel->setText(QString()); - setWindowFilePath(url.isLocalFile() ? url.toLocalFile() : QString()); - m_mediaPlayer->setSource(url); - m_playButton->setEnabled(true); -} - -void VideoPlayer::play() -{ - switch (m_mediaPlayer->playbackState()) { - case QMediaPlayer::PlayingState: - m_mediaPlayer->pause(); - break; - default: - m_mediaPlayer->play(); - break; - } -} - -void VideoPlayer::mediaStateChanged(QMediaPlayer::PlaybackState state) -{ - switch(state) { - case QMediaPlayer::PlayingState: - m_playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPause)); - break; - default: - m_playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay)); - break; - } -} - -void VideoPlayer::positionChanged(qint64 position) -{ - m_positionSlider->setValue(position); -} - -void VideoPlayer::durationChanged(qint64 duration) -{ - m_positionSlider->setRange(0, duration); -} - -void VideoPlayer::setPosition(int position) -{ - m_mediaPlayer->setPosition(position); -} - -void VideoPlayer::handleError() -{ - if (m_mediaPlayer->error() == QMediaPlayer::NoError) - return; - - m_playButton->setEnabled(false); - const QString errorString = m_mediaPlayer->errorString(); - QString message = "Error: "; - if (errorString.isEmpty()) - message += " #" + QString::number(int(m_mediaPlayer->error())); - else - message += errorString; - m_errorLabel->setText(message); -} diff --git a/examples/multimediawidgets/videowidget/videoplayer.h b/examples/multimediawidgets/videowidget/videoplayer.h deleted file mode 100644 index 723df0b6c..000000000 --- a/examples/multimediawidgets/videowidget/videoplayer.h +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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$ -** -****************************************************************************/ - -#ifndef VIDEOPLAYER_H -#define VIDEOPLAYER_H - -#include <QMediaPlayer> -#include <QWidget> - -QT_BEGIN_NAMESPACE -class QAbstractButton; -class QSlider; -class QLabel; -class QUrl; -QT_END_NAMESPACE - -class VideoPlayer : public QWidget -{ - Q_OBJECT -public: - VideoPlayer(QWidget *parent = nullptr); - ~VideoPlayer(); - - void setUrl(const QUrl &url); - -public slots: - void openFile(); - void play(); - -private slots: - void mediaStateChanged(QMediaPlayer::PlaybackState state); - void positionChanged(qint64 position); - void durationChanged(qint64 duration); - void setPosition(int position); - void handleError(); - -private: - QMediaPlayer* m_mediaPlayer; - QAbstractButton *m_playButton; - QSlider *m_positionSlider; - QLabel *m_errorLabel; -}; - -#endif diff --git a/examples/multimediawidgets/videowidget/videowidget.pro b/examples/multimediawidgets/videowidget/videowidget.pro deleted file mode 100644 index 603996b2e..000000000 --- a/examples/multimediawidgets/videowidget/videowidget.pro +++ /dev/null @@ -1,16 +0,0 @@ -TEMPLATE = app -TARGET = videowidget - -QT += multimedia multimediawidgets - -HEADERS = \ - videoplayer.h - -SOURCES = \ - main.cpp \ - videoplayer.cpp - -target.path = $$[QT_INSTALL_EXAMPLES]/multimediawidgets/videowidget -INSTALLS += target - -QT+=widgets |