qtmobility/src/multimedia/qmediarecorder.cpp
changeset 1 2b40d63a9c3d
child 4 90517678cc4f
equal deleted inserted replaced
0:cfcbf08528c4 1:2b40d63a9c3d
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Mobility Components.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include <qmediarecorder.h>
       
    43 
       
    44 #include <qmediarecordercontrol.h>
       
    45 #include <qmediaobject_p.h>
       
    46 #include <qmediaservice.h>
       
    47 #include <qmediaserviceprovider.h>
       
    48 #include <qaudioencodercontrol.h>
       
    49 #include <qvideoencodercontrol.h>
       
    50 #include <qmediacontainercontrol.h>
       
    51 
       
    52 #include <QtCore/qdebug.h>
       
    53 #include <QtCore/qurl.h>
       
    54 #include <QtCore/qstringlist.h>
       
    55 #include <QtCore/qmetaobject.h>
       
    56 
       
    57 #include <QtMultimedia/qaudioformat.h>
       
    58 
       
    59 QTM_BEGIN_NAMESPACE
       
    60 
       
    61 /*!
       
    62     \class QMediaRecorder
       
    63     \ingroup multimedia
       
    64 
       
    65     \preliminary
       
    66     \brief The QMediaRecorder class is used for the recording of media content.
       
    67 
       
    68     The QMediaRecorder class is a high level media recording class.
       
    69     It's not intended to be used alone but for accessing the media
       
    70     recording functions of other media objects, like QRadioTuner,
       
    71     or QAudioCaptureSource.
       
    72 
       
    73     If the radio is used as a source, recording
       
    74     is only possible when the source is in appropriate state
       
    75 
       
    76     \code
       
    77     // Audio only recording
       
    78     audioSource = new QAudioCaptureSource;
       
    79     recorder = new QMediaRecorder(audioSource);
       
    80 
       
    81     QAudioEncoderSettings audioSettings;
       
    82     audioSettings.setCodec("audio/vorbis");
       
    83     audioSettings.setQuality(QtMedia::HighQuality);
       
    84 
       
    85     recorder->setEncodingSettings(audioSettings);
       
    86 
       
    87     recorder->setOutputLocation(QUrl::fromLocalFile(fileName));
       
    88     recorder->record();
       
    89     \endcode
       
    90 
       
    91 
       
    92     \sa
       
    93 */
       
    94 
       
    95 namespace
       
    96 {
       
    97 class MediaRecorderRegisterMetaTypes
       
    98 {
       
    99 public:
       
   100     MediaRecorderRegisterMetaTypes()
       
   101     {
       
   102         qRegisterMetaType<QMediaRecorder::State>("QMediaRecorder::State");
       
   103         qRegisterMetaType<QMediaRecorder::Error>("QMediaRecorder::Error");
       
   104     }
       
   105 } _registerRecorderMetaTypes;
       
   106 }
       
   107 
       
   108 
       
   109 class QMediaRecorderPrivate : public QMediaObjectPrivate
       
   110 {
       
   111     Q_DECLARE_NON_CONST_PUBLIC(QMediaRecorder)
       
   112 
       
   113 public:
       
   114     QMediaRecorderPrivate();
       
   115     void initControls();
       
   116 
       
   117     QMediaRecorderControl *control;
       
   118     QMediaContainerControl *formatControl;
       
   119     QAudioEncoderControl *audioControl;
       
   120     QVideoEncoderControl *videoControl;
       
   121 
       
   122     QMediaRecorder::State state;
       
   123     QMediaRecorder::Error error;
       
   124     QString errorString;
       
   125 
       
   126     void _q_stateChanged(QMediaRecorder::State state);
       
   127     void _q_error(int error, const QString &errorString);
       
   128 };
       
   129 
       
   130 QMediaRecorderPrivate::QMediaRecorderPrivate():
       
   131      control(0),
       
   132      formatControl(0),
       
   133      audioControl(0),
       
   134      videoControl(0),
       
   135      state(QMediaRecorder::StoppedState),
       
   136      error(QMediaRecorder::NoError)
       
   137 {
       
   138 }
       
   139 
       
   140 void QMediaRecorderPrivate::initControls()
       
   141 {
       
   142     Q_Q(QMediaRecorder);
       
   143 
       
   144     if (!service)
       
   145         return;
       
   146 
       
   147     control = qobject_cast<QMediaRecorderControl*>(service->control(QMediaRecorderControl_iid));
       
   148     formatControl = qobject_cast<QMediaContainerControl *>(service->control(QMediaContainerControl_iid));
       
   149     audioControl = qobject_cast<QAudioEncoderControl *>(service->control(QAudioEncoderControl_iid));
       
   150     videoControl = qobject_cast<QVideoEncoderControl *>(service->control(QVideoEncoderControl_iid));
       
   151 
       
   152     if (control) {
       
   153         q->connect(control, SIGNAL(stateChanged(QMediaRecorder::State)),
       
   154                 q, SLOT(_q_stateChanged(QMediaRecorder::State)));
       
   155 
       
   156         q->connect(control, SIGNAL(error(int,QString)),
       
   157                 q, SLOT(_q_error(int,QString)));
       
   158     }
       
   159 }
       
   160 
       
   161 #define ENUM_NAME(c,e,v) (c::staticMetaObject.enumerator(c::staticMetaObject.indexOfEnumerator(e)).valueToKey((v)))
       
   162 
       
   163 
       
   164 void QMediaRecorderPrivate::_q_stateChanged(QMediaRecorder::State ps)
       
   165 {
       
   166     Q_Q(QMediaRecorder);
       
   167 
       
   168     if (ps == QMediaRecorder::RecordingState)
       
   169         q->addPropertyWatch("duration");
       
   170     else
       
   171         q->removePropertyWatch("duration");
       
   172 
       
   173 //    qDebug() << "Recorder state changed:" << ENUM_NAME(QMediaRecorder,"State",ps);
       
   174     if (state != ps) {
       
   175         emit q->stateChanged(ps);
       
   176     }
       
   177 
       
   178     state = ps;
       
   179 }
       
   180 
       
   181 
       
   182 void QMediaRecorderPrivate::_q_error(int error, const QString &errorString)
       
   183 {
       
   184     Q_Q(QMediaRecorder);
       
   185 
       
   186     this->error = QMediaRecorder::Error(error);
       
   187     this->errorString = errorString;
       
   188 
       
   189     emit q->error(this->error);
       
   190 }
       
   191 
       
   192 
       
   193 /*!
       
   194     Constructs a media recorder which records the media produced by \a mediaObject.
       
   195 
       
   196     The \a parent is passed to QMediaObject.
       
   197 */
       
   198 
       
   199 QMediaRecorder::QMediaRecorder(QMediaObject *mediaObject, QObject *parent):
       
   200     QMediaObject(*new QMediaRecorderPrivate, parent, mediaObject->service())
       
   201 {
       
   202     Q_D(QMediaRecorder);
       
   203 
       
   204     d->initControls();
       
   205 }
       
   206 
       
   207 /*!
       
   208     Destroys a media recorder object.
       
   209 */
       
   210 
       
   211 QMediaRecorder::~QMediaRecorder()
       
   212 {
       
   213 }
       
   214 
       
   215 /*!
       
   216     \property QMediaRecorder::outputLocation
       
   217     \brief the destination location of media content.
       
   218 
       
   219     Setting the location can fail for example when the service supports
       
   220     only local file system locations while the network url was passed,
       
   221     or the service doesn't support media recording.
       
   222 */
       
   223 
       
   224 /*!
       
   225     Returns true if media recorder service ready to use.
       
   226 */
       
   227 bool QMediaRecorder::isAvailable() const
       
   228 {
       
   229     if (d_func()->control != NULL)
       
   230         return true;
       
   231     else
       
   232         return false;
       
   233 }
       
   234 
       
   235 /*!
       
   236     Returns the availability error code.
       
   237 */
       
   238 QtMedia::AvailabilityError QMediaRecorder::availabilityError() const
       
   239 {
       
   240     if (d_func()->control != NULL)
       
   241         return QtMedia::NoError;
       
   242     else
       
   243         return QtMedia::ServiceMissingError;
       
   244 }
       
   245 
       
   246 QUrl QMediaRecorder::outputLocation() const
       
   247 {
       
   248     return d_func()->control ? d_func()->control->outputLocation() : QUrl();
       
   249 }
       
   250 
       
   251 bool QMediaRecorder::setOutputLocation(const QUrl &location)
       
   252 {
       
   253     Q_D(QMediaRecorder);
       
   254     return d->control ? d->control->setOutputLocation(location) : false;
       
   255 }
       
   256 
       
   257 /*!
       
   258     Returns the current media recorder state.
       
   259 
       
   260     \sa QMediaRecorder::State
       
   261 */
       
   262 
       
   263 QMediaRecorder::State QMediaRecorder::state() const
       
   264 {
       
   265     return d_func()->control ? QMediaRecorder::State(d_func()->control->state()) : StoppedState;
       
   266 }
       
   267 
       
   268 /*!
       
   269     Returns the current error state.
       
   270 
       
   271     \sa errorString()
       
   272 */
       
   273 
       
   274 QMediaRecorder::Error QMediaRecorder::error() const
       
   275 {
       
   276     return d_func()->error;
       
   277 }
       
   278 
       
   279 /*!
       
   280     Returns a string describing the current error state.
       
   281 
       
   282     \sa error()
       
   283 */
       
   284 
       
   285 QString QMediaRecorder::errorString() const
       
   286 {
       
   287     return d_func()->errorString;
       
   288 }
       
   289 
       
   290 /*!
       
   291     \property QMediaRecorder::duration
       
   292 
       
   293     \brief the recorded media duration in milliseconds.
       
   294 */
       
   295 
       
   296 qint64 QMediaRecorder::duration() const
       
   297 {
       
   298     return d_func()->control ? d_func()->control->duration() : 0;
       
   299 }
       
   300 
       
   301 
       
   302 /*!
       
   303     Returns a list of MIME types of supported container formats.
       
   304 */
       
   305 QStringList QMediaRecorder::supportedContainers() const
       
   306 {
       
   307     return d_func()->formatControl ?
       
   308            d_func()->formatControl->supportedContainers() : QStringList();
       
   309 }
       
   310 
       
   311 /*!
       
   312     Returns a description of a container format \a mimeType.
       
   313 */
       
   314 QString QMediaRecorder::containerDescription(const QString &mimeType) const
       
   315 {
       
   316     return d_func()->formatControl ?
       
   317            d_func()->formatControl->containerDescription(mimeType) : QString();
       
   318 }
       
   319 
       
   320 /*!
       
   321     Returns the MIME type of the selected container format.
       
   322 */
       
   323 
       
   324 QString QMediaRecorder::containerMimeType() const
       
   325 {
       
   326     return d_func()->formatControl ?
       
   327            d_func()->formatControl->containerMimeType() : QString();
       
   328 }
       
   329 
       
   330 /*!
       
   331     Returns a list of supported audio codecs.
       
   332 */
       
   333 QStringList QMediaRecorder::supportedAudioCodecs() const
       
   334 {
       
   335     return d_func()->audioControl ?
       
   336            d_func()->audioControl->supportedAudioCodecs() : QStringList();
       
   337 }
       
   338 
       
   339 /*!
       
   340     Returns a description of an audio \a codec.
       
   341 */
       
   342 QString QMediaRecorder::audioCodecDescription(const QString &codec) const
       
   343 {
       
   344     return d_func()->audioControl ?
       
   345            d_func()->audioControl->codecDescription(codec) : QString();
       
   346 }
       
   347 
       
   348 /*!
       
   349     Returns a list of supported audio sample rates.
       
   350 
       
   351     If non null audio \a settings parameter is passed,
       
   352     the returned list is reduced to sample rates supported with partial settings applied.
       
   353 
       
   354     It can be used for example to query the list of sample rates, supported by specific audio codec.
       
   355 
       
   356     If the encoder supports arbitrary sample rates within the supported rates range,
       
   357     *\a continuous is set to true, otherwise *\a continuous is set to false.
       
   358 */
       
   359 
       
   360 QList<int> QMediaRecorder::supportedAudioSampleRates(const QAudioEncoderSettings &settings, bool *continuous) const
       
   361 {
       
   362     if (continuous)
       
   363         *continuous = false;
       
   364 
       
   365     return d_func()->audioControl ?
       
   366            d_func()->audioControl->supportedSampleRates(settings, continuous) : QList<int>();
       
   367 }
       
   368 
       
   369 /*!
       
   370     Returns a list of resolutions video can be encoded at.
       
   371 
       
   372     If non null video \a settings parameter is passed,
       
   373     the returned list is reduced to resolution supported with partial settings like video codec or framerate applied.
       
   374 
       
   375     If the encoder supports arbitrary resolutions within the supported range,
       
   376     *\a continuous is set to true, otherwise *\a continuous is set to false.
       
   377 
       
   378     \sa QVideoEncoderSettings::resolution()
       
   379 */
       
   380 QList<QSize> QMediaRecorder::supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous) const
       
   381 {
       
   382     if (continuous)
       
   383         *continuous = false;
       
   384 
       
   385     return d_func()->videoControl ?
       
   386            d_func()->videoControl->supportedResolutions(settings, continuous) : QList<QSize>();
       
   387 }
       
   388 
       
   389 /*!
       
   390     Returns a list of frame rates video can be encoded at.
       
   391 
       
   392     If non null video \a settings parameter is passed,
       
   393     the returned list is reduced to frame rates supported with partial settings like video codec or resolution applied.
       
   394 
       
   395     If the encoder supports arbitrary frame rates within the supported range,
       
   396     *\a continuous is set to true, otherwise *\a continuous is set to false.
       
   397 
       
   398     \sa QVideoEncoderSettings::frameRate()
       
   399 */
       
   400 QList<qreal> QMediaRecorder::supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous) const
       
   401 {
       
   402     if (continuous)
       
   403         *continuous = false;
       
   404 
       
   405     return d_func()->videoControl ?
       
   406            d_func()->videoControl->supportedFrameRates(settings, continuous) : QList<qreal>();
       
   407 }
       
   408 
       
   409 /*!
       
   410     Returns a list of supported video codecs.
       
   411 */
       
   412 QStringList QMediaRecorder::supportedVideoCodecs() const
       
   413 {
       
   414     return d_func()->videoControl ?
       
   415            d_func()->videoControl->supportedVideoCodecs() : QStringList();
       
   416 }
       
   417 
       
   418 /*!
       
   419     Returns a description of a video \a codec.
       
   420 
       
   421     \sa setEncodingSettings()
       
   422 */
       
   423 QString QMediaRecorder::videoCodecDescription(const QString &codec) const
       
   424 {
       
   425     return d_func()->videoControl ?
       
   426            d_func()->videoControl->videoCodecDescription(codec) : QString();
       
   427 }
       
   428 
       
   429 /*!
       
   430     Returns the audio encoder settings being used.
       
   431 
       
   432     \sa setEncodingSettings()
       
   433 */
       
   434 
       
   435 QAudioEncoderSettings QMediaRecorder::audioSettings() const
       
   436 {
       
   437     return d_func()->audioControl ?
       
   438            d_func()->audioControl->audioSettings() : QAudioEncoderSettings();
       
   439 }
       
   440 
       
   441 /*!
       
   442     Returns the video encoder settings being used.
       
   443 
       
   444     \sa setEncodingSettings()
       
   445 */
       
   446 
       
   447 QVideoEncoderSettings QMediaRecorder::videoSettings() const
       
   448 {
       
   449     return d_func()->videoControl ?
       
   450            d_func()->videoControl->videoSettings() : QVideoEncoderSettings();
       
   451 }
       
   452 
       
   453 /*!
       
   454     Sets the \a audio and \a video encoder settings and \a container format MIME type.
       
   455 
       
   456     It's only possible to change setttings when the encoder
       
   457     is in the QMediaEncoder::StoppedState state.
       
   458 
       
   459     If some parameters are not specified, or null settings are passed,
       
   460     the encoder choose the default encoding parameters, depending on
       
   461     media source properties.
       
   462     But while setEncodingSettings is optional, the backend can preload
       
   463     encoding pipeline to improve recording startup time.
       
   464 
       
   465     \sa audioSettings(), videoSettings(), containerMimeType()
       
   466 */
       
   467 
       
   468 void QMediaRecorder::setEncodingSettings(const QAudioEncoderSettings &audio,
       
   469                                          const QVideoEncoderSettings &video,
       
   470                                          const QString &container)
       
   471 {
       
   472     Q_D(QMediaRecorder);
       
   473 
       
   474     if (d->audioControl)
       
   475         d->audioControl->setAudioSettings(audio);
       
   476 
       
   477     if (d->videoControl)
       
   478         d->videoControl->setVideoSettings(video);
       
   479 
       
   480     if (d->formatControl)
       
   481         d->formatControl->setContainerMimeType(container);
       
   482 
       
   483     if (d->control)
       
   484         d->control->applySettings();
       
   485 }
       
   486 
       
   487 
       
   488 /*!
       
   489     Start recording.
       
   490 
       
   491     This is an asynchronous call, with signal
       
   492     stateCahnged(QMediaRecorder::RecordingState) being emited
       
   493     when recording started, otherwise error() signal is emited.
       
   494 */
       
   495 
       
   496 void QMediaRecorder::record()
       
   497 {
       
   498     Q_D(QMediaRecorder);
       
   499 
       
   500     // reset error
       
   501     d->error = NoError;
       
   502     d->errorString = QString();
       
   503 
       
   504     if (d->control)
       
   505         d->control->record();
       
   506 }
       
   507 
       
   508 /*!
       
   509     Pause recording.
       
   510 */
       
   511 
       
   512 void QMediaRecorder::pause()
       
   513 {
       
   514     Q_D(QMediaRecorder);
       
   515     if (d->control)
       
   516         d->control->pause();
       
   517 }
       
   518 
       
   519 /*!
       
   520     Stop recording.
       
   521 */
       
   522 
       
   523 void QMediaRecorder::stop()
       
   524 {
       
   525     Q_D(QMediaRecorder);
       
   526     if (d->control)
       
   527         d->control->stop();
       
   528 }
       
   529 
       
   530 /*!
       
   531     \enum QMediaRecorder::State
       
   532 
       
   533     \value StoppedState    The recorder is not active.
       
   534     \value RecordingState  The recorder is currently active and producing data.
       
   535     \value PausedState     The recorder is paused.
       
   536 */
       
   537 
       
   538 /*!
       
   539     \enum QMediaRecorder::Error
       
   540 
       
   541     \value NoError         No Errors.
       
   542     \value ResourceError   Device is not ready or not available.
       
   543     \value FormatError     Current format is not supported.
       
   544 */
       
   545 
       
   546 /*!
       
   547     \fn QMediaRecorder::stateChanged(State state)
       
   548 
       
   549     Signals that a media recorder's \a state has changed.
       
   550 */
       
   551 
       
   552 /*!
       
   553     \fn QMediaRecorder::durationChanged(qint64 duration)
       
   554 
       
   555     Signals that the \a duration of the recorded media has changed.
       
   556 */
       
   557 
       
   558 /*!
       
   559     \fn QMediaRecorder::error(QMediaRecorder::Error error)
       
   560 
       
   561     Signals that an \a error has occurred.
       
   562 */
       
   563 
       
   564 
       
   565 #include "moc_qmediarecorder.cpp"
       
   566 QTM_END_NAMESPACE
       
   567