Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qmediarecorder.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#include <private/qplatformmediarecorder_p.h>
7#include <qaudiodevice.h>
8#include <qcamera.h>
9#include <qscreencapture.h>
10#include <qwindowcapture.h>
11#include <qmediacapturesession.h>
12#include <private/qplatformcamera_p.h>
13#include <private/qplatformsurfacecapture_p.h>
14#include <private/qplatformmediaintegration_p.h>
15#include <private/qplatformmediacapture_p.h>
16
17#include <QtCore/qdebug.h>
18#include <QtCore/qurl.h>
19#include <QtCore/qstringlist.h>
20#include <QtCore/qmetaobject.h>
21#include <QtCore/qtimer.h>
22
23#include <qaudioformat.h>
24
25QT_BEGIN_NAMESPACE
26
27/*!
28 \class QMediaRecorder
29 \inmodule QtMultimedia
30 \ingroup multimedia
31 \ingroup multimedia_recording
32 \ingroup multimedia_video
33 \ingroup multimedia_audio
34
35 \brief The QMediaRecorder class is used for encoding and recording a capture session.
36
37 Use the QMediaRecorder class to encode and record media generated in
38 \l QMediaCaptureSession. You can generate:
39 \list
40 \li Audio. Use \l QAudioInput or \l QAudioBufferInput.
41 \li Video. Use \l QCamera, \l QScreenCapture, \l QWindowCapture, or \l QVideoFrameInput.
42 \endlist
43
44 To record media, connect a generator to a corresponding media capture session.
45
46 Performance of video encoding and recording is limited by the hardware,
47 the operating system, the installed graphic drivers, and the input video format.
48 If \c QCamera, \c QScreenCapture, or \c QWindowCapture produces video frames
49 faster than \c QMediaRecorder can encode and record them, the recorder
50 may drop some frames. This is likely to occur if the input frame resolution
51 is high, 4K for example, and hardware-accelerated encoding is unavailable.
52 If you generate input video via \c QVideoFrameInput, the method
53 \c QVideoFrameInput::sendVideoFrame will do nothing and return \c false
54 whenever this limitation is reached and the internal frame queue is full.
55 Rely on the signal \c QVideoFrameInput::readyToSendVideoFrame to know
56 when the recorder is ready to receive new frames again.
57 If you cannot change the rate of video frame generation and dropping frames
58 is undesirable, we recommend implementing your own frame queue on top of
59 \c QVideoFrameInput, considering the memory limitations of the hardware.
60
61 \snippet multimedia-snippets/media.cpp Media recorder
62*/
63/*!
64 \qmltype MediaRecorder
65 \nativetype QMediaRecorder
66 \brief For encoding and recording media generated in a CaptureSession.
67
68 \inqmlmodule QtMultimedia
69 \ingroup multimedia_qml
70 \ingroup multimedia_audio_qml
71 \ingroup multimedia_video_qml
72
73 Use the MediaRecorder element within a CaptureSession to encode and record:
74 \list
75 \li Audio captured from an audio interface (like microphone or line input).
76 \li Video captured from camera, screen, or an application window.
77 \endlist
78
79 Performance of video encoding and recording is limited by the hardware,
80 the operating system, the installed graphic drivers, and the input video format.
81 If \c Camera, \c ScreenCapture, or \c WindowCapture produces video frames
82 faster than \c MediaRecorder can encode and record them, the recorder
83 may drop some frames. This is likely to occur if the input frame resolution
84 is high, 4K for example, and hardware-accelerated encoding is unavailable.
85
86 \since 6.2
87 The code below shows a simple capture session containing a MediaRecorder using the default
88 camera and default audio input.
89
90\qml
91 CaptureSession {
92 id: captureSession
93 camera: Camera {
94 id: camera
95 active: true
96 }
97 audioInput: AudioInput {}
98 recorder: MediaRecorder {
99 id: recorder
100 }
101 }
102\endqml
103
104 The code below shows how the recording can be started and stopped.
105\qml
106 CameraButton {
107 text: "Record"
108 visible: recorder.recorderState !== MediaRecorder.RecordingState
109 onClicked: recorder.record()
110 }
111
112 CameraButton {
113 id: stopButton
114 text: "Stop"
115 visible: recorder.recorderState === MediaRecorder.RecordingState
116 onClicked: recorder.stop()
117 }
118\endqml
119
120 \sa CaptureSession, Camera, ScreenCapture, WindowCapture, AudioInput, ImageCapture
121*/
122QMediaRecorderPrivate::QMediaRecorderPrivate()
123{
124#if QT_CONFIG(mimetype)
125 // Force an early initialization of the mime database
126 // to avoid a delay when recording for the first time.
127 encoderSettings.mimeType();
128#endif
129}
130
131QString QMediaRecorderPrivate::msgFailedStartRecording()
132{
133 return QMediaRecorder::tr("Failed to start recording");
134}
135
136/*!
137 Constructs a media recorder.
138 The media recorder is a child of \a{parent}.
139*/
140
141QMediaRecorder::QMediaRecorder(QObject *parent)
142 : QObject(parent),
143 d_ptr(new QMediaRecorderPrivate)
144{
145 Q_D(QMediaRecorder);
146
147 auto &mediaIntegration = *QPlatformMediaIntegration::instance();
148
149 d->q_ptr = this;
150 auto maybeControl = mediaIntegration.createRecorder(this);
151 if (maybeControl) {
152 // The first format info initialization may take some time,
153 // for users it seems to be more suitable to have a delay on the object construction
154 // rather than on QMediaRecorder::record
155 mediaIntegration.formatInfo();
156
157 d->control = maybeControl.value();
158 } else {
159 d->initErrorMessage = maybeControl.error();
160 qWarning() << "Failed to initialize QMediaRecorder" << maybeControl.error();
161 }
162}
163
164/*!
165 Destroys a media recorder object.
166*/
167
168QMediaRecorder::~QMediaRecorder()
169{
170 if (d_ptr->captureSession)
171 d_ptr->captureSession->setRecorder(nullptr);
172 delete d_ptr->control;
173 delete d_ptr;
174}
175
176/*!
177 \internal
178*/
179QPlatformMediaRecorder *QMediaRecorder::platformRecoder() const
180{
181 return d_ptr->control;
182}
183
184/*!
185 \internal
186*/
187void QMediaRecorder::setCaptureSession(QMediaCaptureSession *session)
188{
189 Q_D(QMediaRecorder);
190 d->captureSession = session;
191}
192/*!
193 \qmlproperty url QtMultimedia::MediaRecorder::outputLocation
194 \brief The destination location of media content.
195
196 Setting the location can fail, for example when the service supports only
197 local file system locations but a network URL was passed. If the operation
198 fails, the \l errorOccurred() signal is emitted.
199
200 The output location can be empty, a directory, or a file. The path to a
201 directory or file can be relative or absolute. The \l record() method
202 generates the actual location according to the specified output location and
203 system-specific settings. Refer to the \l actualLocation property description
204 for details.
205
206 \sa actualLocation, errorOccurred()
207*/
208
209/*!
210 \property QMediaRecorder::outputLocation
211 \brief The destination location of media content.
212
213 Setting the location can fail, for example when the service supports only
214 local file system locations but a network URL was passed. If the operation
215 fails, the \l errorOccurred() signal is emitted.
216
217 The output location is ignored if a writable \l outputDevice
218 has been assigned to the recorder.
219 This behavior may change in the future, so we recommend setting only one output,
220 either \c outputLocation or \c outputDevice.
221
222 The output location can be empty, a directory, or a file. The path to a
223 directory or file can be relative or absolute. The \l record() method
224 generates the actual location according to the specified output location and
225 system-specific settings. Refer to the \l actualLocation property description
226 for details.
227
228 \sa actualLocation, outputDevice()
229*/
230
231/*!
232 \qmlproperty url QtMultimedia::MediaRecorder::actualLocation
233 \brief The actual location of the last media content.
234
235 The actual location is reset when a new \l outputLocation is assigned.
236 When \l record() is invoked, the recorder generates the actual location
237 basing on the following rules.
238 \list
239 \li If \c outputLocation is empty, a directory, or a file
240 without an extension, the recorder generates the appropriate extension
241 based on the selected media format and system MIME types.
242 \li If \c outputLocation is a directory, the recorder generates a new file
243 name within it.
244 \li If \c outputLocation is empty, the recorder generates a new file name in
245 the system-specific directory for audio or video.
246 \li The recorder generates the actual location before
247 emitting \c recorderStateChanged(RecordingState).
248 \endlist
249*/
250
251/*!
252 \property QMediaRecorder::actualLocation
253 \brief The actual location of the last media content.
254
255 The actual location is reset when a new \l outputLocation
256 or a non-null \l outputDevice is assigned.
257 When \l record() is invoked and \c outputDevice is \c null or not writable,
258 the recorder generates the actual location basing on the following rules.
259 \list
260 \li If \c outputLocation is empty, a directory, or a file
261 without an extension, the recorder generates the appropriate extension
262 based on the selected media format and system MIME types.
263 \li If \c outputLocation is a directory, the recorder generates a new file
264 name within it.
265 \li If \c outputLocation is empty, the recorder generates a new file name in
266 the system-specific directory for audio or video.
267 \li The recorder generates the actual location before
268 emitting \c recorderStateChanged(RecordingState).
269 \endlist
270*/
271
272/*!
273 Returns \c true if media recorder service ready to use.
274*/
275bool QMediaRecorder::isAvailable() const
276{
277 return d_func()->control && d_func()->captureSession;
278}
279
280QUrl QMediaRecorder::outputLocation() const
281{
282 return d_func()->control ? d_func()->control->outputLocation() : QUrl();
283}
284
285void QMediaRecorder::setOutputLocation(const QUrl &location)
286{
287 Q_D(QMediaRecorder);
288 if (!d->control) {
289 emit errorOccurred(QMediaRecorder::ResourceError, d->initErrorMessage);
290 return;
291 }
292 d->control->setOutputLocation(location);
293 d->control->clearActualLocation();
294 if (!location.isEmpty() && !d->control->isLocationWritable(location))
295 emit errorOccurred(QMediaRecorder::LocationNotWritable,
296 QStringLiteral("Output location not writable"));
297}
298
299/*!
300 Set the output IO device for media content.
301
302 The \a device must have been opened in the \l{QIODevice::WriteOnly}{WriteOnly} or
303 \l{QIODevice::ReadWrite}{ReadWrite} modes before the recording starts.
304
305 The media recorder doesn't take ownership of the specified \a device.
306 If the recording has been started, the device must be kept alive and open until
307 the signal \c recorderStateChanged(StoppedState) is emitted.
308
309 This method resets \l actualLocation immediately unless
310 the specified \a device is \c null.
311
312 If a writable output device is assigned to the recorder, \l outputLocation
313 is ignored, and \l actualLocation is not generated when recording starts.
314 This behavior may change in the future, so we recommend setting only
315 one output, either \c outputLocation or \c outputDevice.
316
317 \c QMediaRecorder::setOutputDevice is only supported with the FFmpeg backend.
318
319 \sa outputDevice(), outputLocation
320*/
321void QMediaRecorder::setOutputDevice(QIODevice *device)
322{
323 Q_D(QMediaRecorder);
324 if (!d->control) {
325 emit errorOccurred(QMediaRecorder::ResourceError, d->initErrorMessage);
326 return;
327 }
328
329 d->control->setOutputDevice(device);
330
331 if (device)
332 d->control->clearActualLocation();
333}
334
335/*!
336 Returns the output IO device for media content.
337
338 \sa setOutputDevice()
339*/
340QIODevice *QMediaRecorder::outputDevice() const
341{
342 Q_D(const QMediaRecorder);
343 return d->control ? d->control->outputDevice() : nullptr;
344}
345
346QUrl QMediaRecorder::actualLocation() const
347{
348 Q_D(const QMediaRecorder);
349 return d->control ? d->control->actualLocation() : QUrl();
350}
351
352/*!
353 Returns the current media recorder state.
354
355 \sa QMediaRecorder::RecorderState
356*/
357
358QMediaRecorder::RecorderState QMediaRecorder::recorderState() const
359{
360 return d_func()->control ? QMediaRecorder::RecorderState(d_func()->control->state()) : StoppedState;
361}
362
363/*!
364 \property QMediaRecorder::error
365
366 Returns the current error state.
367
368 \sa errorString()
369*/
370
371QMediaRecorder::Error QMediaRecorder::error() const
372{
373 Q_D(const QMediaRecorder);
374
375 return d->control ? d->control->error() : QMediaRecorder::ResourceError;
376}
377/*!
378 \qmlproperty string QtMultimedia::MediaRecorder::errorString
379 \brief This property holds a string describing the current error state.
380
381 \sa error
382*/
383/*!
384 \property QMediaRecorder::errorString
385
386 Returns a string describing the current error state.
387
388 \sa error()
389*/
390
391QString QMediaRecorder::errorString() const
392{
393 Q_D(const QMediaRecorder);
394
395 return d->control ? d->control->errorString() : d->initErrorMessage;
396}
397/*!
398 \qmlproperty qint64 QtMultimedia::MediaRecorder::duration
399
400 \brief This property holds the recorded media duration in milliseconds.
401*/
402
403/*!
404 \property QMediaRecorder::duration
405
406 \brief the recorded media duration in milliseconds.
407*/
408
409qint64 QMediaRecorder::duration() const
410{
411 return d_func()->control ? d_func()->control->duration() : 0;
412}
413
414#if QT_DEPRECATED_SINCE(6, 9)
415/*!
416 \fn void QMediaRecorder::encoderSettingsChanged()
417 \deprecated [6.9] Use specific signals instead.
418
419 Signals when the encoder settings change.
420*/
421#endif
422
423/*!
424 \qmlmethod QtMultimedia::MediaRecorder::record()
425 \brief Starts recording.
426
427 While the recorder state is changed immediately to
428 \c MediaRecorder.RecordingState, recording may start asynchronously.
429
430 If recording fails, the error() signal is emitted with recorder state being
431 reset back to \c{QMediaRecorder.StoppedState}.
432
433 This method updates \l actualLocation according to its generation rules.
434
435 \note On mobile devices, recording will happen in the orientation the
436 device had when calling record and is locked for the duration of the recording.
437 To avoid artifacts on the user interface, we recommend to keep the user interface
438 locked to the same orientation as long as the recording is ongoing using
439 the contentOrientation property of the Window and unlock it again once the recording
440 is finished.
441*/
442/*!
443 Starts recording.
444
445 While the recorder state is changed immediately to
446 c\{QMediaRecorder::RecordingState}, recording may start asynchronously.
447
448 If recording fails error() signal is emitted with recorder state being
449 reset back to \c{QMediaRecorder::StoppedState}.
450
451 This method updates \l actualLocation according to its generation rules.
452
453 \note On mobile devices, recording will happen in the orientation the
454 device had when calling record and is locked for the duration of the recording.
455 To avoid artifacts on the user interface, we recommend to keep the user interface
456 locked to the same orientation as long as the recording is ongoing using
457 the contentOrientation property of QWindow and unlock it again once the recording
458 is finished.
459*/
460
461void QMediaRecorder::record()
462{
463 Q_D(QMediaRecorder);
464
465 if (!d->control || !d->captureSession)
466 return;
467
468 if (d->control->state() == QMediaRecorder::PausedState) {
469 d->control->resume();
470 } else {
471 auto oldMediaFormat = d->encoderSettings.mediaFormat();
472
473 auto platformSession = d->captureSession->platformSession();
474 const bool hasVideo = platformSession && !platformSession->activeVideoSources().empty();
475
476 d->encoderSettings.resolveFormat(hasVideo ? QMediaFormat::RequiresVideo : QMediaFormat::NoFlags);
477 d->control->clearActualLocation();
478 d->control->clearError();
479
480 auto settings = d->encoderSettings;
481 d->control->record(d->encoderSettings);
482
483#if QT_DEPRECATED_SINCE(6, 9)
484QT_WARNING_PUSH
485QT_WARNING_DISABLE_DEPRECATED
486 if (settings != d->encoderSettings)
487 emit encoderSettingsChanged();
488QT_WARNING_POP
489#endif
490
491 if (oldMediaFormat != d->encoderSettings.mediaFormat())
492 emit mediaFormatChanged();
493
494 if (settings.encodingMode() != d->encoderSettings.encodingMode())
495 emit encodingModeChanged();
496
497 if (settings.quality() != d->encoderSettings.quality())
498 emit qualityChanged();
499
500 if (settings.videoResolution() != d->encoderSettings.videoResolution())
501 emit videoResolutionChanged();
502
503 if (!QtPrivate::fuzzyCompare(settings.videoFrameRate(),
504 d->encoderSettings.videoFrameRate()))
505 emit videoFrameRateChanged();
506
507 if (settings.videoBitRate() != d->encoderSettings.videoBitRate())
508 emit videoBitRateChanged();
509
510 if (settings.audioBitRate() != d->encoderSettings.audioBitRate())
511 emit audioBitRateChanged();
512
513 if (settings.audioChannelCount() != d->encoderSettings.audioChannelCount())
514 emit audioChannelCountChanged();
515
516 if (settings.audioSampleRate() != d->encoderSettings.audioSampleRate())
517 emit audioSampleRateChanged();
518 }
519}
520/*!
521 \qmlmethod QtMultimedia::MediaRecorder::pause()
522 \brief Pauses recording.
523
524 The recorder state is changed to QMediaRecorder.PausedState.
525
526 Depending on the platform, pausing recording may be not supported.
527 In this case the recorder state is unchanged.
528*/
529/*!
530 Pauses recording.
531
532 The recorder state is changed to QMediaRecorder::PausedState.
533
534 Depending on the platform, pausing recording may be not supported.
535 In this case the recorder state is unchanged.
536*/
537
538void QMediaRecorder::pause()
539{
540 Q_D(QMediaRecorder);
541 if (d->control && d->captureSession)
542 d->control->pause();
543}
544/*!
545 \qmlmethod QtMultimedia::MediaRecorder::stop()
546 \brief Stops the recording.
547
548 The recorder will stop the recording. Processing pending video and audio data might
549 however still take some time. The recording is finished, once the state of the media
550 recorder changes to QMediaRecorder::StoppedState.
551*/
552
553/*!
554 The recorder will stop the recording. Processing pending video and audio data might
555 however still take some time. The recording is finished, once the state of the media
556 recorder changes to QMediaRecorder::StoppedState.
557*/
558void QMediaRecorder::stop()
559{
560 Q_D(QMediaRecorder);
561 if (d->control && d->captureSession)
562 d->control->stop();
563}
564/*!
565 \qmlproperty enumeration QtMultimedia::MediaRecorder::recorderState
566 \brief This property holds the current media recorder state.
567
568 The state property represents the user request and is changed synchronously
569 during record(), pause() or stop() calls.
570 RecorderSstate may also change asynchronously when recording fails.
571
572 \value MediaRecorder.StoppedState The recorder is not active.
573 \value MediaRecorder.RecordingState The recording is requested.
574 \value MediaRecorder.PausedState The recorder is pause.
575*/
576/*!
577 \enum QMediaRecorder::RecorderState
578
579 \value StoppedState The recorder is not active.
580 \value RecordingState The recording is requested.
581 \value PausedState The recorder is paused.
582*/
583/*!
584 \qmlproperty enumeration QtMultimedia::MediaRecorder::error
585 \brief This property holds the current media recorder error state.
586
587 \value MediaRecorder.NoError Not in an error state.
588 \value MediaRecorder.ResourceError Not enough system resources
589 \value MediaRecorder.FormatError the current format is not supported.
590 \value MediaRecorder.OutOfSpaceError No space left on device.
591 \value MediaRecorder.LocationNotWriteable The output location is not writable.
592*/
593/*!
594 \enum QMediaRecorder::Error
595
596 \value NoError No Errors.
597 \value ResourceError Device is not ready or not available.
598 \value FormatError Current format is not supported.
599 \value OutOfSpaceError No space left on device.
600 \value LocationNotWritable The output location is not writable.
601*/
602
603/*!
604 \property QMediaRecorder::recorderState
605 \brief The current state of the media recorder.
606
607 The state property represents the user request and is changed synchronously
608 during record(), pause() or stop() calls.
609 Recorder state may also change asynchronously when recording fails.
610*/
611
612/*!
613 \qmlsignal QtMultimedia::MediaRecorder::recorderStateChanged(RecorderState state)
614 \brief Signals that a media recorder's \a state has changed.
615*/
616
617/*!
618 \fn QMediaRecorder::recorderStateChanged(QMediaRecorder::RecorderState state)
619
620 Signals that a media recorder's \a state has changed.
621*/
622
623/*!
624 \qmlsignal QtMultimedia::MediaRecorder::durationChanged(qint64 duration)
625 \brief Signals that the \a duration of the recorded media has changed.
626*/
627
628/*!
629 \fn QMediaRecorder::durationChanged(qint64 duration)
630
631 Signals that the \a duration of the recorded media has changed.
632*/
633/*!
634 \qmlsignal QtMultimedia::MediaRecorder::actualLocationChanged(const QUrl &location)
635 \brief Signals that the actual \a location of the recorded media has changed.
636
637 This signal is usually emitted when recording starts.
638*/
639/*!
640 \fn QMediaRecorder::actualLocationChanged(const QUrl &location)
641
642 Signals that the actual \a location of the recorded media has changed.
643 This signal is usually emitted when recording starts.
644*/
645/*!
646 \qmlsignal QtMultimedia::MediaRecorder::errorOccurred(Error error, const QString &errorString)
647 \brief Signals that an \a error has occurred.
648
649 The \a errorString contains a description of the error.
650*/
651/*!
652 \fn QMediaRecorder::errorOccurred(QMediaRecorder::Error error, const QString &errorString)
653
654 Signals that an \a error has occurred, with \a errorString containing
655 a description of the error.
656*/
657
658/*!
659 \qmlproperty mediaMetaData QtMultimedia::MediaRecorder::metaData
660
661 \brief This property holds meta data associated with the recording.
662
663 When a recording is started, any meta-data assigned will be attached to that
664 recording.
665
666 \note Ensure that meta-data is assigned correctly by assigning it before
667 starting the recording.
668
669 \sa mediaMetaData
670*/
671
672/*!
673 \property QMediaRecorder::metaData
674
675 Returns the metaData associated with the recording.
676*/
677QMediaMetaData QMediaRecorder::metaData() const
678{
679 Q_D(const QMediaRecorder);
680
681 return d->control ? d->control->metaData() : QMediaMetaData{};
682}
683
684/*!
685 Sets the meta data to \a metaData.
686
687 \note To ensure that meta-data is set correctly, it should be set before starting the recording.
688 Once the recording is started, any meta-data set will be attached to the next recording.
689*/
690void QMediaRecorder::setMetaData(const QMediaMetaData &metaData)
691{
692 Q_D(QMediaRecorder);
693
694 if (d->control && d->captureSession)
695 d->control->setMetaData(metaData);
696}
697
698/*!
699 Adds \a metaData to the recorded media.
700*/
701void QMediaRecorder::addMetaData(const QMediaMetaData &metaData)
702{
703 auto data = this->metaData();
704 // merge data
705 for (auto &&[key, value] : metaData.asKeyValueRange())
706 data.insert(key, value);
707 setMetaData(data);
708}
709
710/*!
711 \property QMediaRecorder::autoStop
712
713 This property controls whether the media recorder stops automatically when
714 all media inputs have reported the end of the stream or have been deactivated.
715
716 The end of the stream is reported by sending an empty media frame,
717 which you can send explicitly via \l QVideoFrameInput or \l QAudioBufferInput.
718
719 Video inputs, specificly, \l QCamera, \l QScreenCapture and \l QWindowCapture,
720 can be deactivated via the function \c setActive.
721
722 Defaults to \c false.
723
724 QMediaRecorder::autoStop is only supported with the FFmpeg backend.
725
726 \sa QCamera, QScreenCapture, QWindowCapture
727*/
728
729bool QMediaRecorder::autoStop() const
730{
731 Q_D(const QMediaRecorder);
732
733 return d->autoStop;
734}
735
736void QMediaRecorder::setAutoStop(bool autoStop)
737{
738 Q_D(QMediaRecorder);
739
740 if (d->autoStop == autoStop)
741 return;
742
743 d->autoStop = autoStop;
744
745 if (d->control)
746 d->control->updateAutoStop();
747
748 emit autoStopChanged();
749}
750
751/*!
752 \qmlsignal QtMultimedia::MediaRecorder::metaDataChanged()
753
754 \brief Signals that a media object's meta-data has changed.
755
756 If multiple meta-data elements are changed metaDataChanged() is emitted
757 once.
758*/
759/*!
760 \fn QMediaRecorder::metaDataChanged()
761
762 Signals that a media object's meta-data has changed.
763
764 If multiple meta-data elements are changed metaDataChanged() is emitted
765 once.
766*/
767
768/*!
769 Returns the media capture session.
770*/
771QMediaCaptureSession *QMediaRecorder::captureSession() const
772{
773 Q_D(const QMediaRecorder);
774 return d->captureSession;
775}
776/*!
777 \qmlproperty enumeration QtMultimedia::MediaRecorder::quality
778
779 Enumerates quality encoding levels.
780
781 \value MediaRecorder.VeryLowQuality
782 \value MediaRecorder.LowQuality
783 \value MediaRecorder.NormalQuality
784 \value MediaRecorder.HighQuality
785 \value MediaRecorder.VeryHighQuality
786*/
787/*!
788 \enum QMediaRecorder::Quality
789
790 Enumerates quality encoding levels.
791
792 \value VeryLowQuality
793 \value LowQuality
794 \value NormalQuality
795 \value HighQuality
796 \value VeryHighQuality
797*/
798
799/*!
800 \enum QMediaRecorder::EncodingMode
801
802 Enumerates encoding modes.
803
804 \value ConstantQualityEncoding Encoding will aim to have a constant quality, adjusting bitrate to fit.
805 \value ConstantBitRateEncoding Encoding will use a constant bit rate, adjust quality to fit.
806 \value AverageBitRateEncoding Encoding will try to keep an average bitrate setting, but will use
807 more or less as needed.
808 \value TwoPassEncoding The media will first be processed to determine the characteristics,
809 and then processed a second time allocating more bits to the areas
810 that need it.
811*/
812
813/*!
814
815 \qmlproperty mediaFormat QtMultimedia::MediaRecorder::mediaFormat
816
817 \brief This property holds the current MediaFormat of the recorder.
818*/
819/*!
820 \property QMediaRecorder::mediaFormat
821
822 \brief This property holds the current \l QMediaFormat of the recorder.
823
824 The value of this property may change when invoking \l record(). If this happens, the
825 mediaFormatChanged() signal will be emitted. This will always happen if the
826 \l QMediaFormat::audioCodec or \l QMediaFormat::fileFormat properties are set to unspecified.
827 If a video source (\l QCamera, \l QScreenCapture, or \l QVideoFrameInput) is connected to the
828 \l QMediaCaptureSession, \l QMediaFormat::videoCodec must also be specified.
829 The \l QMediaFormat::audioCodec and \l QMediaFormat::videoCodec property values may also change
830 if the media backend does not support the selected file format or codec.
831
832 The \l QMediaFormat::fileFormat property value may also change to an \c audio only format if a
833 video format was requested, but \l QMediaCaptureSession does not have a video source connected.
834 For example, if \l QMediaFormat::fileFormat is set to \l QMediaFormat::MPEG4, it may
835 be changed to \l QMediaFormat::Mpeg4Audio.
836
837 Applications can determine if \c mediaFormat will change before recording starts by calling the
838 \l QMediaFormat::isSupported() function. When recording without any video inputs,
839 \l record() will not be changed the \l QMediaFormat if the following is true:
840 \list
841 \li \l QMediaFormat::fileFormat is specified
842 \li \l QMediaFormat::audioCodec is specified
843 \li \l QMediaFormat::videoCodec is \b{unspecified}
844 \li \l QMediaFormat::isSupported() returns \c true
845 \endlist
846 When recording with video input, \c mediaFormat will not be changed if the following is true:
847 \list
848 \li \l QMediaFormat::fileFormat is specified
849 \li \l QMediaFormat::audioCodec is specified
850 \li \l QMediaFormat::videoCodec is specified
851 \li \l QMediaFormat::isSupported() returns \c true
852 \endlist
853
854 \note The \l QMediaRecorder does not take the file name extension from the \l outputLocation
855 property into account when determining the \l QMediaFormat::fileFormat, and will not adjust the
856 extension of the \l outputLocation \l QUrl to match the selected file format if an extension is
857 specified. Applications should therefore make sure to set the
858 \l {QMediaFormat::fileFormat}{QMediaRecorder::mediaFormat::fileFormat} to match the file
859 extension, or not specify a file extension. If no file extension is specified, the
860 \l actualLocation file extension will be updated to match the file format used for recording.
861
862 \sa QMediaFormat::isSupported(), actualLocation
863*/
864QMediaFormat QMediaRecorder::mediaFormat() const
865{
866 Q_D(const QMediaRecorder);
867 return d->encoderSettings.mediaFormat();
868}
869
870void QMediaRecorder::setMediaFormat(const QMediaFormat &format)
871{
872 Q_D(QMediaRecorder);
873 if (d->encoderSettings.mediaFormat() == format)
874 return;
875 d->encoderSettings.setMediaFormat(format);
876 emit mediaFormatChanged();
877}
878
879/*!
880
881 \qmlproperty enumeration QtMultimedia::MediaRecorder::encodingMode
882 \since 6.6
883 \brief This property holds the encoding mode.
884 \sa QMediaRecorder::EncodingMode
885*/
886
887/*!
888 \property QMediaRecorder::encodingMode
889 \brief the encoding mode.
890 \sa EncodingMode
891*/
892
893/*!
894 Returns the encoding mode.
895
896 \sa EncodingMode
897*/
898QMediaRecorder::EncodingMode QMediaRecorder::encodingMode() const
899{
900 Q_D(const QMediaRecorder);
901 return d->encoderSettings.encodingMode();
902}
903
904/*!
905 \fn void QMediaRecorder::encodingModeChanged()
906
907 Signals when the encoding mode changes.
908*/
909/*!
910 Sets the encoding \a mode setting.
911
912 If ConstantQualityEncoding is set, the quality
913 encoding parameter is used and bit rates are ignored,
914 otherwise the bitrates are used.
915
916 \sa encodingMode(), EncodingMode
917*/
918void QMediaRecorder::setEncodingMode(EncodingMode mode)
919{
920 Q_D(QMediaRecorder);
921 if (d->encoderSettings.encodingMode() == mode)
922 return;
923 d->encoderSettings.setEncodingMode(mode);
924 emit encodingModeChanged();
925}
926
927/*!
928 \property QMediaRecorder::quality
929
930 Returns the recording quality.
931*/
932QMediaRecorder::Quality QMediaRecorder::quality() const
933{
934 Q_D(const QMediaRecorder);
935 return d->encoderSettings.quality();
936}
937
938/*!
939 \fn void QMediaRecorder::qualityChanged()
940
941 Signals when the recording quality changes.
942*/
943void QMediaRecorder::setQuality(Quality quality)
944{
945 Q_D(QMediaRecorder);
946
947 quality = std::clamp(quality, QMediaRecorder::Quality::VeryLowQuality,
948 QMediaRecorder::Quality::VeryHighQuality);
949
950 if (d->encoderSettings.quality() == quality)
951 return;
952
953 d->encoderSettings.setQuality(quality);
954 emit qualityChanged();
955}
956
957/*!
958 \qmlproperty Size QtMultimedia::MediaRecorder::videoResolution
959 \since 6.6
960 \brief This property holds the resolution of the encoded video.
961
962 Set an empty Size to make the recorder choose an optimal resolution based
963 on what is available from the video source and the limitations of the codec.
964*/
965
966/*!
967 \property QMediaRecorder::videoResolution
968 \since 6.6
969 \brief the resolution of the encoded video.
970
971 An empty QSize indicates the recorder will choose an optimal resolution based
972 on what is available from the video source and the limitations of the codec.
973*/
974
975/*!
976 Returns the resolution of the encoded video.
977*/
978QSize QMediaRecorder::videoResolution() const
979{
980 Q_D(const QMediaRecorder);
981 return d->encoderSettings.videoResolution();
982}
983
984/*!
985 \fn void QMediaRecorder::videoResolutionChanged()
986
987 Signals when the video recording resolution changes.
988*/
989/*!
990 Sets the resolution of the encoded video to \a{size}.
991
992 Pass an empty QSize to make the recorder choose an optimal resolution based
993 on what is available from the video source and the limitations of the codec.
994*/
995void QMediaRecorder::setVideoResolution(const QSize &size)
996{
997 Q_D(QMediaRecorder);
998 if (d->encoderSettings.videoResolution() == size)
999 return;
1000 d->encoderSettings.setVideoResolution(size);
1001 emit videoResolutionChanged();
1002}
1003
1004/*! \fn void QMediaRecorder::setVideoResolution(int width, int height)
1005
1006 Sets the \a width and \a height of the resolution of the encoded video.
1007
1008 \overload
1009*/
1010
1011/*!
1012 \qmlproperty real QtMultimedia::MediaRecorder::videoFrameRate
1013 \since 6.6
1014 \brief This property holds the video frame rate.
1015
1016 A value of 0 indicates the recorder should make an optimal choice based on what is available
1017 from the video source and the limitations of the codec.
1018*/
1019
1020/*!
1021 \property QMediaRecorder::videoFrameRate
1022 \since 6.6
1023 \brief the video frame rate.
1024
1025 A value of 0 indicates the recorder should make an optimal choice based on what is available
1026 from the video source and the limitations of the codec.
1027*/
1028
1029/*!
1030 Returns the video frame rate.
1031*/
1032qreal QMediaRecorder::videoFrameRate() const
1033{
1034 Q_D(const QMediaRecorder);
1035 return d->encoderSettings.videoFrameRate();
1036}
1037
1038/*!
1039 \fn void QMediaRecorder::videoFrameRateChanged()
1040
1041 Signals when the recording video frame rate changes.
1042*/
1043/*!
1044 Sets the video \a frameRate.
1045
1046 A value of 0 indicates the recorder should make an optimal choice based on what is available
1047 from the video source and the limitations of the codec.
1048*/
1049void QMediaRecorder::setVideoFrameRate(qreal frameRate)
1050{
1051 Q_D(QMediaRecorder);
1052 if (d->encoderSettings.videoFrameRate() == frameRate)
1053 return;
1054 d->encoderSettings.setVideoFrameRate(frameRate);
1055 emit videoFrameRateChanged();
1056}
1057
1058/*!
1059 \qmlproperty int QtMultimedia::MediaRecorder::videoBitRate
1060 \since 6.6
1061 \brief This property holds the bit rate of the compressed video stream in bits per second.
1062*/
1063
1064/*!
1065 \property QMediaRecorder::videoBitRate
1066 \since 6.6
1067 \brief the bit rate of the compressed video stream in bits per second.
1068*/
1069
1070/*!
1071 Returns the bit rate of the compressed video stream in bits per second.
1072*/
1073int QMediaRecorder::videoBitRate() const
1074{
1075 Q_D(const QMediaRecorder);
1076 return d->encoderSettings.videoBitRate();
1077}
1078
1079/*!
1080 \fn void QMediaRecorder::videoBitRateChanged()
1081
1082 Signals when the recording video bit rate changes.
1083*/
1084/*!
1085 Sets the video \a bitRate in bits per second.
1086*/
1087void QMediaRecorder::setVideoBitRate(int bitRate)
1088{
1089 Q_D(QMediaRecorder);
1090 if (d->encoderSettings.videoBitRate() == bitRate)
1091 return;
1092 d->encoderSettings.setVideoBitRate(bitRate);
1093 emit videoBitRateChanged();
1094}
1095
1096/*!
1097 \qmlproperty int QtMultimedia::MediaRecorder::audioBitRate
1098 \since 6.6
1099 \brief This property holds the bit rate of the compressed audio stream in bits per second.
1100*/
1101
1102/*!
1103 \property QMediaRecorder::audioBitRate
1104 \brief the bit rate of the compressed audio stream in bits per second.
1105*/
1106/*!
1107 Returns the bit rate of the compressed audio stream in bits per second.
1108*/
1109int QMediaRecorder::audioBitRate() const
1110{
1111 Q_D(const QMediaRecorder);
1112 return d->encoderSettings.audioBitRate();
1113}
1114
1115/*!
1116 \fn void QMediaRecorder::audioBitRateChanged()
1117
1118 Signals when the recording audio bit rate changes.
1119*/
1120/*!
1121 Sets the audio \a bitRate in bits per second.
1122*/
1123void QMediaRecorder::setAudioBitRate(int bitRate)
1124{
1125 Q_D(QMediaRecorder);
1126 if (d->encoderSettings.audioBitRate() == bitRate)
1127 return;
1128 d->encoderSettings.setAudioBitRate(bitRate);
1129 emit audioBitRateChanged();
1130}
1131
1132/*!
1133 \qmlproperty int QtMultimedia::MediaRecorder::audioChannelCount
1134 \since 6.6
1135 \brief This property holds the number of audio channels.
1136*/
1137
1138/*!
1139 \property QMediaRecorder::audioChannelCount
1140 \brief the number of audio channels.
1141*/
1142
1143/*!
1144 Returns the number of audio channels.
1145*/
1146int QMediaRecorder::audioChannelCount() const
1147{
1148 Q_D(const QMediaRecorder);
1149 return d->encoderSettings.audioChannelCount();
1150}
1151
1152/*!
1153 \fn void QMediaRecorder::audioChannelCountChanged()
1154
1155 Signals when the recording audio channel count changes.
1156*/
1157/*!
1158 Sets the number of audio \a channels.
1159
1160 A value of -1 indicates the recorder should make an optimal choice based on
1161 what is available from the audio source and the limitations of the codec.
1162*/
1163void QMediaRecorder::setAudioChannelCount(int channels)
1164{
1165 Q_D(QMediaRecorder);
1166 if (d->encoderSettings.audioChannelCount() == channels)
1167 return;
1168 d->encoderSettings.setAudioChannelCount(channels);
1169 emit audioChannelCountChanged();
1170}
1171
1172/*!
1173 \qmlproperty int QtMultimedia::MediaRecorder::audioSampleRate
1174 \since 6.6
1175 \brief This property holds the audio sample rate in Hz.
1176*/
1177
1178/*!
1179 \property QMediaRecorder::audioSampleRate
1180 \brief the audio sample rate in Hz.
1181*/
1182
1183/*!
1184 Returns the audio sample rate in Hz.
1185*/
1186int QMediaRecorder::audioSampleRate() const
1187{
1188 Q_D(const QMediaRecorder);
1189 return d->encoderSettings.audioSampleRate();
1190}
1191/*!
1192 \fn void QMediaRecorder::audioSampleRateChanged()
1193
1194 Signals when the recording audio sample rate changes.
1195*/
1196/*!
1197 Sets the audio \a sampleRate in Hz.
1198
1199 A value of \c -1 indicates the recorder should make an optimal choice based
1200 on what is available from the audio source, and the limitations of the codec.
1201*/
1202void QMediaRecorder::setAudioSampleRate(int sampleRate)
1203{
1204 Q_D(QMediaRecorder);
1205 if (d->encoderSettings.audioSampleRate() == sampleRate)
1206 return;
1207 d->encoderSettings.setAudioSampleRate(sampleRate);
1208 emit audioSampleRateChanged();
1209}
1210
1211QT_END_NAMESPACE
1212
1213#include "moc_qmediarecorder.cpp"