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