1 /*****************************************************************************
2 * VLC backend for the Phonon library *
3 * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
4 * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
5 * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
7 * This program is free software; you can redistribute it and/or *
8 * modify it under the terms of the GNU Lesser General Public *
9 * License as published by the Free Software Foundation; either *
10 * version 3 of the License, or (at your option) any later version. *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
15 * Lesser General Public License for more details. *
17 * You should have received a copy of the GNU Lesser General Public *
18 * License along with this package; if not, write to the Free Software *
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
20 *****************************************************************************/
22 #include "mediaobject.h"
24 #include "seekstack.h"
26 #include <QtCore/QUrl>
27 #include <QtCore/QMetaType>
28 #include <QtCore/QTimer>
30 //Time in milliseconds before sending aboutToFinish() signal
32 static const int ABOUT_TO_FINISH_TIME = 2000;
38 MediaObject::MediaObject(QObject *p_parent)
41 currentState = Phonon::LoadingState;
42 i_video_widget_id = 0;
43 b_prefinish_mark_reached_emitted = false;
44 b_about_to_finish_emitted = false;
45 i_transition_time = 0;
47 // By default, no tick() signal
48 // FIXME: Not implemented yet
51 qRegisterMetaType<QMultiMap<QString, QString> >("QMultiMap<QString, QString>");
53 connect(this, SIGNAL(stateChanged(Phonon::State)),
54 SLOT(stateChangedInternal(Phonon::State)));
56 connect(this, SIGNAL(tickInternal(qint64)),
57 SLOT(tickInternalSlot(qint64)));
60 MediaObject::~MediaObject()
64 void MediaObject::setVideoWidgetId(WId i_widget_id)
66 i_video_widget_id = i_widget_id;
69 void MediaObject::play()
71 qDebug() << __FUNCTION__;
73 if (currentState == Phonon::PausedState) {
81 void MediaObject::seek(qint64 milliseconds)
83 static SeekStack *p_stack = new SeekStack(this);
85 p_stack->pushSeek(milliseconds);
87 qint64 currentTime = this->currentTime();
88 qint64 totalTime = this->totalTime();
90 if (currentTime < totalTime - i_prefinish_mark) {
91 b_prefinish_mark_reached_emitted = false;
93 if (currentTime < totalTime - ABOUT_TO_FINISH_TIME) {
94 b_about_to_finish_emitted = false;
98 void MediaObject::tickInternalSlot(qint64 currentTime)
100 qint64 totalTime = this->totalTime();
102 if (i_tick_interval > 0) {
103 // If _tickInternal == 0 means tick() signal is disabled
104 // Default is _tickInternal = 0
105 emit tick(currentTime);
108 if (currentState == Phonon::PlayingState) {
109 if (currentTime >= totalTime - i_prefinish_mark) {
110 if (!b_prefinish_mark_reached_emitted) {
111 b_prefinish_mark_reached_emitted = true;
112 emit prefinishMarkReached(totalTime - currentTime);
115 if (currentTime >= totalTime - ABOUT_TO_FINISH_TIME) {
116 if (!b_about_to_finish_emitted) {
117 // Track is about to finish
118 b_about_to_finish_emitted = true;
119 emit aboutToFinish();
125 void MediaObject::loadMedia(const QString & filename)
127 // Default MediaObject state is Phonon::LoadingState
128 currentState = Phonon::LoadingState;
131 loadMediaInternal(filename);
134 void MediaObject::resume()
139 qint32 MediaObject::tickInterval() const
141 return i_tick_interval;
144 void MediaObject::setTickInterval(qint32 tickInterval)
146 i_tick_interval = tickInterval;
147 // if (_tickInterval <= 0) {
148 // _tickTimer->setInterval(50);
150 // _tickTimer->setInterval(_tickInterval);
154 qint64 MediaObject::currentTime() const
157 Phonon::State st = state();
160 case Phonon::PausedState:
161 time = currentTimeInternal();
163 case Phonon::BufferingState:
164 time = currentTimeInternal();
166 case Phonon::PlayingState:
167 time = currentTimeInternal();
169 case Phonon::StoppedState:
172 case Phonon::LoadingState:
175 case Phonon::ErrorState:
179 qCritical() << __FUNCTION__ << "Error: unsupported Phonon::State:" << st;
185 Phonon::State MediaObject::state() const
190 Phonon::ErrorType MediaObject::errorType() const
192 return Phonon::NormalError;
195 MediaSource MediaObject::source() const
200 void MediaObject::setSource(const MediaSource & source)
202 qDebug() << __FUNCTION__;
204 mediaSource = source;
206 switch (source.type()) {
207 case MediaSource::Invalid:
209 case MediaSource::LocalFile:
210 loadMedia(mediaSource.fileName());
212 case MediaSource::Url:
213 loadMedia(mediaSource.url().toString());
215 case MediaSource::Disc:
216 switch (source.discType()) {
218 qCritical() << __FUNCTION__
219 << "Error: the MediaSource::Disc doesn't specify which one (Phonon::NoDisc)";
222 loadMedia(mediaSource.deviceName());
225 loadMedia("dvd://" + mediaSource.deviceName());
228 loadMedia(mediaSource.deviceName());
231 qCritical() << __FUNCTION__ << "Error: unsupported MediaSource::Disc:" << source.discType();
235 case MediaSource::Stream:
238 qCritical() << __FUNCTION__
239 << "Error: unsupported MediaSource:"
245 void MediaObject::setNextSource(const MediaSource & source)
250 qint32 MediaObject::prefinishMark() const
252 return i_prefinish_mark;
255 void MediaObject::setPrefinishMark(qint32 msecToEnd)
257 i_prefinish_mark = msecToEnd;
258 if (currentTime() < totalTime() - i_prefinish_mark) {
259 // Not about to finish
260 b_prefinish_mark_reached_emitted = false;
264 qint32 MediaObject::transitionTime() const
266 return i_transition_time;
269 void MediaObject::setTransitionTime(qint32 time)
271 i_transition_time = time;
274 void MediaObject::stateChangedInternal(Phonon::State newState)
276 qDebug() << __FUNCTION__ << "newState:" << newState
277 << "previousState:" << currentState ;
279 if (newState == currentState) {
285 Phonon::State previousState = currentState;
286 currentState = newState;
287 emit stateChanged(currentState, previousState);
291 } // Namespace Phonon::VLC