qtmobility/src/multimedia/qmediaplayer.cpp
changeset 14 6fbed849b4f4
parent 11 06b8e2af4411
child 15 1f895d8a5b2b
equal deleted inserted replaced
11:06b8e2af4411 14:6fbed849b4f4
    46 #include <QtCore/qpointer.h>
    46 #include <QtCore/qpointer.h>
    47 
    47 
    48 
    48 
    49 #include "qmediaplayer.h"
    49 #include "qmediaplayer.h"
    50 
    50 
    51 #include "qmediaobject_p.h"
    51 #include <qmediaobject_p.h>
    52 #include "qmediaservice.h"
    52 #include <qmediaservice.h>
    53 #include "qmediaplayercontrol.h"
    53 #include <qmediaplayercontrol.h>
    54 #include "qmediaserviceprovider.h"
    54 #include <qmediaserviceprovider.h>
    55 #include "qmediaplaylist.h"
    55 #include <qmediaplaylist.h>
    56 #include "qmediaplaylistcontrol.h"
    56 #include <qmediaplaylistcontrol.h>
    57 #include "qvideowidget.h"
    57 #include <qmediaplaylistsourcecontrol.h>
    58 #include "qgraphicsvideoitem.h"
    58 #include <qvideowidget.h>
       
    59 #include <qgraphicsvideoitem.h>
    59 
    60 
    60 QT_BEGIN_NAMESPACE
    61 QT_BEGIN_NAMESPACE
    61 
    62 
    62 /*!
    63 /*!
    63     \class QMediaPlayer
    64     \class QMediaPlayer
    82 
    83 
    83     QVideoWidget can be used with QMediaPlayer for video rendering and QMediaPlaylist
    84     QVideoWidget can be used with QMediaPlayer for video rendering and QMediaPlaylist
    84     for accessing playlist functionality.
    85     for accessing playlist functionality.
    85 
    86 
    86     \code
    87     \code
    87         player = new QMediaPlayer;
       
    88 
       
    89         playlist = new QMediaPlaylist;
    88         playlist = new QMediaPlaylist;
    90         playlist->setMediaObject(player);
       
    91         playlist->append(QUrl("http://example.com/movie1.mp4"));
    89         playlist->append(QUrl("http://example.com/movie1.mp4"));
    92         playlist->append(QUrl("http://example.com/movie2.mp4"));
    90         playlist->append(QUrl("http://example.com/movie2.mp4"));
    93 
    91 
       
    92         player = new QMediaPlayer;
       
    93         player->setPlaylist(playlist);
       
    94 
    94         widget = new QVideoWidget;
    95         widget = new QVideoWidget;
    95         widget->setMediaObject(player);
    96         player->addVideoOutput(widget);
    96         widget->show();
    97         widget->show();
    97 
    98 
    98         player->play();
    99         player->play();
    99     \endcode
   100     \endcode
   100 
   101 
   121 
   122 
   122 public:
   123 public:
   123     QMediaPlayerPrivate()
   124     QMediaPlayerPrivate()
   124         : provider(0)
   125         : provider(0)
   125         , control(0)
   126         , control(0)
   126         , playlistControl(0)
   127         , playlistSourceControl(0)
   127         , state(QMediaPlayer::StoppedState)
   128         , state(QMediaPlayer::StoppedState)
   128         , error(QMediaPlayer::NoError)
   129         , error(QMediaPlayer::NoError)
   129         , filterStates(false)
   130         , filterStates(false)
   130         , playlist(0)
   131         , playlist(0)
   131     {}
   132     {}
   132 
   133 
   133     QMediaServiceProvider *provider;
   134     QMediaServiceProvider *provider;
   134     QMediaPlayerControl* control;
   135     QMediaPlayerControl* control;
   135     QMediaPlaylistControl* playlistControl;
   136     QMediaPlaylistSourceControl* playlistSourceControl;
   136     QMediaPlayer::State state;
   137     QMediaPlayer::State state;
   137     QMediaPlayer::Error error;
   138     QMediaPlayer::Error error;
   138     QString errorString;
   139     QString errorString;
   139     bool filterStates;
   140     bool filterStates;
   140 
   141 
       
   142     QPointer<QObject> videoOutput;
   141     QMediaPlaylist *playlist;
   143     QMediaPlaylist *playlist;
   142     QPointer<QVideoWidget> videoWidget;
       
   143     QPointer<QGraphicsVideoItem> videoItem;
       
   144 
   144 
   145     void _q_stateChanged(QMediaPlayer::State state);
   145     void _q_stateChanged(QMediaPlayer::State state);
   146     void _q_mediaStatusChanged(QMediaPlayer::MediaStatus status);
   146     void _q_mediaStatusChanged(QMediaPlayer::MediaStatus status);
   147     void _q_error(int error, const QString &errorString);
   147     void _q_error(int error, const QString &errorString);
   148     void _q_updateMedia(const QMediaContent&);
   148     void _q_updateMedia(const QMediaContent&);
   155 
   155 
   156     if (filterStates)
   156     if (filterStates)
   157         return;
   157         return;
   158 
   158 
   159     if (playlist
   159     if (playlist
   160             && !playlistControl //service should do this itself
       
   161             && ps != state && ps == QMediaPlayer::StoppedState
   160             && ps != state && ps == QMediaPlayer::StoppedState
   162             && control->mediaStatus() == QMediaPlayer::EndOfMedia) {
   161             && control->mediaStatus() == QMediaPlayer::EndOfMedia) {
   163         playlist->next();
   162         playlist->next();
   164         ps = control->state();
   163         ps = control->state();
   165     }
   164     }
   204     emit q->error(this->error);
   203     emit q->error(this->error);
   205 }
   204 }
   206 
   205 
   207 void QMediaPlayerPrivate::_q_updateMedia(const QMediaContent &media)
   206 void QMediaPlayerPrivate::_q_updateMedia(const QMediaContent &media)
   208 {
   207 {
       
   208     if (!control)
       
   209         return;
       
   210 
   209     const QMediaPlayer::State currentState = state;
   211     const QMediaPlayer::State currentState = state;
   210 
   212 
   211     filterStates = true;
   213     filterStates = true;
   212     control->setMedia(media, 0);
   214     control->setMedia(media, 0);
   213 
   215 
   233 
   235 
   234 void QMediaPlayerPrivate::_q_playlistDestroyed()
   236 void QMediaPlayerPrivate::_q_playlistDestroyed()
   235 {
   237 {
   236     playlist = 0;
   238     playlist = 0;
   237 
   239 
       
   240     if (!control)
       
   241         return;
       
   242 
       
   243     if (playlistSourceControl)
       
   244         playlistSourceControl->setPlaylist(0);
       
   245 
   238     control->setMedia(QMediaContent(), 0);
   246     control->setMedia(QMediaContent(), 0);
   239 }
   247 }
   240 
   248 
   241 static QMediaService *playerService(QMediaPlayer::Flags flags, QMediaServiceProvider *provider)
   249 static QMediaService *playerService(QMediaPlayer::Flags flags, QMediaServiceProvider *provider)
   242 {
   250 {
   272     d->provider = provider;
   280     d->provider = provider;
   273 
   281 
   274     if (d->service == 0) {
   282     if (d->service == 0) {
   275         d->error = ServiceMissingError;
   283         d->error = ServiceMissingError;
   276     } else {
   284     } else {
   277         d->control = qobject_cast<QMediaPlayerControl*>(d->service->control(QMediaPlayerControl_iid));
   285         d->control = qobject_cast<QMediaPlayerControl*>(d->service->requestControl(QMediaPlayerControl_iid));
   278         d->playlistControl = qobject_cast<QMediaPlaylistControl*>(d->service->control(QMediaPlaylistControl_iid));
   286         d->playlistSourceControl = qobject_cast<QMediaPlaylistSourceControl*>(d->service->requestControl(QMediaPlaylistSourceControl_iid));
       
   287 
   279         if (d->control != 0) {
   288         if (d->control != 0) {
   280             connect(d->control, SIGNAL(mediaChanged(QMediaContent)), SIGNAL(mediaChanged(QMediaContent)));
   289             connect(d->control, SIGNAL(mediaChanged(QMediaContent)), SIGNAL(mediaChanged(QMediaContent)));
   281             connect(d->control, SIGNAL(stateChanged(QMediaPlayer::State)), SLOT(_q_stateChanged(QMediaPlayer::State)));
   290             connect(d->control, SIGNAL(stateChanged(QMediaPlayer::State)), SLOT(_q_stateChanged(QMediaPlayer::State)));
   282             connect(d->control, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
   291             connect(d->control, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
   283                     SLOT(_q_mediaStatusChanged(QMediaPlayer::MediaStatus)));
   292                     SLOT(_q_mediaStatusChanged(QMediaPlayer::MediaStatus)));
   308 
   317 
   309 QMediaPlayer::~QMediaPlayer()
   318 QMediaPlayer::~QMediaPlayer()
   310 {
   319 {
   311     Q_D(QMediaPlayer);
   320     Q_D(QMediaPlayer);
   312 
   321 
       
   322     if (d->service) {
       
   323         if (d->control)
       
   324             d->service->releaseControl(d->control);
       
   325     }
       
   326 
   313     d->provider->releaseService(d->service);
   327     d->provider->releaseService(d->service);
   314 }
   328 }
   315 
   329 
   316 QMediaContent QMediaPlayer::media() const
   330 QMediaContent QMediaPlayer::media() const
   317 {
   331 {
   339         return d->control->mediaStream();
   353         return d->control->mediaStream();
   340 
   354 
   341     return 0;
   355     return 0;
   342 }
   356 }
   343 
   357 
       
   358 QMediaPlaylist *QMediaPlayer::playlist() const
       
   359 {
       
   360     return d_func()->playlistSourceControl ?
       
   361             d_func()->playlistSourceControl->playlist() :
       
   362             d_func()->playlist;
       
   363 }
       
   364 
       
   365 void QMediaPlayer::setPlaylist(QMediaPlaylist *playlist)
       
   366 {
       
   367     Q_D(QMediaPlayer);
       
   368 
       
   369     if (d->playlistSourceControl) {
       
   370         if (d->playlistSourceControl->playlist())
       
   371             disconnect(d->playlist, SIGNAL(destroyed()), this, SLOT(_q_playlistDestroyed()));
       
   372 
       
   373         d->playlistSourceControl->setPlaylist(playlist);
       
   374 
       
   375         if (playlist)
       
   376             connect(d->playlist, SIGNAL(destroyed()), this, SLOT(_q_playlistDestroyed()));
       
   377     } else {
       
   378         if (d->playlist) {
       
   379             disconnect(d->playlist, SIGNAL(currentMediaChanged(QMediaContent)),
       
   380                     this, SLOT(_q_updateMedia(QMediaContent)));
       
   381             disconnect(d->playlist, SIGNAL(destroyed()), this, SLOT(_q_playlistDestroyed()));
       
   382         }
       
   383 
       
   384         d->playlist = playlist;
       
   385 
       
   386         if (d->playlist) {
       
   387             connect(d->playlist, SIGNAL(currentMediaChanged(QMediaContent)),
       
   388                     this, SLOT(_q_updateMedia(QMediaContent)));
       
   389             connect(d->playlist, SIGNAL(destroyed()), this, SLOT(_q_playlistDestroyed()));
       
   390 
       
   391             if (d->control != 0)
       
   392                 d->control->setMedia(playlist->currentMedia(), 0);
       
   393         } else {
       
   394             setMedia(QMediaContent(), 0);
       
   395         }
       
   396 
       
   397     }
       
   398 }
       
   399 
   344 QMediaPlayer::State QMediaPlayer::state() const
   400 QMediaPlayer::State QMediaPlayer::state() const
   345 {
   401 {
   346     return d_func()->state;
   402     return d_func()->state;
   347 }
   403 }
   348 
   404 
   468 void QMediaPlayer::play()
   524 void QMediaPlayer::play()
   469 {
   525 {
   470     Q_D(QMediaPlayer);
   526     Q_D(QMediaPlayer);
   471 
   527 
   472     if (d->control == 0) {
   528     if (d->control == 0) {
   473         QMetaObject::invokeMethod(this, "_q_error", Qt::QueuedConnection);
   529         QMetaObject::invokeMethod(this, "_q_error", Qt::QueuedConnection,
   474                                     Q_ARG(int, QMediaPlayer::ServiceMissingError),
   530                                     Q_ARG(int, QMediaPlayer::ServiceMissingError),
   475                                     Q_ARG(QString, tr("The QMediaPlayer object does not have a valid service"));
   531                                     Q_ARG(QString, tr("The QMediaPlayer object does not have a valid service")));
   476         return;
   532         return;
   477     }
   533     }
   478 
   534 
   479     //if playlist control is available, the service should advance itself
   535     //if playlist control is available, the service should advance itself
   480     if (d->playlist && !d->playlistControl && d->playlist->currentIndex() == -1 && !d->playlist->isEmpty())
   536     if (d->playlist && d->playlist->currentIndex() == -1 && !d->playlist->isEmpty())
   481         d->playlist->setCurrentIndex(0);
   537         d->playlist->setCurrentIndex(0);
   482 
   538 
   483     // Reset error conditions
   539     // Reset error conditions
   484     d->error = NoError;
   540     d->error = NoError;
   485     d->errorString = QString();
   541     d->errorString = QString();
   567 
   623 
   568 void QMediaPlayer::setMedia(const QMediaContent &media, QIODevice *stream)
   624 void QMediaPlayer::setMedia(const QMediaContent &media, QIODevice *stream)
   569 {
   625 {
   570     Q_D(QMediaPlayer);
   626     Q_D(QMediaPlayer);
   571 
   627 
       
   628     if (playlist() && playlist()->currentMedia() != media)
       
   629         setPlaylist(0);
       
   630 
   572     if (d->control != 0)
   631     if (d->control != 0)
   573         d_func()->control->setMedia(media, stream);
   632         d_func()->control->setMedia(media, stream);
   574 }
   633 }
   575 
   634 
   576 /*!
   635 /*!
   577     \internal
   636     \internal
   578 */
   637 */
   579 
   638 
   580 void QMediaPlayer::bind(QObject *obj)
   639 bool QMediaPlayer::bind(QObject *obj)
   581 {
   640 {
   582     Q_D(QMediaPlayer);
   641     return QMediaObject::bind(obj);
   583 
       
   584     if (d->control != 0) {
       
   585         QMediaPlaylist *playlist = qobject_cast<QMediaPlaylist*>(obj);
       
   586 
       
   587         if (playlist) {
       
   588             if (d->playlist)
       
   589                 d->playlist->setMediaObject(0);
       
   590 
       
   591             d->playlist = playlist;
       
   592             connect(d->playlist, SIGNAL(currentMediaChanged(QMediaContent)),
       
   593                     this, SLOT(_q_updateMedia(QMediaContent)));
       
   594             connect(d->playlist, SIGNAL(destroyed()), this, SLOT(_q_playlistDestroyed()));
       
   595 
       
   596             setMedia(playlist->currentMedia());
       
   597 
       
   598             return;
       
   599         }
       
   600 
       
   601         QVideoWidget *videoWidget = qobject_cast<QVideoWidget*>(obj);
       
   602         QGraphicsVideoItem *videoItem = qobject_cast<QGraphicsVideoItem*>(obj);
       
   603 
       
   604         if (videoWidget || videoItem) {
       
   605             //detach the current video output
       
   606             if (d->videoWidget) {
       
   607                 d->videoWidget->setMediaObject(0);
       
   608                 d->videoWidget = 0;
       
   609             }
       
   610 
       
   611             if (d->videoItem) {
       
   612                 d->videoItem->setMediaObject(0);
       
   613                 d->videoItem = 0;
       
   614             }
       
   615         }
       
   616 
       
   617         if (videoWidget)
       
   618             d->videoWidget = videoWidget;
       
   619 
       
   620         if (videoItem)
       
   621             d->videoItem = videoItem;
       
   622     }
       
   623 }
   642 }
   624 
   643 
   625 /*!
   644 /*!
   626     \internal
   645     \internal
   627 */
   646 */
   628 
   647 
   629 void QMediaPlayer::unbind(QObject *obj)
   648 void QMediaPlayer::unbind(QObject *obj)
   630 {
   649 {
   631     Q_D(QMediaPlayer);
   650     QMediaObject::unbind(obj);
   632 
       
   633     if (obj == d->videoWidget) {
       
   634         d->videoWidget = 0;
       
   635     } else if (obj == d->videoItem) {
       
   636         d->videoItem = 0;
       
   637     } else if (obj == d->playlist) {
       
   638         disconnect(d->playlist, SIGNAL(currentMediaChanged(QMediaContent)),
       
   639                 this, SLOT(_q_updateMedia(QMediaContent)));
       
   640         disconnect(d->playlist, SIGNAL(destroyed()), this, SLOT(_q_playlistDestroyed()));
       
   641         d->playlist = 0;
       
   642         setMedia(QMediaContent());
       
   643     }
       
   644 }
   651 }
   645 
   652 
   646 /*!
   653 /*!
   647     Returns the level of support a media player has for a \a mimeType and a set of \a codecs.
   654     Returns the level of support a media player has for a \a mimeType and a set of \a codecs.
   648 
   655 
   649     The \a flags argument allows additional requirements such as performance indicators to be
   656     The \a flags argument allows additional requirements such as performance indicators to be
   650     specified.
   657     specified.
   651 */
   658 */
   652 QtMediaServices::SupportEstimate QMediaPlayer::hasSupport(const QString &mimeType,
   659 QtMultimedia::SupportEstimate QMediaPlayer::hasSupport(const QString &mimeType,
   653                                                const QStringList& codecs,
   660                                                const QStringList& codecs,
   654                                                Flags flags)
   661                                                Flags flags)
   655 {
   662 {
   656     return QMediaServiceProvider::defaultServiceProvider()->hasSupport(QByteArray(Q_MEDIASERVICE_MEDIAPLAYER),
   663     return QMediaServiceProvider::defaultServiceProvider()->hasSupport(QByteArray(Q_MEDIASERVICE_MEDIAPLAYER),
   657                                                                     mimeType,
   664                                                                     mimeType,
   669 {
   676 {
   670     return QMediaServiceProvider::defaultServiceProvider()->supportedMimeTypes(QByteArray(Q_MEDIASERVICE_MEDIAPLAYER),
   677     return QMediaServiceProvider::defaultServiceProvider()->supportedMimeTypes(QByteArray(Q_MEDIASERVICE_MEDIAPLAYER),
   671                                                                                flags);
   678                                                                                flags);
   672 }
   679 }
   673 
   680 
       
   681 /*!
       
   682     Attach a QVideoWidget video \a output to the media player.
       
   683 
       
   684     If the media player has already video output attached,
       
   685     it will be replaced with a new one.
       
   686 
       
   687     \sa setVideoOutput(QGraphicsVideoItem*)
       
   688 */
       
   689 void QMediaPlayer::setVideoOutput(QVideoWidget *output)
       
   690 {
       
   691     Q_D(QMediaPlayer);
       
   692 
       
   693     if (d->videoOutput)
       
   694         unbind(d->videoOutput);
       
   695 
       
   696     d->videoOutput = output;
       
   697 
       
   698     if (d->videoOutput)
       
   699         bind(d->videoOutput);
       
   700 }
       
   701 
       
   702 /*!
       
   703     Attach a QGraphicsVideoItem video \a output to the media player.
       
   704 
       
   705     If the media player has already video output attached,
       
   706     it will be replaced with a new one.
       
   707 
       
   708     \sa setVideoOutput(QVideoWidget*)
       
   709 */
       
   710 void QMediaPlayer::setVideoOutput(QGraphicsVideoItem *output)
       
   711 {
       
   712     Q_D(QMediaPlayer);
       
   713 
       
   714     if (d->videoOutput)
       
   715         unbind(d->videoOutput);
       
   716 
       
   717     d->videoOutput = output;
       
   718 
       
   719     if (d->videoOutput)
       
   720         bind(d->videoOutput);
       
   721 }
   674 
   722 
   675 // Enums
   723 // Enums
   676 /*!
   724 /*!
   677     \enum QMediaPlayer::State
   725     \enum QMediaPlayer::State
   678 
   726 
   794 
   842 
   795     \sa QMediaContent
   843     \sa QMediaContent
   796 */
   844 */
   797 
   845 
   798 /*!
   846 /*!
       
   847     \property QMediaPlayer::playlist
       
   848     \brief the media playlist being used by the player object.
       
   849 
       
   850     The player object will use the current playlist item for selection of the content to
       
   851     be played.
       
   852 
       
   853     By default this property is set to null.
       
   854 
       
   855     If the media playlist is used as a source, QMediaPlayer::media is updated with
       
   856     a current playlist item. The current source should be selected with
       
   857     QMediaPlaylist::setCurrentIndex(int) instead of QMediaPlayer::setMedia(),
       
   858     otherwise the current playlist will be discarded.
       
   859 
       
   860     \sa QMediaContent
       
   861 */
       
   862 
       
   863 
       
   864 /*!
   799     \property QMediaPlayer::mediaStatus
   865     \property QMediaPlayer::mediaStatus
   800     \brief the status of the current media stream.
   866     \brief the status of the current media stream.
   801 
   867 
   802     The stream status describes how the playback of the current stream is
   868     The stream status describes how the playback of the current stream is
   803     progressing.
   869     progressing.