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 (!qFuzzyCompare(settings.videoFrameRate(), d->encoderSettings.videoFrameRate()))
504 emit videoFrameRateChanged();
505
506 if (settings.videoBitRate() != d->encoderSettings.videoBitRate())
507 emit videoBitRateChanged();
508
509 if (settings.audioBitRate() != d->encoderSettings.audioBitRate())
510 emit audioBitRateChanged();
511
512 if (settings.audioChannelCount() != d->encoderSettings.audioChannelCount())
513 emit audioChannelCountChanged();
514
515 if (settings.audioSampleRate() != d->encoderSettings.audioSampleRate())
516 emit audioSampleRateChanged();
517 }
518}
519/*!
520 \qmlmethod QtMultimedia::MediaRecorder::pause()
521 \brief Pauses recording.
522
523 The recorder state is changed to QMediaRecorder.PausedState.
524
525 Depending on the platform, pausing recording may be not supported.
526 In this case the recorder state is unchanged.
527*/
528/*!
529 Pauses recording.
530
531 The recorder state is changed to QMediaRecorder::PausedState.
532
533 Depending on the platform, pausing recording may be not supported.
534 In this case the recorder state is unchanged.
535*/
536
537void QMediaRecorder::pause()
538{
539 Q_D(QMediaRecorder);
540 if (d->control && d->captureSession)
541 d->control->pause();
542}
543/*!
544 \qmlmethod QtMultimedia::MediaRecorder::stop()
545 \brief Stops the recording.
546
547 The recorder will stop the recording. Processing pending video and audio data might
548 however still take some time. The recording is finished, once the state of the media
549 recorder changes to QMediaRecorder::StoppedState.
550*/
551
552/*!
553 The recorder will stop the recording. Processing pending video and audio data might
554 however still take some time. The recording is finished, once the state of the media
555 recorder changes to QMediaRecorder::StoppedState.
556*/
557void QMediaRecorder::stop()
558{
559 Q_D(QMediaRecorder);
560 if (d->control && d->captureSession)
561 d->control->stop();
562}
563/*!
564 \qmlproperty enumeration QtMultimedia::MediaRecorder::recorderState
565 \brief This property holds the current media recorder state.
566
567 The state property represents the user request and is changed synchronously
568 during record(), pause() or stop() calls.
569 RecorderSstate may also change asynchronously when recording fails.
570
571 \value MediaRecorder.StoppedState The recorder is not active.
572 \value MediaRecorder.RecordingState The recording is requested.
573 \value MediaRecorder.PausedState The recorder is pause.
574*/
575/*!
576 \enum QMediaRecorder::RecorderState
577
578 \value StoppedState The recorder is not active.
579 \value RecordingState The recording is requested.
580 \value PausedState The recorder is paused.
581*/
582/*!
583 \qmlproperty enumeration QtMultimedia::MediaRecorder::error
584 \brief This property holds the current media recorder error state.
585
586 \value MediaRecorder.NoError Not in an error state.
587 \value MediaRecorder.ResourceError Not enough system resources
588 \value MediaRecorder.FormatError the current format is not supported.
589 \value MediaRecorder.OutOfSpaceError No space left on device.
590 \value MediaRecorder.LocationNotWriteable The output location is not writable.
591*/
592/*!
593 \enum QMediaRecorder::Error
594
595 \value NoError No Errors.
596 \value ResourceError Device is not ready or not available.
597 \value FormatError Current format is not supported.
598 \value OutOfSpaceError No space left on device.
599 \value LocationNotWritable The output location is not writable.
600*/
601
602/*!
603 \property QMediaRecorder::recorderState
604 \brief The current state of the media recorder.
605
606 The state property represents the user request and is changed synchronously
607 during record(), pause() or stop() calls.
608 Recorder state may also change asynchronously when recording fails.
609*/
610
611/*!
612 \qmlsignal QtMultimedia::MediaRecorder::recorderStateChanged(RecorderState state)
613 \brief Signals that a media recorder's \a state has changed.
614*/
615
616/*!
617 \fn QMediaRecorder::recorderStateChanged(QMediaRecorder::RecorderState state)
618
619 Signals that a media recorder's \a state has changed.
620*/
621
622/*!
623 \qmlsignal QtMultimedia::MediaRecorder::durationChanged(qint64 duration)
624 \brief Signals that the \a duration of the recorded media has changed.
625*/
626
627/*!
628 \fn QMediaRecorder::durationChanged(qint64 duration)
629
630 Signals that the \a duration of the recorded media has changed.
631*/
632/*!
633 \qmlsignal QtMultimedia::MediaRecorder::actualLocationChanged(const QUrl &location)
634 \brief Signals that the actual \a location of the recorded media has changed.
635
636 This signal is usually emitted when recording starts.
637*/
638/*!
639 \fn QMediaRecorder::actualLocationChanged(const QUrl &location)
640
641 Signals that the actual \a location of the recorded media has changed.
642 This signal is usually emitted when recording starts.
643*/
644/*!
645 \qmlsignal QtMultimedia::MediaRecorder::errorOccurred(Error error, const QString &errorString)
646 \brief Signals that an \a error has occurred.
647
648 The \a errorString contains a description of the error.
649*/
650/*!
651 \fn QMediaRecorder::errorOccurred(QMediaRecorder::Error error, const QString &errorString)
652
653 Signals that an \a error has occurred, with \a errorString containing
654 a description of the error.
655*/
656
657/*!
658 \qmlproperty mediaMetaData QtMultimedia::MediaRecorder::metaData
659
660 \brief This property holds meta data associated with the recording.
661
662 When a recording is started, any meta-data assigned will be attached to that
663 recording.
664
665 \note Ensure that meta-data is assigned correctly by assigning it before
666 starting the recording.
667
668 \sa mediaMetaData
669*/
670
671/*!
672 \property QMediaRecorder::metaData
673
674 Returns the metaData associated with the recording.
675*/
676QMediaMetaData QMediaRecorder::metaData() const
677{
678 Q_D(const QMediaRecorder);
679
680 return d->control ? d->control->metaData() : QMediaMetaData{};
681}
682
683/*!
684 Sets the meta data to \a metaData.
685
686 \note To ensure that meta-data is set correctly, it should be set before starting the recording.
687 Once the recording is started, any meta-data set will be attached to the next recording.
688*/
689void QMediaRecorder::setMetaData(const QMediaMetaData &metaData)
690{
691 Q_D(QMediaRecorder);
692
693 if (d->control && d->captureSession)
694 d->control->setMetaData(metaData);
695}
696
697/*!
698 Adds \a metaData to the recorded media.
699*/
700void QMediaRecorder::addMetaData(const QMediaMetaData &metaData)
701{
702 auto data = this->metaData();
703 // merge data
704 for (auto &&[key, value] : metaData.asKeyValueRange())
705 data.insert(key, value);
706 setMetaData(data);
707}
708
709/*!
710 \property QMediaRecorder::autoStop
711
712 This property controls whether the media recorder stops automatically when
713 all media inputs have reported the end of the stream or have been deactivated.
714
715 The end of the stream is reported by sending an empty media frame,
716 which you can send explicitly via \l QVideoFrameInput or \l QAudioBufferInput.
717
718 Video inputs, specificly, \l QCamera, \l QScreenCapture and \l QWindowCapture,
719 can be deactivated via the function \c setActive.
720
721 Defaults to \c false.
722
723 QMediaRecorder::autoStop is only supported with the FFmpeg backend.
724
725 \sa QCamera, QScreenCapture, QWindowCapture
726*/
727
728bool QMediaRecorder::autoStop() const
729{
730 Q_D(const QMediaRecorder);
731
732 return d->autoStop;
733}
734
735void QMediaRecorder::setAutoStop(bool autoStop)
736{
737 Q_D(QMediaRecorder);
738
739 if (d->autoStop == autoStop)
740 return;
741
742 d->autoStop = autoStop;
743
744 if (d->control)
745 d->control->updateAutoStop();
746
747 emit autoStopChanged();
748}
749
750/*!
751 \qmlsignal QtMultimedia::MediaRecorder::metaDataChanged()
752
753 \brief Signals that a media object's meta-data has changed.
754
755 If multiple meta-data elements are changed metaDataChanged() is emitted
756 once.
757*/
758/*!
759 \fn QMediaRecorder::metaDataChanged()
760
761 Signals that a media object's meta-data has changed.
762
763 If multiple meta-data elements are changed metaDataChanged() is emitted
764 once.
765*/
766
767/*!
768 Returns the media capture session.
769*/
770QMediaCaptureSession *QMediaRecorder::captureSession() const
771{
772 Q_D(const QMediaRecorder);
773 return d->captureSession;
774}
775/*!
776 \qmlproperty enumeration QtMultimedia::MediaRecorder::quality
777
778 Enumerates quality encoding levels.
779
780 \value MediaRecorder.VeryLowQuality
781 \value MediaRecorder.LowQuality
782 \value MediaRecorder.NormalQuality
783 \value MediaRecorder.HighQuality
784 \value MediaRecorder.VeryHighQuality
785*/
786/*!
787 \enum QMediaRecorder::Quality
788
789 Enumerates quality encoding levels.
790
791 \value VeryLowQuality
792 \value LowQuality
793 \value NormalQuality
794 \value HighQuality
795 \value VeryHighQuality
796*/
797
798/*!
799 \enum QMediaRecorder::EncodingMode
800
801 Enumerates encoding modes.
802
803 \value ConstantQualityEncoding Encoding will aim to have a constant quality, adjusting bitrate to fit.
804 \value ConstantBitRateEncoding Encoding will use a constant bit rate, adjust quality to fit.
805 \value AverageBitRateEncoding Encoding will try to keep an average bitrate setting, but will use
806 more or less as needed.
807 \value TwoPassEncoding The media will first be processed to determine the characteristics,
808 and then processed a second time allocating more bits to the areas
809 that need it.
810*/
811
812/*!
813
814 \qmlproperty mediaFormat QtMultimedia::MediaRecorder::mediaFormat
815
816 \brief This property holds the current MediaFormat of the recorder.
817*/
818/*!
819 \property QMediaRecorder::mediaFormat
820
821 \brief This property holds the current \l QMediaFormat of the recorder.
822
823 The value of this property may change when invoking \l record(). If this happens, the
824 mediaFormatChanged() signal will be emitted. This will always happen if the
825 \l QMediaFormat::audioCodec or \l QMediaFormat::fileFormat properties are set to unspecified.
826 If a video source (\l QCamera, \l QScreenCapture, or \l QVideoFrameInput) is connected to the
827 \l QMediaCaptureSession, \l QMediaFormat::videoCodec must also be specified.
828 The \l QMediaFormat::audioCodec and \l QMediaFormat::videoCodec property values may also change
829 if the media backend does not support the selected file format or codec.
830
831 The \l QMediaFormat::fileFormat property value may also change to an \c audio only format if a
832 video format was requested, but \l QMediaCaptureSession does not have a video source connected.
833 For example, if \l QMediaFormat::fileFormat is set to \l QMediaFormat::MPEG4, it may
834 be changed to \l QMediaFormat::Mpeg4Audio.
835
836 Applications can determine if \c mediaFormat will change before recording starts by calling the
837 \l QMediaFormat::isSupported() function. When recording without any video inputs,
838 \l record() will not be changed the \l QMediaFormat if the following is true:
839 \list
840 \li \l QMediaFormat::fileFormat is specified
841 \li \l QMediaFormat::audioCodec is specified
842 \li \l QMediaFormat::videoCodec is \b{unspecified}
843 \li \l QMediaFormat::isSupported() returns \c true
844 \endlist
845 When recording with video input, \c mediaFormat will not be changed if the following is true:
846 \list
847 \li \l QMediaFormat::fileFormat is specified
848 \li \l QMediaFormat::audioCodec is specified
849 \li \l QMediaFormat::videoCodec is specified
850 \li \l QMediaFormat::isSupported() returns \c true
851 \endlist
852
853 \note The \l QMediaRecorder does not take the file name extension from the \l outputLocation
854 property into account when determining the \l QMediaFormat::fileFormat, and will not adjust the
855 extension of the \l outputLocation \l QUrl to match the selected file format if an extension is
856 specified. Applications should therefore make sure to set the
857 \l {QMediaFormat::fileFormat}{QMediaRecorder::mediaFormat::fileFormat} to match the file
858 extension, or not specify a file extension. If no file extension is specified, the
859 \l actualLocation file extension will be updated to match the file format used for recording.
860
861 \sa QMediaFormat::isSupported(), actualLocation
862*/
863QMediaFormat QMediaRecorder::mediaFormat() const
864{
865 Q_D(const QMediaRecorder);
866 return d->encoderSettings.mediaFormat();
867}
868
869void QMediaRecorder::setMediaFormat(const QMediaFormat &format)
870{
871 Q_D(QMediaRecorder);
872 if (d->encoderSettings.mediaFormat() == format)
873 return;
874 d->encoderSettings.setMediaFormat(format);
875 emit mediaFormatChanged();
876}
877
878/*!
879
880 \qmlproperty enumeration QtMultimedia::MediaRecorder::encodingMode
881 \since 6.6
882 \brief This property holds the encoding mode.
883 \sa QMediaRecorder::EncodingMode
884*/
885
886/*!
887 \property QMediaRecorder::encodingMode
888 \brief the encoding mode.
889 \sa EncodingMode
890*/
891
892/*!
893 Returns the encoding mode.
894
895 \sa EncodingMode
896*/
897QMediaRecorder::EncodingMode QMediaRecorder::encodingMode() const
898{
899 Q_D(const QMediaRecorder);
900 return d->encoderSettings.encodingMode();
901}
902
903/*!
904 \fn void QMediaRecorder::encodingModeChanged()
905
906 Signals when the encoding mode changes.
907*/
908/*!
909 Sets the encoding \a mode setting.
910
911 If ConstantQualityEncoding is set, the quality
912 encoding parameter is used and bit rates are ignored,
913 otherwise the bitrates are used.
914
915 \sa encodingMode(), EncodingMode
916*/
917void QMediaRecorder::setEncodingMode(EncodingMode mode)
918{
919 Q_D(QMediaRecorder);
920 if (d->encoderSettings.encodingMode() == mode)
921 return;
922 d->encoderSettings.setEncodingMode(mode);
923 emit encodingModeChanged();
924}
925
926/*!
927 \property QMediaRecorder::quality
928
929 Returns the recording quality.
930*/
931QMediaRecorder::Quality QMediaRecorder::quality() const
932{
933 Q_D(const QMediaRecorder);
934 return d->encoderSettings.quality();
935}
936
937/*!
938 \fn void QMediaRecorder::qualityChanged()
939
940 Signals when the recording quality changes.
941*/
942void QMediaRecorder::setQuality(Quality quality)
943{
944 Q_D(QMediaRecorder);
945
946 quality = std::clamp(quality, QMediaRecorder::Quality::VeryLowQuality,
947 QMediaRecorder::Quality::VeryHighQuality);
948
949 if (d->encoderSettings.quality() == quality)
950 return;
951
952 d->encoderSettings.setQuality(quality);
953 emit qualityChanged();
954}
955
956/*!
957 \qmlproperty Size QtMultimedia::MediaRecorder::videoResolution
958 \since 6.6
959 \brief This property holds the resolution of the encoded video.
960
961 Set an empty Size to make the recorder choose an optimal resolution based
962 on what is available from the video source and the limitations of the codec.
963*/
964
965
966/*!
967 Returns the resolution of the encoded video.
968*/
969QSize QMediaRecorder::videoResolution() const
970{
971 Q_D(const QMediaRecorder);
972 return d->encoderSettings.videoResolution();
973}
974
975/*!
976 \fn void QMediaRecorder::videoResolutionChanged()
977
978 Signals when the video recording resolution changes.
979*/
980/*!
981 Sets the resolution of the encoded video to \a{size}.
982
983 Pass an empty QSize to make the recorder choose an optimal resolution based
984 on what is available from the video source and the limitations of the codec.
985*/
986void QMediaRecorder::setVideoResolution(const QSize &size)
987{
988 Q_D(QMediaRecorder);
989 if (d->encoderSettings.videoResolution() == size)
990 return;
991 d->encoderSettings.setVideoResolution(size);
992 emit videoResolutionChanged();
993}
994
995/*! \fn void QMediaRecorder::setVideoResolution(int width, int height)
996
997 Sets the \a width and \a height of the resolution of the encoded video.
998
999 \overload
1000*/
1001
1002/*!
1003 \qmlproperty real QtMultimedia::MediaRecorder::videoFrameRate
1004 \since 6.6
1005 \brief This property holds the video frame rate.
1006
1007 A value of 0 indicates the recorder should make an optimal choice based on what is available
1008 from the video source and the limitations of the codec.
1009*/
1010
1011/*!
1012 Returns the video frame rate.
1013*/
1014qreal QMediaRecorder::videoFrameRate() const
1015{
1016 Q_D(const QMediaRecorder);
1017 return d->encoderSettings.videoFrameRate();
1018}
1019
1020/*!
1021 \fn void QMediaRecorder::videoFrameRateChanged()
1022
1023 Signals when the recording video frame rate changes.
1024*/
1025/*!
1026 Sets the video \a frameRate.
1027
1028 A value of 0 indicates the recorder should make an optimal choice based on what is available
1029 from the video source and the limitations of the codec.
1030*/
1031void QMediaRecorder::setVideoFrameRate(qreal frameRate)
1032{
1033 Q_D(QMediaRecorder);
1034 if (d->encoderSettings.videoFrameRate() == frameRate)
1035 return;
1036 d->encoderSettings.setVideoFrameRate(frameRate);
1037 emit videoFrameRateChanged();
1038}
1039
1040/*!
1041 \qmlproperty int QtMultimedia::MediaRecorder::videoBitRate
1042 \since 6.6
1043 \brief This property holds the bit rate of the compressed video stream in bits per second.
1044*/
1045
1046/*!
1047 Returns the bit rate of the compressed video stream in bits per second.
1048*/
1049int QMediaRecorder::videoBitRate() const
1050{
1051 Q_D(const QMediaRecorder);
1052 return d->encoderSettings.videoBitRate();
1053}
1054
1055/*!
1056 \fn void QMediaRecorder::videoBitRateChanged()
1057
1058 Signals when the recording video bit rate changes.
1059*/
1060/*!
1061 Sets the video \a bitRate in bits per second.
1062*/
1063void QMediaRecorder::setVideoBitRate(int bitRate)
1064{
1065 Q_D(QMediaRecorder);
1066 if (d->encoderSettings.videoBitRate() == bitRate)
1067 return;
1068 d->encoderSettings.setVideoBitRate(bitRate);
1069 emit videoBitRateChanged();
1070}
1071
1072/*!
1073 \qmlproperty int QtMultimedia::MediaRecorder::audioBitRate
1074 \since 6.6
1075 \brief This property holds the bit rate of the compressed audio stream in bits per second.
1076*/
1077
1078/*!
1079 \property QMediaRecorder::audioBitRate
1080 \brief the bit rate of the compressed audio stream in bits per second.
1081*/
1082/*!
1083 Returns the bit rate of the compressed audio stream in bits per second.
1084*/
1085int QMediaRecorder::audioBitRate() const
1086{
1087 Q_D(const QMediaRecorder);
1088 return d->encoderSettings.audioBitRate();
1089}
1090
1091/*!
1092 \fn void QMediaRecorder::audioBitRateChanged()
1093
1094 Signals when the recording audio bit rate changes.
1095*/
1096/*!
1097 Sets the audio \a bitRate in bits per second.
1098*/
1099void QMediaRecorder::setAudioBitRate(int bitRate)
1100{
1101 Q_D(QMediaRecorder);
1102 if (d->encoderSettings.audioBitRate() == bitRate)
1103 return;
1104 d->encoderSettings.setAudioBitRate(bitRate);
1105 emit audioBitRateChanged();
1106}
1107
1108/*!
1109 \qmlproperty int QtMultimedia::MediaRecorder::audioChannelCount
1110 \since 6.6
1111 \brief This property holds the number of audio channels.
1112*/
1113
1114/*!
1115 \property QMediaRecorder::audioChannelCount
1116 \brief the number of audio channels.
1117*/
1118
1119/*!
1120 Returns the number of audio channels.
1121*/
1122int QMediaRecorder::audioChannelCount() const
1123{
1124 Q_D(const QMediaRecorder);
1125 return d->encoderSettings.audioChannelCount();
1126}
1127
1128/*!
1129 \fn void QMediaRecorder::audioChannelCountChanged()
1130
1131 Signals when the recording audio channel count changes.
1132*/
1133/*!
1134 Sets the number of audio \a channels.
1135
1136 A value of -1 indicates the recorder should make an optimal choice based on
1137 what is available from the audio source and the limitations of the codec.
1138*/
1139void QMediaRecorder::setAudioChannelCount(int channels)
1140{
1141 Q_D(QMediaRecorder);
1142 if (d->encoderSettings.audioChannelCount() == channels)
1143 return;
1144 d->encoderSettings.setAudioChannelCount(channels);
1145 emit audioChannelCountChanged();
1146}
1147
1148/*!
1149 \qmlproperty int QtMultimedia::MediaRecorder::audioSampleRate
1150 \since 6.6
1151 \brief This property holds the audio sample rate in Hz.
1152*/
1153
1154/*!
1155 \property QMediaRecorder::audioSampleRate
1156 \brief the audio sample rate in Hz.
1157*/
1158
1159/*!
1160 Returns the audio sample rate in Hz.
1161*/
1162int QMediaRecorder::audioSampleRate() const
1163{
1164 Q_D(const QMediaRecorder);
1165 return d->encoderSettings.audioSampleRate();
1166}
1167/*!
1168 \fn void QMediaRecorder::audioSampleRateChanged()
1169
1170 Signals when the recording audio sample rate changes.
1171*/
1172/*!
1173 Sets the audio \a sampleRate in Hz.
1174
1175 A value of \c -1 indicates the recorder should make an optimal choice based
1176 on what is available from the audio source, and the limitations of the codec.
1177*/
1178void QMediaRecorder::setAudioSampleRate(int sampleRate)
1179{
1180 Q_D(QMediaRecorder);
1181 if (d->encoderSettings.audioSampleRate() == sampleRate)
1182 return;
1183 d->encoderSettings.setAudioSampleRate(sampleRate);
1184 emit audioSampleRateChanged();
1185}
1186
1187QT_END_NAMESPACE
1188
1189#include "moc_qmediarecorder.cpp"