qtmobility/plugins/declarative/multimedia/qdeclarativemediabase.cpp
changeset 14 6fbed849b4f4
equal deleted inserted replaced
11:06b8e2af4411 14:6fbed849b4f4
       
     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 "qdeclarativemediabase_p.h"
       
    43 
       
    44 #include <QtCore/qcoreevent.h>
       
    45 #include <QtCore/qurl.h>
       
    46 
       
    47 #include <qmediaplayercontrol.h>
       
    48 #include <qmediaservice.h>
       
    49 #include <qmediaserviceprovider.h>
       
    50 #include <qmetadatareadercontrol.h>
       
    51 #include "qmetadatacontrolmetaobject_p.h"
       
    52 
       
    53 
       
    54 
       
    55 QT_BEGIN_NAMESPACE
       
    56 
       
    57 
       
    58 class QDeclarativeMediaBaseObject : public QMediaObject
       
    59 {
       
    60 public:
       
    61     QDeclarativeMediaBaseObject(QMediaService *service)
       
    62         : QMediaObject(0, service)
       
    63     {
       
    64     }
       
    65 };
       
    66 
       
    67 class QDeclarativeMediaBasePlayerControl : public QMediaPlayerControl
       
    68 {
       
    69 public:
       
    70     QDeclarativeMediaBasePlayerControl(QObject *parent)
       
    71         : QMediaPlayerControl(parent)
       
    72     {
       
    73     }
       
    74 
       
    75     QMediaPlayer::State state() const { return QMediaPlayer::StoppedState; }
       
    76     QMediaPlayer::MediaStatus mediaStatus() const { return QMediaPlayer::NoMedia; }
       
    77 
       
    78     qint64 duration() const { return 0; }
       
    79     qint64 position() const { return 0; }
       
    80     void setPosition(qint64) {}
       
    81     int volume() const { return 0; }
       
    82     void setVolume(int) {}
       
    83     bool isMuted() const { return false; }
       
    84     void setMuted(bool) {}
       
    85     int bufferStatus() const { return 0; }
       
    86     bool isAudioAvailable() const { return false; }
       
    87     bool isVideoAvailable() const { return false; }
       
    88     bool isSeekable() const { return false; }
       
    89     QMediaTimeRange availablePlaybackRanges() const { return QMediaTimeRange(); }
       
    90     qreal playbackRate() const { return 1; }
       
    91     void setPlaybackRate(qreal) {}
       
    92     QMediaContent media() const { return QMediaContent(); }
       
    93     const QIODevice *mediaStream() const { return 0; }
       
    94     void setMedia(const QMediaContent &, QIODevice *) {}
       
    95 
       
    96     void play() {}
       
    97     void pause() {}
       
    98     void stop() {}
       
    99 };
       
   100 
       
   101 class QDeclarativeMediaBaseAnimation : public QObject
       
   102 {
       
   103 public:
       
   104     QDeclarativeMediaBaseAnimation(QDeclarativeMediaBase *media)
       
   105         : m_media(media)
       
   106     {
       
   107     }
       
   108 
       
   109     void start() { if (!m_timer.isActive()) m_timer.start(500, this); }
       
   110     void stop() { m_timer.stop(); }
       
   111 
       
   112 protected:
       
   113     void timerEvent(QTimerEvent *event)
       
   114     {
       
   115         if (event->timerId() == m_timer.timerId()) {
       
   116             event->accept();
       
   117 
       
   118             if (m_media->m_state == QMediaPlayer::PlayingState)
       
   119                 emit m_media->positionChanged();
       
   120             if (m_media->m_status == QMediaPlayer::BufferingMedia || QMediaPlayer::StalledMedia)
       
   121                 emit m_media->bufferProgressChanged();
       
   122         } else {
       
   123             QObject::timerEvent(event);
       
   124         }
       
   125     }
       
   126 
       
   127 private:
       
   128     QDeclarativeMediaBase *m_media;
       
   129     QBasicTimer m_timer;
       
   130 };
       
   131 
       
   132 void QDeclarativeMediaBase::_q_stateChanged(QMediaPlayer::State state)
       
   133 {
       
   134     if (m_state == state)
       
   135         return;
       
   136 
       
   137     switch (state) {
       
   138     case QMediaPlayer::StoppedState: {
       
   139             emit stopped();
       
   140 
       
   141             if (m_playing) {
       
   142                 m_playing = false;
       
   143                 emit playingChanged();
       
   144             }
       
   145         }
       
   146         break;
       
   147     case QMediaPlayer::PausedState: {
       
   148             emit paused();
       
   149 
       
   150             if (!m_paused) {
       
   151                 m_paused = true;
       
   152                 emit pausedChanged();
       
   153             }
       
   154 
       
   155             if (m_state == QMediaPlayer::StoppedState)
       
   156                 emit started();
       
   157         }
       
   158         break;
       
   159     case QMediaPlayer::PlayingState: {
       
   160             if (m_state == QMediaPlayer::PausedState)
       
   161                 emit resumed();
       
   162             else
       
   163                 emit started();
       
   164 
       
   165            if (m_paused) {
       
   166                m_paused = false;
       
   167                emit pausedChanged();
       
   168            }
       
   169         }
       
   170         break;
       
   171     }
       
   172 
       
   173     // Check
       
   174     if (state == QMediaPlayer::PlayingState
       
   175             || m_status == QMediaPlayer::BufferingMedia
       
   176             || m_status == QMediaPlayer::StalledMedia) {
       
   177         m_animation->start();
       
   178     }
       
   179     else {
       
   180         m_animation->stop();
       
   181     }
       
   182 
       
   183     m_state = state;
       
   184 }
       
   185 
       
   186 void QDeclarativeMediaBase::_q_mediaStatusChanged(QMediaPlayer::MediaStatus status)
       
   187 {
       
   188     if (status != m_status) {
       
   189         m_status = status;
       
   190 
       
   191         switch (status) {
       
   192         case QMediaPlayer::LoadedMedia:
       
   193             emit loaded();
       
   194             break;
       
   195         case QMediaPlayer::BufferingMedia:
       
   196             emit buffering();
       
   197             break;
       
   198         case QMediaPlayer::BufferedMedia:
       
   199             emit buffered();
       
   200             break;
       
   201         case QMediaPlayer::StalledMedia:
       
   202             emit stalled();
       
   203             break;
       
   204         case QMediaPlayer::EndOfMedia:
       
   205             emit endOfMedia();
       
   206             break;
       
   207         default:
       
   208             break;
       
   209         }
       
   210 
       
   211         emit statusChanged();
       
   212 
       
   213         if (m_state == QMediaPlayer::PlayingState
       
   214                 || m_status == QMediaPlayer::BufferingMedia
       
   215                 || m_status == QMediaPlayer::StalledMedia) {
       
   216             m_animation->start();
       
   217         } else {
       
   218             m_animation->stop();
       
   219         }
       
   220     }
       
   221 }
       
   222 
       
   223 void QDeclarativeMediaBase::_q_metaDataChanged()
       
   224 {
       
   225     m_metaObject->metaDataChanged();
       
   226 }
       
   227 
       
   228 QDeclarativeMediaBase::QDeclarativeMediaBase()
       
   229     : m_paused(false)
       
   230     , m_playing(false)
       
   231     , m_autoLoad(true)
       
   232     , m_loaded(false)
       
   233     , m_muted(false)
       
   234     , m_position(0)
       
   235     , m_vol(1.0)
       
   236     , m_playbackRate(1.0)
       
   237     , m_mediaService(0)
       
   238     , m_playerControl(0)
       
   239     , m_mediaObject(0)
       
   240     , m_mediaProvider(0)
       
   241     , m_metaDataControl(0)
       
   242     , m_metaObject(0)
       
   243     , m_animation(0)
       
   244     , m_state(QMediaPlayer::StoppedState)
       
   245     , m_status(QMediaPlayer::NoMedia)
       
   246     , m_error(QMediaPlayer::ServiceMissingError)
       
   247 {
       
   248 }
       
   249 
       
   250 QDeclarativeMediaBase::~QDeclarativeMediaBase()
       
   251 {
       
   252 }
       
   253 
       
   254 void QDeclarativeMediaBase::shutdown()
       
   255 {
       
   256     delete m_metaObject;
       
   257     delete m_mediaObject;
       
   258 
       
   259     if (m_mediaProvider)
       
   260         m_mediaProvider->releaseService(m_mediaService);
       
   261 
       
   262     delete m_animation;
       
   263 
       
   264 }
       
   265 
       
   266 void QDeclarativeMediaBase::setObject(QObject *object)
       
   267 {
       
   268     if ((m_mediaProvider = QMediaServiceProvider::defaultServiceProvider())) {
       
   269         if ((m_mediaService = m_mediaProvider->requestService(Q_MEDIASERVICE_MEDIAPLAYER))) {
       
   270             m_playerControl = qobject_cast<QMediaPlayerControl *>(
       
   271                     m_mediaService->requestControl(QMediaPlayerControl_iid));
       
   272             m_metaDataControl = qobject_cast<QMetaDataReaderControl *>(
       
   273                     m_mediaService->requestControl(QMetaDataReaderControl_iid));
       
   274             m_mediaObject = new QDeclarativeMediaBaseObject(m_mediaService);
       
   275         }
       
   276     }
       
   277 
       
   278     if (m_playerControl) {
       
   279         QObject::connect(m_playerControl, SIGNAL(stateChanged(QMediaPlayer::State)),
       
   280                 object, SLOT(_q_stateChanged(QMediaPlayer::State)));
       
   281         QObject::connect(m_playerControl, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
       
   282                 object, SLOT(_q_mediaStatusChanged(QMediaPlayer::MediaStatus)));
       
   283         QObject::connect(m_playerControl, SIGNAL(mediaChanged(QMediaContent)),
       
   284                 object, SIGNAL(sourceChanged()));
       
   285         QObject::connect(m_playerControl, SIGNAL(durationChanged(qint64)),
       
   286                 object, SIGNAL(durationChanged()));
       
   287         QObject::connect(m_playerControl, SIGNAL(positionChanged(qint64)),
       
   288                 object, SIGNAL(positionChanged()));
       
   289         QObject::connect(m_playerControl, SIGNAL(volumeChanged(int)),
       
   290                 object, SIGNAL(volumeChanged()));
       
   291         QObject::connect(m_playerControl, SIGNAL(mutedChanged(bool)),
       
   292                 object, SIGNAL(mutedChanged()));
       
   293         QObject::connect(m_playerControl, SIGNAL(bufferStatusChanged(int)),
       
   294                 object, SIGNAL(bufferProgressChanged()));
       
   295         QObject::connect(m_playerControl, SIGNAL(seekableChanged(bool)),
       
   296                 object, SIGNAL(seekableChanged()));
       
   297         QObject::connect(m_playerControl, SIGNAL(playbackRateChanged(qreal)),
       
   298                 object, SIGNAL(playbackRateChanged()));
       
   299         QObject::connect(m_playerControl, SIGNAL(error(int,QString)),
       
   300                 object, SLOT(_q_error(int,QString)));
       
   301 
       
   302         m_animation = new QDeclarativeMediaBaseAnimation(this);
       
   303         m_error = QMediaPlayer::NoError;
       
   304     } else {
       
   305         m_playerControl = new QDeclarativeMediaBasePlayerControl(object);
       
   306     }
       
   307 
       
   308     if (m_metaDataControl) {
       
   309         m_metaObject = new QMetaDataControlMetaObject(m_metaDataControl, object);
       
   310 
       
   311         QObject::connect(m_metaDataControl, SIGNAL(metaDataChanged()),
       
   312                 object, SLOT(_q_metaDataChanged()));
       
   313     }
       
   314 
       
   315     // Init
       
   316     m_playerControl->setVolume(m_vol * 100);
       
   317     m_playerControl->setMuted(m_muted);
       
   318     m_playerControl->setPlaybackRate(m_playbackRate);
       
   319 
       
   320     if (!m_source.isEmpty() && (m_autoLoad || m_playing)) // Override autoLoad if playing set
       
   321         m_playerControl->setMedia(m_source, 0);
       
   322 
       
   323     if (m_paused)
       
   324         m_playerControl->pause();
       
   325     else if (m_playing)
       
   326         m_playerControl->play();
       
   327 
       
   328     if ((m_playing || m_paused) && m_position > 0)
       
   329         m_playerControl->setPosition(m_position);
       
   330 }
       
   331 
       
   332 
       
   333 // Properties
       
   334 
       
   335 QUrl QDeclarativeMediaBase::source() const
       
   336 {
       
   337     return m_source;
       
   338 }
       
   339 
       
   340 void QDeclarativeMediaBase::setSource(const QUrl &url)
       
   341 {
       
   342     if (url == m_source)
       
   343         return;
       
   344 
       
   345     m_source = url;
       
   346     m_loaded = false;
       
   347     if (m_playerControl != 0 && m_autoLoad) {
       
   348         if (m_error != QMediaPlayer::ServiceMissingError && m_error != QMediaPlayer::NoError) {
       
   349             m_error = QMediaPlayer::NoError;
       
   350             m_errorString = QString();
       
   351 
       
   352             emit errorChanged();
       
   353         }
       
   354 
       
   355         m_playerControl->setMedia(m_source, 0);
       
   356         m_loaded = true;
       
   357     }
       
   358     else
       
   359         emit sourceChanged();
       
   360 }
       
   361 
       
   362 bool QDeclarativeMediaBase::isAutoLoad() const
       
   363 {
       
   364     return m_autoLoad;
       
   365 }
       
   366 
       
   367 void QDeclarativeMediaBase::setAutoLoad(bool autoLoad)
       
   368 {
       
   369     if (m_autoLoad == autoLoad)
       
   370         return;
       
   371 
       
   372     m_autoLoad = autoLoad;
       
   373     emit autoLoadChanged();
       
   374 }
       
   375 
       
   376 bool QDeclarativeMediaBase::isPlaying() const
       
   377 {
       
   378     return m_playing;
       
   379 }
       
   380 
       
   381 void QDeclarativeMediaBase::setPlaying(bool playing)
       
   382 {
       
   383     if (playing == m_playing)
       
   384         return;
       
   385 
       
   386     m_playing = playing;
       
   387     if (m_playerControl != 0) {
       
   388         if (m_playing) {
       
   389             if (!m_autoLoad && !m_loaded) {
       
   390                 m_playerControl->setMedia(m_source, 0);
       
   391                 m_playerControl->setPosition(m_position);
       
   392                 m_loaded = true;
       
   393             }
       
   394 
       
   395             if (!m_paused)
       
   396                 m_playerControl->play();
       
   397             else
       
   398                 m_playerControl->pause();
       
   399         }
       
   400         else if (m_state != QMediaPlayer::StoppedState)
       
   401             m_playerControl->stop();
       
   402     }
       
   403 
       
   404     emit playingChanged();
       
   405 }
       
   406 
       
   407 bool QDeclarativeMediaBase::isPaused() const
       
   408 {
       
   409     return m_paused;
       
   410 }
       
   411 
       
   412 void QDeclarativeMediaBase::setPaused(bool paused)
       
   413 {
       
   414     if (m_paused == paused)
       
   415         return;
       
   416 
       
   417     m_paused = paused;
       
   418     if (m_playerControl != 0) {
       
   419         if (!m_autoLoad && !m_loaded) {
       
   420             m_playerControl->setMedia(m_source, 0);
       
   421             m_playerControl->setPosition(m_position);
       
   422             m_loaded = true;
       
   423         }
       
   424 
       
   425         if (m_paused && m_state == QMediaPlayer::PlayingState) {
       
   426             m_playerControl->pause();
       
   427         }
       
   428         else if (!m_paused && m_playing) {
       
   429             m_playerControl->play();
       
   430         }
       
   431     }
       
   432 
       
   433     emit pausedChanged();
       
   434 }
       
   435 
       
   436 int QDeclarativeMediaBase::duration() const
       
   437 {
       
   438     return m_playerControl == 0 ? 0 : m_playerControl->duration();
       
   439 }
       
   440 
       
   441 int QDeclarativeMediaBase::position() const
       
   442 {
       
   443     return m_playerControl == 0 ? m_position : m_playerControl->position();
       
   444 }
       
   445 
       
   446 void QDeclarativeMediaBase::setPosition(int position)
       
   447 {
       
   448     if (m_position == position)
       
   449         return;
       
   450 
       
   451     m_position = position;
       
   452     if (m_playerControl != 0)
       
   453         m_playerControl->setPosition(m_position);
       
   454     else
       
   455         emit positionChanged();
       
   456 }
       
   457 
       
   458 qreal QDeclarativeMediaBase::volume() const
       
   459 {
       
   460     return m_playerControl == 0 ? m_vol : qreal(m_playerControl->volume()) / 100;
       
   461 }
       
   462 
       
   463 void QDeclarativeMediaBase::setVolume(qreal volume)
       
   464 {
       
   465     if (m_vol == volume)
       
   466         return;
       
   467 
       
   468     m_vol = volume;
       
   469 
       
   470     if (m_playerControl != 0)
       
   471         m_playerControl->setVolume(qRound(volume * 100));
       
   472     else
       
   473         emit volumeChanged();
       
   474 }
       
   475 
       
   476 bool QDeclarativeMediaBase::isMuted() const
       
   477 {
       
   478     return m_playerControl == 0 ? m_muted : m_playerControl->isMuted();
       
   479 }
       
   480 
       
   481 void QDeclarativeMediaBase::setMuted(bool muted)
       
   482 {
       
   483     if (m_muted == muted)
       
   484         return;
       
   485 
       
   486     m_muted = muted;
       
   487 
       
   488     if (m_playerControl != 0)
       
   489         m_playerControl->setMuted(muted);
       
   490     else
       
   491         emit mutedChanged();
       
   492 }
       
   493 
       
   494 qreal QDeclarativeMediaBase::bufferProgress() const
       
   495 {
       
   496     return m_playerControl == 0 ? 0 : qreal(m_playerControl->bufferStatus()) / 100;
       
   497 }
       
   498 
       
   499 bool QDeclarativeMediaBase::isSeekable() const
       
   500 {
       
   501     return m_playerControl == 0 ? false : m_playerControl->isSeekable();
       
   502 }
       
   503 
       
   504 qreal QDeclarativeMediaBase::playbackRate() const
       
   505 {
       
   506     return m_playbackRate;
       
   507 }
       
   508 
       
   509 void QDeclarativeMediaBase::setPlaybackRate(qreal rate)
       
   510 {
       
   511     if (m_playbackRate == rate)
       
   512         return;
       
   513 
       
   514     m_playbackRate = rate;
       
   515 
       
   516     if (m_playerControl != 0)
       
   517         m_playerControl->setPlaybackRate(m_playbackRate);
       
   518     else
       
   519         emit playbackRateChanged();
       
   520 }
       
   521 
       
   522 QString QDeclarativeMediaBase::errorString() const
       
   523 {
       
   524     return m_errorString;
       
   525 }
       
   526 
       
   527 QT_END_NAMESPACE
       
   528