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