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

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

source code of qtmultimedia/src/multimedia/recording/qmediarecorder.cpp