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&); |
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))); |
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. |