MainWindow::MainWindow(QWidget* parent, Qt::WindowFlags flags): QMainWindow(parent, flags), d(new MainWindowPrivate) { d->selector = new QDocumentSelector(this); d->selector->setFilter(QContentFilter(QContent::Document) & (QContentFilter::mimeType("video/*") | QContentFilter::mimeType("audio/*"))); connect(d->selector, SIGNAL(documentSelected(QContent)), SLOT(documentSelected(QContent))); setCentralWidget(d->selector); d->audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this); d->videoWidget = new Phonon::VideoWidget(this); d->mediaObject = new Phonon::MediaObject(this); // metaInformationResolver = new Phonon::MediaObject(this); d->mediaObject->setTickInterval(1000); // MediaObject connect(d->mediaObject, SIGNAL(currentSourceChanged(const Phonon::MediaSource &)), SLOT(currentSourceChanged(const Phonon::MediaSource &))); connect(d->mediaObject, SIGNAL(stateChanged(Phonon::State, Phonon::State)), SLOT(stateChanged(Phonon::State, Phonon::State))); connect(d->mediaObject, SIGNAL(tick(qint64)), SLOT(tick(qint64))); /* connect(d->mediaObject, SIGNAL(metaDataChanged(QMultiMap<QString,QString>)), SLOT(metaDataChanged(QMultiMap<QString,QString>))); */ connect(d->mediaObject, SIGNAL(seekableChanged(bool)), SLOT(seekableChanged(bool))); connect(d->mediaObject, SIGNAL(hasVideoChanged(bool)), SLOT(hasVideoChanged(bool))); connect(d->mediaObject, SIGNAL(finished()), SLOT(finished())); connect(d->mediaObject, SIGNAL(prefinishMarkReached(qint32)), SLOT(prefinishMarkReached(qint32))); connect(d->mediaObject, SIGNAL(aboutToFinish()), SLOT(aboutToFinish())); connect(d->mediaObject, SIGNAL(totalTimeChanged(qint64)), SLOT(totalTimeChanged(qint64))); connect(d->mediaObject, SIGNAL(bufferStatus(int)), SLOT(bufferStatus(int))); // Meta info /* connect(metaInformationResolver, SIGNAL(stateChanged(Phonon::State,Phonon::State)), SLOT(metaStateChanged(Phonon::State, Phonon::State))); */ Phonon::createPath(d->mediaObject, d->audioOutput); Phonon::createPath(d->mediaObject, d->videoWidget); }
void MediaOutput::checkPrefinishMark( qint64 time ) { if (totalTimeInMSec > 0 && prefinishMark > 0) { const qint64 timeToEnd = totalTimeInMSec - currentTime(); if (timeToEnd < prefinishMark) emit prefinishMarkReached(timeToEnd); } }
void MediaObject::swapBuffers() { if (m_stopped || m_paused) return; m_currentTime += m_tickIntervalResolution; if (m_tickInterval) { m_tick ++; if (m_tick > (m_tickInterval - 1)) { emit tick(m_currentTime); m_tick = 0; } } if ((m_prefinishMark > 0)&& (m_prefinishMark < m_currentTime)) emit prefinishMarkReached(m_totalTime - m_currentTime); while (!m_bufferingFinished) { setState(Phonon::BufferingState); qWarning() << QLatin1String("buffer underun"); Sleep(20); } setState(Phonon::PlayingState); //if size == o then stop... if (m_nextBufferIndex) { int size = m_soundBuffer1.waveHeader->dwBufferLength = m_soundBuffer1.data.size(); if (size == buffer_size) { playBuffer(m_soundBuffer1.waveHeader); emit outOfData(m_stream, &m_soundBuffer1.data, &m_bufferingFinished); } else { playBuffer(m_soundBuffer1.waveHeader); m_stopped = true; setState(Phonon::StoppedState); emit finished(); seek(0); } } else { int size = m_soundBuffer2.waveHeader->dwBufferLength = m_soundBuffer2.data.size(); if (size == buffer_size) { playBuffer(m_soundBuffer2.waveHeader); emit outOfData(m_stream, &m_soundBuffer2.data, &m_bufferingFinished); } else { playBuffer(m_soundBuffer2.waveHeader); m_stopped = true; setState(Phonon::StoppedState); emit finished(); seek(0); } } m_nextBufferIndex =! m_nextBufferIndex; }
void Player::scrobblingToggled(bool enabled) { Settings::instance()->setScroblingEnabled(enabled); if (enabled) { if (Settings::instance()->lastFMUser().isEmpty() || Settings::instance()->lastFMSession().isEmpty()) _lastFMDialog->show(); connect(_player, SIGNAL(prefinishMarkReached(qint32)), Scrobbler::instance(), SLOT(scrobble())); connect(Scrobbler::instance(), SIGNAL(scrobblerError(int,QString)), this, SLOT(scrobblerError(int,QString))); } else {
void MediaObject::emitTick() { if (m_resumeState) { return; } if(m_tickInterval > 0) currentPos += m_tickInterval; else currentPos += 100; qint64 currentTime = currentPos; qint64 totalTime = m_totalTime; if (m_tickInterval > 0 && currentTime != m_previousTickTime) { emit tick(currentTime); m_previousTickTime = currentTime; } if (m_state == Phonon::PlayingState) { if (currentTime >= totalTime - m_prefinishMark) { if (m_prefinishMarkReachedNotEmitted) { m_prefinishMarkReachedNotEmitted = false; emit prefinishMarkReached(totalTime - currentTime); } } // Prepare load of next source if (currentTime >= totalTime - 500) { if (!m_aboutToFinishEmitted) { m_aboutToFinishEmitted = true; // track is about to finish emit aboutToFinish(); } } if(currentTime >= totalTime) { m_tickTimer->stop(); if(m_nextSource.type() != MediaSource::Invalid && m_nextSource.type() != MediaSource::Empty) { setSource(m_nextSource); m_nextSource = MediaSource(); m_pendingState = Phonon::PlayingState; } else { setState(Phonon::PausedState); currentPos = 0; emit finished(); } } } }
//utility function to save the graph to a file void MediaObject::timerEvent(QTimerEvent *e) { if (e->timerId() == m_tickTimer.timerId()) { const qint64 current = currentTime(); const qint64 total = totalTime(); if ( m_tickInterval != 0 && current > m_targetTick) { updateTargetTick(); emit tick(current); } //check that the title hasn't changed #ifndef QT_NO_PHONON_MEDIACONTROLLER if (m_autoplayTitles && m_currentTitle < _iface_availableTitles() - 1) { if (current >= total) { //we go to the next title _iface_setCurrentTitle(m_currentTitle + 1, false); emit tick(current); } return; } #endif //QT_NO_PHONON_MEDIACONTROLLER if (total) { const qint64 remaining = total - current; if (m_transitionTime < 0 && m_nextSourceReadyToStart) { if (remaining < -m_transitionTime + TIMER_INTERVAL/2) { //we need to switch graphs to run the next source in the queue (with cross-fading) switchToNextSource(); return; } else if (current < -m_transitionTime) { //we are currently crossfading for (int i = 0; i < m_audioOutputs.count(); ++i) { m_audioOutputs.at(i)->setCrossFadingProgress( currentGraph()->index(), qMin( qreal(1.), qreal(current) / qreal(-m_transitionTime))); } } } if (m_prefinishMark > 0 && !m_prefinishMarkSent && remaining < m_prefinishMark + TIMER_INTERVAL/2) { #ifdef GRAPH_DEBUG qDebug() << "DS9: emit prefinishMarkReached" << remaining << QTime::currentTime().toString(); #endif m_prefinishMarkSent = true; emit prefinishMarkReached( remaining ); } if (!m_aboutToFinishSent && remaining < PRELOAD_TIME - m_transitionTime + TIMER_INTERVAL/2) { //let's take a 2 seconds time time to actually load the next file #ifdef GRAPH_DEBUG qDebug() << "DS9: emit aboutToFinish" << remaining << QTime::currentTime().toString(); #endif m_aboutToFinishSent = true; emit aboutToFinish(); } } else { //total is 0: the stream is probably live (endless) } if (m_buffering) { ComPointer<IAMNetworkStatus> status(currentGraph()->realSource(), IID_IAMNetworkStatus); if (status) { long l; status->get_BufferingProgress(&l); emit bufferStatus(l); #ifdef GRAPH_DEBUG qDebug() << "emit bufferStatus(" << l << ")"; #endif } } } }
void MediaObject::positionChanged(quint32 position) { if (d->prefinishMark > 0 && static_cast<qint32>(position) >= d->prefinishMark) emit prefinishMarkReached(d->prefinishMark); }
void MediaObjectPrivate::setupBackendObject() { Q_Q(MediaObject); Q_ASSERT(m_backendObject); //pDebug() << Q_FUNC_INFO; #ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM QObject::connect(m_backendObject, SIGNAL(stateChanged(Phonon::State, Phonon::State)), q, SLOT(_k_stateChanged(Phonon::State, Phonon::State))); #else QObject::connect(m_backendObject, SIGNAL(stateChanged(Phonon::State, Phonon::State)), q, SIGNAL(stateChanged(Phonon::State, Phonon::State))); #endif // QT_NO_PHONON_ABSTRACTMEDIASTREAM QObject::connect(m_backendObject, SIGNAL(tick(qint64)), q, SIGNAL(tick(qint64))); QObject::connect(m_backendObject, SIGNAL(seekableChanged(bool)), q, SIGNAL(seekableChanged(bool))); #ifndef QT_NO_PHONON_VIDEO QObject::connect(m_backendObject, SIGNAL(hasVideoChanged(bool)), q, SIGNAL(hasVideoChanged(bool))); #endif //QT_NO_PHONON_VIDEO QObject::connect(m_backendObject, SIGNAL(bufferStatus(int)), q, SIGNAL(bufferStatus(int))); QObject::connect(m_backendObject, SIGNAL(finished()), q, SIGNAL(finished())); QObject::connect(m_backendObject, SIGNAL(aboutToFinish()), q, SLOT(_k_aboutToFinish())); QObject::connect(m_backendObject, SIGNAL(prefinishMarkReached(qint32)), q, SIGNAL(prefinishMarkReached(qint32))); QObject::connect(m_backendObject, SIGNAL(totalTimeChanged(qint64)), q, SIGNAL(totalTimeChanged(qint64))); QObject::connect(m_backendObject, SIGNAL(metaDataChanged(const QMultiMap<QString, QString> &)), q, SLOT(_k_metaDataChanged(const QMultiMap<QString, QString> &))); QObject::connect(m_backendObject, SIGNAL(currentSourceChanged(const MediaSource&)), q, SLOT(_k_currentSourceChanged(const MediaSource&))); // set up attributes pINTERFACE_CALL(setTickInterval(tickInterval)); pINTERFACE_CALL(setPrefinishMark(prefinishMark)); pINTERFACE_CALL(setTransitionTime(transitionTime)); switch(state) { case LoadingState: case StoppedState: case ErrorState: break; case PlayingState: case BufferingState: QTimer::singleShot(0, q, SLOT(_k_resumePlay())); break; case PausedState: QTimer::singleShot(0, q, SLOT(_k_resumePause())); break; } const State backendState = pINTERFACE_CALL(state()); if (state != backendState && state != ErrorState) { // careful: if state is ErrorState we might be switching from a // MediaObject to a ByteStream for KIO fallback. In that case the state // change to ErrorState was already suppressed. pDebug() << "emitting a state change because the backend object has been replaced"; emit q->stateChanged(backendState, state); state = backendState; } #ifndef QT_NO_PHONON_MEDIACONTROLLER for (int i = 0 ; i < interfaceList.count(); ++i) { interfaceList.at(i)->_backendObjectChanged(); } #endif //QT_NO_PHONON_MEDIACONTROLLER // set up attributes if (isPlayable(mediaSource.type())) { #ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM if (mediaSource.type() == MediaSource::Stream) { Q_ASSERT(mediaSource.stream()); mediaSource.stream()->d_func()->setMediaObjectPrivate(this); } #endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM pINTERFACE_CALL(setSource(mediaSource)); } }