diff options
Diffstat (limited to 'src/multimedia/recording/qmediarecorder.cpp')
-rw-r--r-- | src/multimedia/recording/qmediarecorder.cpp | 1324 |
1 files changed, 584 insertions, 740 deletions
diff --git a/src/multimedia/recording/qmediarecorder.cpp b/src/multimedia/recording/qmediarecorder.cpp index 617627985..d4237c87d 100644 --- a/src/multimedia/recording/qmediarecorder.cpp +++ b/src/multimedia/recording/qmediarecorder.cpp @@ -1,61 +1,24 @@ -/**************************************************************************** -** -** 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 "qmediarecorder.h" +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #include "qmediarecorder_p.h" -#include <qmediarecordercontrol.h> -#include "qmediaobject_p.h" -#include <qmediaservice.h> -#include <qmediaserviceprovider_p.h> -#include <qmetadatawritercontrol.h> -#include <qaudioencodersettingscontrol.h> -#include <qvideoencodersettingscontrol.h> -#include <qmediacontainercontrol.h> -#include <qmediaavailabilitycontrol.h> +#include <private/qplatformmediarecorder_p.h> +#include <qaudiodevice.h> #include <qcamera.h> -#include <qcameracontrol.h> +#include <qscreencapture.h> +#include <qwindowcapture.h> +#include <qmediacapturesession.h> +#include <private/qplatformcamera_p.h> +#include <private/qplatformsurfacecapture_p.h> +#include <private/qplatformmediaintegration_p.h> +#include <private/qplatformmediacapture_p.h> #include <QtCore/qdebug.h> #include <QtCore/qurl.h> #include <QtCore/qstringlist.h> #include <QtCore/qmetaobject.h> +#include <QtCore/qtimer.h> #include <qaudioformat.h> @@ -66,179 +29,103 @@ QT_BEGIN_NAMESPACE \inmodule QtMultimedia \ingroup multimedia \ingroup multimedia_recording + \ingroup multimedia_video + \ingroup multimedia_audio - \brief The QMediaRecorder class is used for the recording of media content. + \brief The QMediaRecorder class is used for encoding and recording a capture session. - The QMediaRecorder class is a high level media recording class. It's not - intended to be used alone but for accessing the media recording functions - of other media objects, like QCamera. + The QMediaRecorder class is a class for encoding and recording media generated in a + QMediaCaptureSession. \snippet multimedia-snippets/media.cpp Media recorder - - \sa QAudioRecorder */ +/*! + \qmltype MediaRecorder + \instantiates QMediaRecorder + \brief For encoding and recording media generated in a CaptureSession. -static void qRegisterMediaRecorderMetaTypes() -{ - qRegisterMetaType<QMediaRecorder::State>("QMediaRecorder::State"); - qRegisterMetaType<QMediaRecorder::Status>("QMediaRecorder::Status"); - qRegisterMetaType<QMediaRecorder::Error>("QMediaRecorder::Error"); -} - -Q_CONSTRUCTOR_FUNCTION(qRegisterMediaRecorderMetaTypes) - - -QMediaRecorderPrivate::QMediaRecorderPrivate(): - mediaObject(nullptr), - control(nullptr), - formatControl(nullptr), - audioControl(nullptr), - videoControl(nullptr), - metaDataControl(nullptr), - availabilityControl(nullptr), - settingsChanged(false), - notifyTimer(nullptr), - state(QMediaRecorder::StoppedState), - error(QMediaRecorder::NoError) -{ -} - -#define ENUM_NAME(c,e,v) (c::staticMetaObject.enumerator(c::staticMetaObject.indexOfEnumerator(e)).valueToKey((v))) - -void QMediaRecorderPrivate::_q_stateChanged(QMediaRecorder::State ps) -{ - Q_Q(QMediaRecorder); - - if (ps == QMediaRecorder::RecordingState) - notifyTimer->start(); - else - notifyTimer->stop(); - -// qDebug() << "Recorder state changed:" << ENUM_NAME(QMediaRecorder,"State",ps); - if (state != ps) { - emit q->stateChanged(ps); - } - - state = ps; -} - - -void QMediaRecorderPrivate::_q_error(int error, const QString &errorString) -{ - Q_Q(QMediaRecorder); - - this->error = QMediaRecorder::Error(error); - this->errorString = errorString; + \inqmlmodule QtMultimedia + \ingroup multimedia_qml + \ingroup multimedia_audio_qml + \ingroup multimedia_video_qml - emit q->error(this->error); -} + The MediaRecorder element can be used within a CaptureSession to record and encode audio and + video captured from a microphone and camera -void QMediaRecorderPrivate::_q_serviceDestroyed() -{ - mediaObject = nullptr; - control = nullptr; - formatControl = nullptr; - audioControl = nullptr; - videoControl = nullptr; - metaDataControl = nullptr; - availabilityControl = nullptr; - settingsChanged = true; -} + \since 6.2 + The code below shows a simple capture session containing a MediaRecorder using the default + camera and default audio input. -void QMediaRecorderPrivate::_q_updateActualLocation(const QUrl &location) -{ - if (actualLocation != location) { - actualLocation = location; - emit q_func()->actualLocationChanged(actualLocation); +\qml + CaptureSession { + id: captureSession + camera: Camera { + id: camera + active: true + } + audioInput: AudioInput {} + recorder: MediaRecorder { + id: recorder + } } -} - -void QMediaRecorderPrivate::_q_notify() -{ - emit q_func()->durationChanged(q_func()->duration()); -} - -void QMediaRecorderPrivate::_q_updateNotifyInterval(int ms) -{ - notifyTimer->setInterval(ms); -} - -void QMediaRecorderPrivate::applySettingsLater() -{ - if (control && !settingsChanged) { - settingsChanged = true; - QMetaObject::invokeMethod(q_func(), "_q_applySettings", Qt::QueuedConnection); +\endqml + + The code below shows how the recording can be started and stopped. +\qml + CameraButton { + text: "Record" + visible: recorder.recorderState !== MediaRecorder.RecordingState + onClicked: recorder.record() } -} -void QMediaRecorderPrivate::_q_applySettings() -{ - if (control && settingsChanged) { - settingsChanged = false; - control->applySettings(); + CameraButton { + id: stopButton + text: "Stop" + visible: recorder.recorderState === MediaRecorder.RecordingState + onClicked: recorder.stop() } -} +\endqml -void QMediaRecorderPrivate::_q_availabilityChanged(QMultimedia::AvailabilityStatus availability) + \sa CaptureSession, Camera, AudioInput, ImageCapture +*/ +QMediaRecorderPrivate::QMediaRecorderPrivate() { - Q_Q(QMediaRecorder); - Q_UNUSED(error); - Q_UNUSED(availability); - - // Really this should not always emit, but - // we can't really tell from here (isAvailable - // may not have changed, or the mediaobject's overridden - // availability() may not have changed). - q->availabilityChanged(q->availability()); - q->availabilityChanged(q->isAvailable()); + // Force an early initialization of the mime database + // to avoid a delay when recording for the first time. + encoderSettings.mimeType(); } -void QMediaRecorderPrivate::restartCamera() +QString QMediaRecorderPrivate::msgFailedStartRecording() { - //restart camera if it can't apply new settings in the Active state - QCamera *camera = qobject_cast<QCamera*>(mediaObject); - if (camera && camera->captureMode() == QCamera::CaptureVideo) { - QMetaObject::invokeMethod(camera, - "_q_preparePropertyChange", - Qt::DirectConnection, - Q_ARG(int, QCameraControl::VideoEncodingSettings)); - } + return QMediaRecorder::tr("Failed to start recording"); } - /*! - Constructs a media recorder which records the media produced by \a mediaObject. - - The \a parent is passed to QMediaObject. + Constructs a media recorder which records the media produced by a microphone and camera. + The media recorder is a child of \a{parent}. */ -QMediaRecorder::QMediaRecorder(QMediaObject *mediaObject, QObject *parent): - QObject(parent), - d_ptr(new QMediaRecorderPrivate) +QMediaRecorder::QMediaRecorder(QObject *parent) + : QObject(parent), + d_ptr(new QMediaRecorderPrivate) { Q_D(QMediaRecorder); - d->q_ptr = this; - d->notifyTimer = new QTimer(this); - connect(d->notifyTimer, SIGNAL(timeout()), SLOT(_q_notify())); - - setMediaObject(mediaObject); -} + auto &mediaIntegration = *QPlatformMediaIntegration::instance(); -/*! - \internal -*/ -QMediaRecorder::QMediaRecorder(QMediaRecorderPrivate &dd, QMediaObject *mediaObject, QObject *parent): - QObject(parent), - d_ptr(&dd) -{ - Q_D(QMediaRecorder); d->q_ptr = this; - - d->notifyTimer = new QTimer(this); - connect(d->notifyTimer, SIGNAL(timeout()), SLOT(_q_notify())); - - setMediaObject(mediaObject); + auto maybeControl = mediaIntegration.createRecorder(this); + if (maybeControl) { + // The first format info initialization may take some time, + // for users it seems to be more suitable to have a delay on the object construction + // rather than on QMediaRecorder::record + mediaIntegration.formatInfo(); + + d->control = maybeControl.value(); + } else { + d->initErrorMessage = maybeControl.error(); + qWarning() << "Failed to initialize QMediaRecorder" << maybeControl.error(); + } } /*! @@ -247,219 +134,76 @@ QMediaRecorder::QMediaRecorder(QMediaRecorderPrivate &dd, QMediaObject *mediaObj QMediaRecorder::~QMediaRecorder() { + if (d_ptr->captureSession) + d_ptr->captureSession->setRecorder(nullptr); + delete d_ptr->control; delete d_ptr; } /*! - Returns the QMediaObject instance that this QMediaRecorder is bound too, - or 0 otherwise. + \internal */ -QMediaObject *QMediaRecorder::mediaObject() const +QPlatformMediaRecorder *QMediaRecorder::platformRecoder() const { - return d_func()->mediaObject; + return d_ptr->control; } /*! \internal */ -bool QMediaRecorder::setMediaObject(QMediaObject *object) +void QMediaRecorder::setCaptureSession(QMediaCaptureSession *session) { Q_D(QMediaRecorder); + d->captureSession = session; +} +/*! + \qmlproperty QUrl QtMultimedia::MediaRecorder::outputLocation + \brief The destination location of media content. - if (object == d->mediaObject) - return true; - - if (d->mediaObject) { - if (d->control) { - disconnect(d->control, SIGNAL(stateChanged(QMediaRecorder::State)), - this, SLOT(_q_stateChanged(QMediaRecorder::State))); - - disconnect(d->control, SIGNAL(statusChanged(QMediaRecorder::Status)), - this, SIGNAL(statusChanged(QMediaRecorder::Status))); - - disconnect(d->control, SIGNAL(mutedChanged(bool)), - this, SIGNAL(mutedChanged(bool))); - - disconnect(d->control, SIGNAL(volumeChanged(qreal)), - this, SIGNAL(volumeChanged(qreal))); - - disconnect(d->control, SIGNAL(durationChanged(qint64)), - this, SIGNAL(durationChanged(qint64))); - - disconnect(d->control, SIGNAL(actualLocationChanged(QUrl)), - this, SLOT(_q_updateActualLocation(QUrl))); - - disconnect(d->control, SIGNAL(error(int,QString)), - this, SLOT(_q_error(int,QString))); - } - - disconnect(d->mediaObject, SIGNAL(notifyIntervalChanged(int)), this, SLOT(_q_updateNotifyInterval(int))); - - QMediaService *service = d->mediaObject->service(); - - if (service) { - disconnect(service, SIGNAL(destroyed()), this, SLOT(_q_serviceDestroyed())); - - if (d->control) - service->releaseControl(d->control); - if (d->formatControl) - service->releaseControl(d->formatControl); - if (d->audioControl) - service->releaseControl(d->audioControl); - if (d->videoControl) - service->releaseControl(d->videoControl); - if (d->metaDataControl) { - disconnect(d->metaDataControl, SIGNAL(metaDataChanged()), - this, SIGNAL(metaDataChanged())); - disconnect(d->metaDataControl, SIGNAL(metaDataChanged(QString,QVariant)), - this, SIGNAL(metaDataChanged(QString,QVariant))); - disconnect(d->metaDataControl, SIGNAL(metaDataAvailableChanged(bool)), - this, SIGNAL(metaDataAvailableChanged(bool))); - disconnect(d->metaDataControl, SIGNAL(writableChanged(bool)), - this, SIGNAL(metaDataWritableChanged(bool))); - - service->releaseControl(d->metaDataControl); - } - if (d->availabilityControl) { - disconnect(d->availabilityControl, SIGNAL(availabilityChanged(QMultimedia::AvailabilityStatus)), - this, SLOT(_q_availabilityChanged(QMultimedia::AvailabilityStatus))); - service->releaseControl(d->availabilityControl); - } - } - } - - d->control = nullptr; - d->formatControl = nullptr; - d->audioControl = nullptr; - d->videoControl = nullptr; - d->metaDataControl = nullptr; - d->availabilityControl = nullptr; - - d->mediaObject = object; - - if (d->mediaObject) { - QMediaService *service = d->mediaObject->service(); - - d->notifyTimer->setInterval(d->mediaObject->notifyInterval()); - connect(d->mediaObject, SIGNAL(notifyIntervalChanged(int)), SLOT(_q_updateNotifyInterval(int))); - - if (service) { - d->control = qobject_cast<QMediaRecorderControl*>(service->requestControl(QMediaRecorderControl_iid)); - - if (d->control) { - d->formatControl = qobject_cast<QMediaContainerControl *>(service->requestControl(QMediaContainerControl_iid)); - d->audioControl = qobject_cast<QAudioEncoderSettingsControl *>(service->requestControl(QAudioEncoderSettingsControl_iid)); - d->videoControl = qobject_cast<QVideoEncoderSettingsControl *>(service->requestControl(QVideoEncoderSettingsControl_iid)); - - QMediaControl *control = service->requestControl(QMetaDataWriterControl_iid); - if (control) { - d->metaDataControl = qobject_cast<QMetaDataWriterControl *>(control); - if (!d->metaDataControl) { - service->releaseControl(control); - } else { - connect(d->metaDataControl, - SIGNAL(metaDataChanged()), - SIGNAL(metaDataChanged())); - connect(d->metaDataControl, SIGNAL(metaDataChanged(QString,QVariant)), - this, SIGNAL(metaDataChanged(QString,QVariant))); - connect(d->metaDataControl, - SIGNAL(metaDataAvailableChanged(bool)), - SIGNAL(metaDataAvailableChanged(bool))); - connect(d->metaDataControl, - SIGNAL(writableChanged(bool)), - SIGNAL(metaDataWritableChanged(bool))); - } - } - - d->availabilityControl = service->requestControl<QMediaAvailabilityControl*>(); - if (d->availabilityControl) { - connect(d->availabilityControl, SIGNAL(availabilityChanged(QMultimedia::AvailabilityStatus)), - this, SLOT(_q_availabilityChanged(QMultimedia::AvailabilityStatus))); - } - - connect(d->control, SIGNAL(stateChanged(QMediaRecorder::State)), - this, SLOT(_q_stateChanged(QMediaRecorder::State))); - - connect(d->control, SIGNAL(statusChanged(QMediaRecorder::Status)), - this, SIGNAL(statusChanged(QMediaRecorder::Status))); - - connect(d->control, SIGNAL(mutedChanged(bool)), - this, SIGNAL(mutedChanged(bool))); - - connect(d->control, SIGNAL(volumeChanged(qreal)), - this, SIGNAL(volumeChanged(qreal))); - - connect(d->control, SIGNAL(durationChanged(qint64)), - this, SIGNAL(durationChanged(qint64))); - - connect(d->control, SIGNAL(actualLocationChanged(QUrl)), - this, SLOT(_q_updateActualLocation(QUrl))); - - connect(d->control, SIGNAL(error(int,QString)), - this, SLOT(_q_error(int,QString))); - - connect(service, SIGNAL(destroyed()), this, SLOT(_q_serviceDestroyed())); - - - d->applySettingsLater(); - - return true; - } - } + Setting the location can fail, for example when the service supports only + local file system locations but a network URL was passed. If the operation + fails an errorOccured() signal is emitted. - d->mediaObject = nullptr; - return false; - } + The location can be relative or empty. If empty the recorder uses the + system specific place and file naming scheme. - return true; -} + \sa errorOccurred() +*/ /*! \property QMediaRecorder::outputLocation \brief the destination location of media content. Setting the location can fail, for example when the service supports only - local file system locations but a network URL was passed. If the service - does not support media recording this setting the output location will - always fail. + local file system locations but a network URL was passed. If the operation + fails an errorOccured() signal is emitted. - The \a location can be relative or empty; - in this case the recorder uses the system specific place and file naming scheme. - After recording has stated, QMediaRecorder::outputLocation() returns the actual output location. + The output location can be relative or empty; in the latter case the recorder + uses the system specific place and file naming scheme. */ /*! - \property QMediaRecorder::actualLocation - \brief the actual location of the last media content. + \qmlproperty QUrl QtMultimedia::MediaRecorder::actualLocation + \brief The actual location of the last media content. The actual location is usually available after recording starts, and reset when new location is set or new recording starts. */ /*! - Returns true if media recorder service ready to use. + \property QMediaRecorder::actualLocation + \brief The actual location of the last media content. - \sa availabilityChanged() + The actual location is usually available after recording starts, + and reset when new location is set or new recording starts. */ -bool QMediaRecorder::isAvailable() const -{ - return availability() == QMultimedia::Available; -} /*! - Returns the availability of this functionality. - - \sa availabilityChanged() + Returns \c true if media recorder service ready to use. */ -QMultimedia::AvailabilityStatus QMediaRecorder::availability() const +bool QMediaRecorder::isAvailable() const { - if (d_func()->control == nullptr) - return QMultimedia::ServiceMissing; - - if (d_func()->availabilityControl) - return d_func()->availabilityControl->availability(); - - return QMultimedia::Available; + return d_func()->control && d_func()->captureSession; } QUrl QMediaRecorder::outputLocation() const @@ -467,41 +211,68 @@ QUrl QMediaRecorder::outputLocation() const return d_func()->control ? d_func()->control->outputLocation() : QUrl(); } -bool QMediaRecorder::setOutputLocation(const QUrl &location) +void QMediaRecorder::setOutputLocation(const QUrl &location) { Q_D(QMediaRecorder); - d->actualLocation.clear(); - return d->control ? d->control->setOutputLocation(location) : false; + if (!d->control) { + emit errorOccurred(QMediaRecorder::ResourceError, d->initErrorMessage); + return; + } + d->control->setOutputLocation(location); + d->control->clearActualLocation(); + if (!location.isEmpty() && !d->control->isLocationWritable(location)) + emit errorOccurred(QMediaRecorder::LocationNotWritable, tr("Output location not writable")); } -QUrl QMediaRecorder::actualLocation() const +/*! + Set the output IO device for media content. + + The \a device must have been opened in the \l{QIODevice::WriteOnly}{WriteOnly} or + \l{QIODevice::ReadWrite}{ReadWrite} modes before the recording starts. + + The media recorder doesn't take ownership of the specified \a device. + If the recording has been started, the device must be kept alive and open until + the signal \c recorderStateChanged(StoppedState) is emitted. + + \sa outputDevice() +*/ +void QMediaRecorder::setOutputDevice(QIODevice *device) { - return d_func()->actualLocation; + Q_D(QMediaRecorder); + d->control->setOutputDevice(device); } /*! - Returns the current media recorder state. + Returns the output IO device for media content. - \sa QMediaRecorder::State + \sa setOutputDevice() */ +QIODevice *QMediaRecorder::outputDevice() const +{ + Q_D(const QMediaRecorder); + return d->control->outputDevice(); +} -QMediaRecorder::State QMediaRecorder::state() const +QUrl QMediaRecorder::actualLocation() const { - return d_func()->control ? QMediaRecorder::State(d_func()->control->state()) : StoppedState; + Q_D(const QMediaRecorder); + return d->control ? d->control->actualLocation() : QUrl(); } /*! - Returns the current media recorder status. + Returns the current media recorder state. - \sa QMediaRecorder::Status + \sa QMediaRecorder::RecorderState */ -QMediaRecorder::Status QMediaRecorder::status() const +QMediaRecorder::RecorderState QMediaRecorder::recorderState() const { - return d_func()->control ? QMediaRecorder::Status(d_func()->control->status()) : UnavailableStatus; + return d_func()->control ? QMediaRecorder::RecorderState(d_func()->control->state()) : StoppedState; } /*! + \property QMediaRecorder::error + Returns the current error state. \sa errorString() @@ -509,10 +280,19 @@ QMediaRecorder::Status QMediaRecorder::status() const QMediaRecorder::Error QMediaRecorder::error() const { - return d_func()->error; + Q_D(const QMediaRecorder); + + return d->control ? d->control->error() : QMediaRecorder::ResourceError; } +/*! + \qmlproperty string QtMultimedia::MediaRecorder::errorString + \brief This property holds a string describing the current error state. + \sa error +*/ /*! + \property QMediaRecorder::errorString + Returns a string describing the current error state. \sa error() @@ -520,8 +300,15 @@ QMediaRecorder::Error QMediaRecorder::error() const QString QMediaRecorder::errorString() const { - return d_func()->errorString; + Q_D(const QMediaRecorder); + + return d->control ? d->control->errorString() : d->initErrorMessage; } +/*! + \qmlproperty qint64 QtMultimedia::MediaRecorder::duration + + \brief This property holds the recorded media duration in milliseconds. +*/ /*! \property QMediaRecorder::duration @@ -533,577 +320,634 @@ qint64 QMediaRecorder::duration() const { return d_func()->control ? d_func()->control->duration() : 0; } - /*! - \property QMediaRecorder::muted + \fn void QMediaRecorder::encoderSettingsChanged() - \brief whether a recording audio stream is muted. + Signals when the encoder settings change. */ +/*! + \qmlmethod QtMultimedia::MediaRecorder::record() + \brief Starts recording. -bool QMediaRecorder::isMuted() const -{ - return d_func()->control ? d_func()->control->isMuted() : 0; -} - -void QMediaRecorder::setMuted(bool muted) -{ - Q_D(QMediaRecorder); + While the recorder state is changed immediately to + \c MediaRecorder.RecordingState, recording may start asynchronously. - if (d->control) - d->control->setMuted(muted); -} + If recording fails, the error() signal is emitted with recorder state being + reset back to \c{QMediaRecorder.StoppedState}. + \note On mobile devices, recording will happen in the orientation the + device had when calling record and is locked for the duration of the recording. + To avoid artifacts on the user interface, we recommend to keep the user interface + locked to the same orientation as long as the recording is ongoing using + the contentOrientation property of the Window and unlock it again once the recording + is finished. +*/ /*! - \property QMediaRecorder::volume - - \brief the current recording audio volume. + Start recording. - The volume is scaled linearly from \c 0.0 (silence) to \c 1.0 (full volume). Values outside this - range will be clamped. + While the recorder state is changed immediately to + c\{QMediaRecorder::RecordingState}, recording may start asynchronously. - The default volume is \c 1.0. + If recording fails error() signal is emitted with recorder state being + reset back to \c{QMediaRecorder::StoppedState}. - UI volume controls should usually be scaled nonlinearly. For example, using a logarithmic scale - will produce linear changes in perceived loudness, which is what a user would normally expect - from a volume control. See QAudio::convertVolume() for more details. + \note On mobile devices, recording will happen in the orientation the + device had when calling record and is locked for the duration of the recording. + To avoid artifacts on the user interface, we recommend to keep the user interface + locked to the same orientation as long as the recording is ongoing using + the contentOrientation property of QWindow and unlock it again once the recording + is finished. */ -qreal QMediaRecorder::volume() const +void QMediaRecorder::record() { - return d_func()->control ? d_func()->control->volume() : 1.0; -} + Q_D(QMediaRecorder); + if (!d->control || !d->captureSession) + return; -void QMediaRecorder::setVolume(qreal volume) -{ - Q_D(QMediaRecorder); + if (d->control->state() == QMediaRecorder::PausedState) { + d->control->resume(); + } else { + auto oldMediaFormat = d->encoderSettings.mediaFormat(); + + auto platformSession = d->captureSession->platformSession(); + const bool hasVideo = platformSession && !platformSession->activeVideoSources().empty(); + + d->encoderSettings.resolveFormat(hasVideo ? QMediaFormat::RequiresVideo : QMediaFormat::NoFlags); + d->control->clearActualLocation(); + d->control->clearError(); + + auto settings = d->encoderSettings; + d->control->record(d->encoderSettings); - if (d->control) { - volume = qMax(qreal(0.0), volume); - d->control->setVolume(volume); + if (settings != d->encoderSettings) + emit encoderSettingsChanged(); + + if (oldMediaFormat != d->encoderSettings.mediaFormat()) + emit mediaFormatChanged(); } } +/*! + \qmlmethod QtMultimedia::MediaRecorder::pause() + \brief Pauses recording. + + The recorder state is changed to QMediaRecorder.PausedState. + Depending on the platform, pausing recording may be not supported. + In this case the recorder state is unchanged. +*/ /*! - Returns a list of supported container formats. + Pauses recording. + + The recorder state is changed to QMediaRecorder::PausedState. + + Depending on the platform, pausing recording may be not supported. + In this case the recorder state is unchanged. */ -QStringList QMediaRecorder::supportedContainers() const + +void QMediaRecorder::pause() { - return d_func()->formatControl ? - d_func()->formatControl->supportedContainers() : QStringList(); + Q_D(QMediaRecorder); + if (d->control && d->captureSession) + d->control->pause(); } - /*! - Returns a description of a container \a format. + \qmlmethod QtMultimedia::MediaRecorder::stop() + \brief Stops the recording. + + The recorder will stop the recording. Processing pending video and audio data might + however still take some time. The recording is finished, once the state of the media + recorder changes to QMediaRecorder::StoppedState. */ -QString QMediaRecorder::containerDescription(const QString &format) const -{ - return d_func()->formatControl ? - d_func()->formatControl->containerDescription(format) : QString(); -} /*! - Returns the selected container format. + The recorder will stop the recording. Processing pending video and audio data might + however still take some time. The recording is finished, once the state of the media + recorder changes to QMediaRecorder::StoppedState. */ - -QString QMediaRecorder::containerFormat() const +void QMediaRecorder::stop() { - return d_func()->formatControl ? - d_func()->formatControl->containerFormat() : QString(); + Q_D(QMediaRecorder); + if (d->control && d->captureSession) + d->control->stop(); } +/*! + \qmlproperty enumeration QtMultimedia::MediaRecorder::recorderState + \brief This property holds the current media recorder state. + The state property represents the user request and is changed synchronously + during record(), pause() or stop() calls. + RecorderSstate may also change asynchronously when recording fails. + + \value MediaRecorder.StoppedState The recorder is not active. + \value MediaRecorder.RecordingState The recording is requested. + \value MediaRecorder.PausedState The recorder is pause. +*/ /*! - Returns a list of supported audio codecs. + \enum QMediaRecorder::RecorderState + + \value StoppedState The recorder is not active. + \value RecordingState The recording is requested. + \value PausedState The recorder is paused. */ -QStringList QMediaRecorder::supportedAudioCodecs() const -{ - return d_func()->audioControl ? - d_func()->audioControl->supportedAudioCodecs() : QStringList(); -} +/*! + \qmlproperty enumeration QtMultimedia::MediaRecorder::error + \brief This property holds the current media recorder error state. + \value MediaRecorder.NoError Not in an error state. + \value MediaRecorder.ResourceError Not enough system resources + \value MediaRecorder.FormatError the current format is not supported. + \value MediaRecorder.OutOfSpaceError No space left on device. + \value MediaRecorder.LocationNotWriteable The output location is not writable. +*/ /*! - Returns a description of an audio \a codec. + \enum QMediaRecorder::Error + + \value NoError No Errors. + \value ResourceError Device is not ready or not available. + \value FormatError Current format is not supported. + \value OutOfSpaceError No space left on device. + \value LocationNotWritable The output location is not writable. */ -QString QMediaRecorder::audioCodecDescription(const QString &codec) const -{ - return d_func()->audioControl ? - d_func()->audioControl->codecDescription(codec) : QString(); -} /*! - Returns a list of supported audio sample rates. + \property QMediaRecorder::recorderState + \brief The current state of the media recorder. - If non null audio \a settings parameter is passed, the returned list is - reduced to sample rates supported with partial settings applied. + The state property represents the user request and is changed synchronously + during record(), pause() or stop() calls. + Recorder state may also change asynchronously when recording fails. +*/ - This can be used to query the list of sample rates, supported by specific - audio codec. +/*! + \qmlsignal QtMultimedia::MediaRecorder::recorderStateChanged(RecorderState state) + \brief Signals that a media recorder's \a state has changed. +*/ - If the encoder supports arbitrary sample rates within the supported rates - range, *\a continuous is set to true, otherwise *\a continuous is set to - false. +/*! + \fn QMediaRecorder::recorderStateChanged(QMediaRecorder::RecorderState state) + + Signals that a media recorder's \a state has changed. */ -QList<int> QMediaRecorder::supportedAudioSampleRates(const QAudioEncoderSettings &settings, bool *continuous) const -{ - if (continuous) - *continuous = false; +/*! + \qmlsignal QtMultimedia::MediaRecorder::durationChanged(qint64 duration) + \brief Signals that the \a duration of the recorded media has changed. +*/ - return d_func()->audioControl ? - d_func()->audioControl->supportedSampleRates(settings, continuous) : QList<int>(); -} +/*! + \fn QMediaRecorder::durationChanged(qint64 duration) + Signals that the \a duration of the recorded media has changed. +*/ /*! - Returns a list of resolutions video can be encoded at. + \qmlsignal QtMultimedia::MediaRecorder::actualLocationChanged(const QUrl &location) + \brief Signals that the actual \a location of the recorded media has changed. - If non null video \a settings parameter is passed, the returned list is - reduced to resolution supported with partial settings like video codec or - framerate applied. + This signal is usually emitted when recording starts. +*/ +/*! + \fn QMediaRecorder::actualLocationChanged(const QUrl &location) - If the encoder supports arbitrary resolutions within the supported range, - *\a continuous is set to true, otherwise *\a continuous is set to false. + Signals that the actual \a location of the recorded media has changed. + This signal is usually emitted when recording starts. +*/ +/*! + \qmlsignal QtMultimedia::MediaRecorder::errorOccurred(Error error, const QString &errorString) + \brief Signals that an \a error has occurred. - \sa QVideoEncoderSettings::resolution() + The \a errorString contains a description of the error. */ -QList<QSize> QMediaRecorder::supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous) const -{ - if (continuous) - *continuous = false; +/*! + \fn QMediaRecorder::errorOccurred(QMediaRecorder::Error error, const QString &errorString) - return d_func()->videoControl ? - d_func()->videoControl->supportedResolutions(settings, continuous) : QList<QSize>(); -} + Signals that an \a error has occurred, with \a errorString containing + a description of the error. +*/ /*! - Returns a list of frame rates video can be encoded at. + \qmlproperty mediaMetaData QtMultimedia::MediaRecorder::metaData - If non null video \a settings parameter is passed, the returned list is - reduced to frame rates supported with partial settings like video codec or - resolution applied. + \brief This property holds meta data associated with the recording. - If the encoder supports arbitrary frame rates within the supported range, - *\a continuous is set to true, otherwise *\a continuous is set to false. + When a recording is started, any meta-data assigned will be attached to that + recording. - \sa QVideoEncoderSettings::frameRate() -*/ -QList<qreal> QMediaRecorder::supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous) const -{ - if (continuous) - *continuous = false; + \note Ensure that meta-data is assigned correctly by assigning it before + starting the recording. - return d_func()->videoControl ? - d_func()->videoControl->supportedFrameRates(settings, continuous) : QList<qreal>(); -} + \sa mediaMetaData +*/ /*! - Returns a list of supported video codecs. + \property QMediaRecorder::metaData + + Returns the metaData associated with the recording. */ -QStringList QMediaRecorder::supportedVideoCodecs() const +QMediaMetaData QMediaRecorder::metaData() const { - return d_func()->videoControl ? - d_func()->videoControl->supportedVideoCodecs() : QStringList(); + Q_D(const QMediaRecorder); + + return d->control ? d->control->metaData() : QMediaMetaData{}; } /*! - Returns a description of a video \a codec. + Sets the meta data to \a metaData. - \sa setEncodingSettings() + \note To ensure that meta-data is set correctly, it should be set before starting the recording. + Once the recording is started, any meta-data set will be attached to the next recording. */ -QString QMediaRecorder::videoCodecDescription(const QString &codec) const +void QMediaRecorder::setMetaData(const QMediaMetaData &metaData) { - return d_func()->videoControl ? - d_func()->videoControl->videoCodecDescription(codec) : QString(); + Q_D(QMediaRecorder); + + if (d->control && d->captureSession) + d->control->setMetaData(metaData); } /*! - Returns the audio encoder settings being used. - - \sa setEncodingSettings() + Adds \a metaData to the recorded media. */ - -QAudioEncoderSettings QMediaRecorder::audioSettings() const +void QMediaRecorder::addMetaData(const QMediaMetaData &metaData) { - return d_func()->audioControl ? - d_func()->audioControl->audioSettings() : QAudioEncoderSettings(); + auto data = this->metaData(); + // merge data + for (const auto &k : metaData.keys()) + data.insert(k, metaData.value(k)); + setMetaData(data); } +/*! + \qmlsignal QtMultimedia::MediaRecorder::metaDataChanged() + + \brief Signals that a media object's meta-data has changed. + If multiple meta-data elements are changed metaDataChanged() is emitted + once. +*/ /*! - Returns the video encoder settings being used. + \fn QMediaRecorder::metaDataChanged() + + Signals that a media object's meta-data has changed. - \sa setEncodingSettings() + If multiple meta-data elements are changed metaDataChanged() is emitted + once. */ -QVideoEncoderSettings QMediaRecorder::videoSettings() const +/*! + Returns the media capture session. +*/ +QMediaCaptureSession *QMediaRecorder::captureSession() const { - return d_func()->videoControl ? - d_func()->videoControl->videoSettings() : QVideoEncoderSettings(); + Q_D(const QMediaRecorder); + return d->captureSession; } - /*! - Sets the audio encoder \a settings. + \qmlproperty enumeration QtMultimedia::MediaRecorder::quality - If some parameters are not specified, or null settings are passed, the - encoder will choose default encoding parameters, depending on media - source properties. + Enumerates quality encoding levels. - It's only possible to change settings when the encoder is in the - QMediaEncoder::StoppedState state. + \value MediaRecorder.VeryLowQuality + \value MediaRecorder.LowQuality + \value MediaRecorder.NormalQuality + \value MediaRecorder.HighQuality + \value MediaRecorder.VeryHighQuality +*/ +/*! + \enum QMediaRecorder::Quality + + Enumerates quality encoding levels. - \sa audioSettings(), videoSettings(), containerFormat() + \value VeryLowQuality + \value LowQuality + \value NormalQuality + \value HighQuality + \value VeryHighQuality */ -void QMediaRecorder::setAudioSettings(const QAudioEncoderSettings &settings) -{ - Q_D(QMediaRecorder); +/*! + \enum QMediaRecorder::EncodingMode - //restart camera if it can't apply new settings in the Active state - d->restartCamera(); + Enumerates encoding modes. - if (d->audioControl) { - d->audioControl->setAudioSettings(settings); - d->applySettingsLater(); - } -} + \value ConstantQualityEncoding Encoding will aim to have a constant quality, adjusting bitrate to fit. + \value ConstantBitRateEncoding Encoding will use a constant bit rate, adjust quality to fit. + \value AverageBitRateEncoding Encoding will try to keep an average bitrate setting, but will use + more or less as needed. + \value TwoPassEncoding The media will first be processed to determine the characteristics, + and then processed a second time allocating more bits to the areas + that need it. +*/ /*! - Sets the video encoder \a settings. - If some parameters are not specified, or null settings are passed, the - encoder will choose default encoding parameters, depending on media - source properties. + \qmlproperty MediaFormat QtMultimedia::MediaRecorder::mediaFormat - It's only possible to change settings when the encoder is in the - QMediaEncoder::StoppedState state. + \brief This property holds the current MediaFormat of the recorder. +*/ +/*! + \property QMediaRecorder::mediaFormat - \sa audioSettings(), videoSettings(), containerFormat() + Returns the recording media format. */ +QMediaFormat QMediaRecorder::mediaFormat() const +{ + Q_D(const QMediaRecorder); + return d->encoderSettings.mediaFormat(); +} -void QMediaRecorder::setVideoSettings(const QVideoEncoderSettings &settings) +void QMediaRecorder::setMediaFormat(const QMediaFormat &format) { Q_D(QMediaRecorder); - - d->restartCamera(); - - if (d->videoControl) { - d->videoControl->setVideoSettings(settings); - d->applySettingsLater(); - } + if (d->encoderSettings.mediaFormat() == format) + return; + d->encoderSettings.setMediaFormat(format); + emit mediaFormatChanged(); } /*! - Sets the media \a container format. - If the container format is not specified, the - encoder will choose format, depending on media source properties - and encoding settings selected. + \qmlproperty enumeration QtMultimedia::MediaRecorder::encodingMode + \since 6.6 + \brief This property holds the encoding mode. + \sa QMediaRecorder::EncodingMode +*/ - It's only possible to change settings when the encoder is in the - QMediaEncoder::StoppedState state. +/*! + Returns the encoding mode. - \sa audioSettings(), videoSettings(), containerFormat() + \sa EncodingMode */ - -void QMediaRecorder::setContainerFormat(const QString &container) +QMediaRecorder::EncodingMode QMediaRecorder::encodingMode() const { - Q_D(QMediaRecorder); - - d->restartCamera(); - - if (d->formatControl) { - d->formatControl->setContainerFormat(container); - d->applySettingsLater(); - } + Q_D(const QMediaRecorder); + return d->encoderSettings.encodingMode(); } /*! - Sets the \a audio and \a video encoder settings and \a container format. + \fn void QMediaRecorder::encodingModeChanged() - If some parameters are not specified, or null settings are passed, the - encoder will choose default encoding parameters, depending on media - source properties. + Signals when the encoding mode changes. +*/ +/*! + Sets the encoding \a mode setting. - It's only possible to change settings when the encoder is in the - QMediaEncoder::StoppedState state. + If ConstantQualityEncoding is set, the quality + encoding parameter is used and bit rates are ignored, + otherwise the bitrates are used. - \sa audioSettings(), videoSettings(), containerFormat() + \sa encodingMode(), EncodingMode */ - -void QMediaRecorder::setEncodingSettings(const QAudioEncoderSettings &audio, - const QVideoEncoderSettings &video, - const QString &container) +void QMediaRecorder::setEncodingMode(EncodingMode mode) { Q_D(QMediaRecorder); - - d->restartCamera(); - - if (d->audioControl) - d->audioControl->setAudioSettings(audio); - - if (d->videoControl) - d->videoControl->setVideoSettings(video); - - if (d->formatControl) - d->formatControl->setContainerFormat(container); - - d->applySettingsLater(); + if (d->encoderSettings.encodingMode() == mode) + return; + d->encoderSettings.setEncodingMode(mode); + emit encodingModeChanged(); } /*! - Start recording. + \property QMediaRecorder::quality - While the recorder state is changed immediately to QMediaRecorder::RecordingState, - recording may start asynchronously, with statusChanged(QMediaRecorder::RecordingStatus) - signal emitted when recording starts. - - If recording fails error() signal is emitted - with recorder state being reset back to QMediaRecorder::StoppedState. + Returns the recording quality. */ - -void QMediaRecorder::record() +QMediaRecorder::Quality QMediaRecorder::quality() const { - Q_D(QMediaRecorder); - - d->actualLocation.clear(); - - if (d->settingsChanged) - d->_q_applySettings(); - - // reset error - d->error = NoError; - d->errorString = QString(); - - if (d->control) - d->control->setState(RecordingState); + Q_D(const QMediaRecorder); + return d->encoderSettings.quality(); } /*! - Pause recording. + \fn void QMediaRecorder::qualityChanged() - The recorder state is changed to QMediaRecorder::PausedState. - - Depending on platform recording pause may be not supported, - in this case the recorder state stays unchanged. + Signals when the recording quality changes. */ - -void QMediaRecorder::pause() +void QMediaRecorder::setQuality(Quality quality) { Q_D(QMediaRecorder); - if (d->control) - d->control->setState(PausedState); + if (d->encoderSettings.quality() == quality) + return; + d->encoderSettings.setQuality(quality); + emit qualityChanged(); } /*! - Stop recording. + \qmlproperty Size QtMultimedia::MediaRecorder::videoResolution + \since 6.6 + \brief This property holds the resolution of the encoded video. - The recorder state is changed to QMediaRecorder::StoppedState. + Set an empty Size to make the recorder choose an optimal resolution based + on what is available from the video source and the limitations of the codec. */ -void QMediaRecorder::stop() + +/*! + Returns the resolution of the encoded video. +*/ +QSize QMediaRecorder::videoResolution() const { - Q_D(QMediaRecorder); - if (d->control) - d->control->setState(StoppedState); + Q_D(const QMediaRecorder); + return d->encoderSettings.videoResolution(); } /*! - \enum QMediaRecorder::State + \fn void QMediaRecorder::videoResolutionChanged() - \value StoppedState The recorder is not active. - If this is the state after recording then the actual created recording has - finished being written to the final location and is ready on all platforms - except on Android. On Android, due to platform limitations, there is no way - to be certain that the recording has finished writing to the final location. - \value RecordingState The recording is requested. - \value PausedState The recorder is paused. + Signals when the video recording resolution changes. */ - /*! - \enum QMediaRecorder::Status + Sets the resolution of the encoded video to \a{size}. - \value UnavailableStatus - The recorder is not available or not supported by connected media object. - \value UnloadedStatus - The recorder is avilable but not loaded. - \value LoadingStatus - The recorder is initializing. - \value LoadedStatus - The recorder is initialized and ready to record media. - \value StartingStatus - Recording is requested but not active yet. - \value RecordingStatus - Recording is active. - \value PausedStatus - Recording is paused. - \value FinalizingStatus - Recording is stopped with media being finalized. + Pass an empty QSize to make the recorder choose an optimal resolution based + on what is available from the video source and the limitations of the codec. */ +void QMediaRecorder::setVideoResolution(const QSize &size) +{ + Q_D(QMediaRecorder); + if (d->encoderSettings.videoResolution() == size) + return; + d->encoderSettings.setVideoResolution(size); + emit videoResolutionChanged(); +} -/*! - \enum QMediaRecorder::Error +/*! \fn void QMediaRecorder::setVideoResolution(int width, int height) - \value NoError No Errors. - \value ResourceError Device is not ready or not available. - \value FormatError Current format is not supported. - \value OutOfSpaceError No space left on device. + Sets the \a width and \a height of the resolution of the encoded video. + + \overload */ /*! - \property QMediaRecorder::state - \brief The current state of the media recorder. + \qmlproperty real QtMultimedia::MediaRecorder::videoFrameRate + \since 6.6 + \brief This property holds the video frame rate. - The state property represents the user request and is changed synchronously - during record(), pause() or stop() calls. - Recorder state may also change asynchronously when recording fails. + A value of 0 indicates the recorder should make an optimal choice based on what is available + from the video source and the limitations of the codec. */ /*! - \property QMediaRecorder::status - \brief The current status of the media recorder. - - The status is changed asynchronously and represents the actual status - of media recorder. + Returns the video frame rate. */ +qreal QMediaRecorder::videoFrameRate() const +{ + Q_D(const QMediaRecorder); + return d->encoderSettings.videoFrameRate(); +} /*! - \fn QMediaRecorder::stateChanged(State state) + \fn void QMediaRecorder::videoFrameRateChanged() - Signals that a media recorder's \a state has changed. + Signals when the recording video frame rate changes. */ - /*! - \fn QMediaRecorder::durationChanged(qint64 duration) + Sets the video \a frameRate. - Signals that the \a duration of the recorded media has changed. + A value of 0 indicates the recorder should make an optimal choice based on what is available + from the video source and the limitations of the codec. */ +void QMediaRecorder::setVideoFrameRate(qreal frameRate) +{ + Q_D(QMediaRecorder); + if (d->encoderSettings.videoFrameRate() == frameRate) + return; + d->encoderSettings.setVideoFrameRate(frameRate); + emit videoFrameRateChanged(); +} /*! - \fn QMediaRecorder::actualLocationChanged(const QUrl &location) - - Signals that the actual \a location of the recorded media has changed. - This signal is usually emitted when recording starts. + \qmlproperty int QtMultimedia::MediaRecorder::videoBitRate + \since 6.6 + \brief This property holds the bit rate of the compressed video stream in bits per second. */ /*! - \fn QMediaRecorder::error(QMediaRecorder::Error error) - - Signals that an \a error has occurred. + Returns the bit rate of the compressed video stream in bits per second. */ +int QMediaRecorder::videoBitRate() const +{ + Q_D(const QMediaRecorder); + return d->encoderSettings.videoBitRate(); +} /*! - \fn QMediaRecorder::availabilityChanged(bool available) + \fn void QMediaRecorder::videoBitRateChanged() - Signals that the media recorder is now available (if \a available is true), or not. + Signals when the recording video bit rate changes. */ - /*! - \fn QMediaRecorder::availabilityChanged(QMultimedia::AvailabilityStatus availability) - - Signals that the service availability has changed to \a availability. + Sets the video \a bitRate in bits per second. */ +void QMediaRecorder::setVideoBitRate(int bitRate) +{ + Q_D(QMediaRecorder); + if (d->encoderSettings.videoBitRate() == bitRate) + return; + d->encoderSettings.setVideoBitRate(bitRate); + emit videoBitRateChanged(); +} /*! - \fn QMediaRecorder::mutedChanged(bool muted) - - Signals that the \a muted state has changed. If true the recording is being muted. + \qmlproperty int QtMultimedia::MediaRecorder::audioBitRate + \since 6.6 + \brief This property holds the bit rate of the compressed audio stream in bits per second. */ /*! - \property QMediaRecorder::metaDataAvailable - \brief whether access to a media object's meta-data is available. - - If this is true there is meta-data available, otherwise there is no meta-data available. + Returns the bit rate of the compressed audio stream in bits per second. */ - -bool QMediaRecorder::isMetaDataAvailable() const +int QMediaRecorder::audioBitRate() const { Q_D(const QMediaRecorder); - - return d->metaDataControl - ? d->metaDataControl->isMetaDataAvailable() - : false; + return d->encoderSettings.audioBitRate(); } /*! - \fn QMediaRecorder::metaDataAvailableChanged(bool available) + \fn void QMediaRecorder::audioBitRateChanged() - Signals that the \a available state of a media object's meta-data has changed. + Signals when the recording audio bit rate changes. */ - /*! - \property QMediaRecorder::metaDataWritable - \brief whether a media object's meta-data is writable. - - If this is true the meta-data is writable, otherwise the meta-data is read-only. + Sets the audio \a bitRate in bits per second. */ - -bool QMediaRecorder::isMetaDataWritable() const +void QMediaRecorder::setAudioBitRate(int bitRate) { - Q_D(const QMediaRecorder); - - return d->metaDataControl - ? d->metaDataControl->isWritable() - : false; + Q_D(QMediaRecorder); + if (d->encoderSettings.audioBitRate() == bitRate) + return; + d->encoderSettings.setAudioBitRate(bitRate); + emit audioBitRateChanged(); } /*! - \fn QMediaRecorder::metaDataWritableChanged(bool writable) - - Signals that the \a writable state of a media object's meta-data has changed. + \qmlproperty int QtMultimedia::MediaRecorder::audioChannelCount + \since 6.6 + \brief This property holds the number of audio channels. */ /*! - Returns the value associated with a meta-data \a key. + Returns the number of audio channels. */ -QVariant QMediaRecorder::metaData(const QString &key) const +int QMediaRecorder::audioChannelCount() const { Q_D(const QMediaRecorder); - - return d->metaDataControl - ? d->metaDataControl->metaData(key) - : QVariant(); + return d->encoderSettings.audioChannelCount(); } /*! - Sets a \a value for a meta-data \a key. + \fn void QMediaRecorder::audioChannelCountChanged() - \note To ensure that meta data is set corretly, it should be set before starting the recording. - Once the recording is stopped, any meta data set will be attached to the next recording. + Signals when the recording audio channel count changes. */ -void QMediaRecorder::setMetaData(const QString &key, const QVariant &value) +/*! + Sets the number of audio \a channels. + + A value of -1 indicates the recorder should make an optimal choice based on + what is available from the audio source and the limitations of the codec. +*/ +void QMediaRecorder::setAudioChannelCount(int channels) { Q_D(QMediaRecorder); - - if (d->metaDataControl) - d->metaDataControl->setMetaData(key, value); + if (d->encoderSettings.audioChannelCount() == channels) + return; + d->encoderSettings.setAudioChannelCount(channels); + emit audioChannelCountChanged(); } /*! - Returns a list of keys there is meta-data available for. + \qmlproperty int QtMultimedia::MediaRecorder::audioSampleRate + \since 6.6 + \brief This property holds the audio sample rate in Hz. +*/ + +/*! + Returns the audio sample rate in Hz. */ -QStringList QMediaRecorder::availableMetaData() const +int QMediaRecorder::audioSampleRate() const { Q_D(const QMediaRecorder); - - return d->metaDataControl - ? d->metaDataControl->availableMetaData() - : QStringList(); + return d->encoderSettings.audioSampleRate(); } - /*! - \fn QMediaRecorder::metaDataChanged() + \fn void QMediaRecorder::audioSampleRateChanged() - Signals that a media object's meta-data has changed. - - If multiple meta-data elements are changed, - metaDataChanged(const QString &key, const QVariant &value) signal is emitted - for each of them with metaDataChanged() changed emitted once. + Signals when the recording audio sample rate changes. */ - /*! - \fn QMediaRecorder::metaDataChanged(const QString &key, const QVariant &value) + Sets the audio \a sampleRate in Hz. - Signal the changes of one meta-data element \a value with the given \a key. + A value of \c -1 indicates the recorder should make an optimal choice based + on what is available from the audio source, and the limitations of the codec. */ +void QMediaRecorder::setAudioSampleRate(int sampleRate) +{ + Q_D(QMediaRecorder); + if (d->encoderSettings.audioSampleRate() == sampleRate) + return; + d->encoderSettings.setAudioSampleRate(sampleRate); + emit audioSampleRateChanged(); +} QT_END_NAMESPACE |