diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index 01b05e463..149cab3fd 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -437,10 +437,11 @@ bool AudioEngine::canSeek() { Q_D( AudioEngine ); -/* - if ( d->playlist.isNull() ) - return true; -*/ + + if ( !d->audioOutput->isSeekable() ) { + return false; + } + return !d->playlist.isNull() && ( d->playlist.data()->seekRestrictions() != PlaylistModes::NoSeek ); } @@ -1249,7 +1250,7 @@ AudioEngine::currentTrackTotalTime() const // libVLC doesn't report total duration for stream data (imem://) // But it's not a real problem for playback, since // EndOfStream is emitted by libVLC itself - if ( d_func()->audioOutput->totalTime() == 0 && d_func()->currentTrack && d_func()->currentTrack->track() ) { + if ( d_func()->audioOutput->totalTime() <= 0 && d_func()->currentTrack && d_func()->currentTrack->track() ) { return d_func()->currentTrack->track()->duration() * 1000 + 1000; } return d_func()->audioOutput->totalTime(); diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp index ebc8a29e8..35371029e 100644 --- a/src/libtomahawk/audio/AudioOutput.cpp +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -53,6 +53,7 @@ AudioOutput::instance() AudioOutput::AudioOutput( QObject* parent ) : QObject( parent ) , currentState( Stopped ) + , seekable( true ) , muted( false ) , m_autoDelete ( true ) , m_volume( 1.0 ) @@ -168,9 +169,11 @@ AudioOutput::setCurrentSource(MediaStream* stream) if ( m_autoDelete && currentStream != 0 ) { delete currentStream; } + currentStream = stream; m_totalTime = 0; m_currentTime = 0; + seekable = true; QByteArray url; switch (stream->type()) { @@ -262,8 +265,9 @@ AudioOutput::setCurrentTime( qint64 time ) { // TODO : This is a bit hacky, but m_totalTime is only used to determine // if we are about to finish - if ( m_totalTime <= 0 ) { + if ( m_totalTime == 0 ) { m_totalTime = AudioEngine::instance()->currentTrackTotalTime(); + seekable = true; } m_currentTime = time; @@ -271,10 +275,15 @@ AudioOutput::setCurrentTime( qint64 time ) // tDebug() << "Current time : " << m_currentTime << " / " << m_totalTime; - if ( time < m_totalTime - ABOUT_TO_FINISH_TIME ) { + qint64 total = m_totalTime; + if ( total <= 0 ) { + total = AudioEngine::instance()->currentTrackTotalTime(); + } + + if ( time < total - ABOUT_TO_FINISH_TIME ) { m_aboutToFinish = false; } - if ( !m_aboutToFinish && m_totalTime > 0 && time >= m_totalTime - ABOUT_TO_FINISH_TIME ) { + if ( !m_aboutToFinish && total > 0 && time >= total - ABOUT_TO_FINISH_TIME ) { m_aboutToFinish = true; emit aboutToFinish(); } @@ -291,10 +300,15 @@ AudioOutput::totalTime() void AudioOutput::setTotalTime( qint64 time ) { - if ( time > 0 ) { + tDebug() << Q_FUNC_INFO << " " << time; + + if ( time <= 0 ) { + seekable = false; + } else { m_totalTime = time; + seekable = true; // emit current time to refresh total time - emit tick( m_currentTime ); + emit tick( time ); } } @@ -303,6 +317,7 @@ void AudioOutput::play() { tDebug() << Q_FUNC_INFO; + if ( libvlc_media_player_is_playing ( vlcPlayer ) ) { libvlc_media_player_set_pause ( vlcPlayer, 0 ); } else { @@ -339,6 +354,10 @@ AudioOutput::seek( qint64 milliseconds ) { tDebug() << Q_FUNC_INFO; + if ( !seekable ) { + return; + } + switch ( currentState ) { case Playing: case Paused: @@ -356,6 +375,15 @@ AudioOutput::seek( qint64 milliseconds ) } +bool +AudioOutput::isSeekable() +{ + tDebug() << Q_FUNC_INFO; + + return seekable; +} + + bool AudioOutput::isMuted() { @@ -413,16 +441,16 @@ AudioOutput::vlcEventCallback( const libvlc_event_t* event, void* opaque ) that->setCurrentTime( event->u.media_player_time_changed.new_time ); break; case libvlc_MediaPlayerSeekableChanged: + // tDebug() << Q_FUNC_INFO << " : seekable changed : " << event->u.media_player_seekable_changed.new_seekable; //TODO, bool event->u.media_player_seekable_changed.new_seekable break; case libvlc_MediaDurationChanged: that->setTotalTime( event->u.media_duration_changed.new_duration ); break; - /* case libvlc_MediaPlayerLengthChanged: - that->setTotalTime( event->u.media_player_length_changed.new_length ); + // tDebug() << Q_FUNC_INFO << " : length changed : " << event->u.media_player_length_changed.new_length; + // that->setTotalTime( event->u.media_player_length_changed.new_length ); break; - */ case libvlc_MediaPlayerNothingSpecial: case libvlc_MediaPlayerOpening: case libvlc_MediaPlayerBuffering: diff --git a/src/libtomahawk/audio/AudioOutput.h b/src/libtomahawk/audio/AudioOutput.h index 564515e58..0a0ff7e3c 100644 --- a/src/libtomahawk/audio/AudioOutput.h +++ b/src/libtomahawk/audio/AudioOutput.h @@ -52,6 +52,7 @@ public: void stop(); void seek(qint64 milliseconds); + bool isSeekable(); bool isMuted(); void setMuted(bool m); void setVolume(qreal vol); @@ -82,6 +83,7 @@ private: static AudioOutput* s_instance; AudioState currentState; MediaStream* currentStream; + bool seekable; bool muted; bool m_autoDelete; qreal m_volume; diff --git a/src/libtomahawk/utils/MediaStream.cpp b/src/libtomahawk/utils/MediaStream.cpp index 8b98f4360..fc9315852 100644 --- a/src/libtomahawk/utils/MediaStream.cpp +++ b/src/libtomahawk/utils/MediaStream.cpp @@ -174,10 +174,6 @@ MediaStream::readCallback ( void* data, const char* cookie, int64_t* dts, int64_ bufsize = that->needData(buffer); } else if ( that->m_type == IODevice ) { - /* - *buffer = new char[BLOCK_SIZE]; - bufsize = that->m_ioDevice->read( (char*)*buffer, BLOCK_SIZE ); - */ bufsize = that->m_ioDevice->read( that->m_buffer, BLOCK_SIZE ); *buffer = that->m_buffer; // tDebug() << "readCallback(QIODevice) returning bufsize : " << bufsize; @@ -186,7 +182,7 @@ MediaStream::readCallback ( void* data, const char* cookie, int64_t* dts, int64_ if ( bufsize > 0 ) { that->m_started = true; } - if ( bufsize == 0 && that->m_started && that->m_bufferingFinished == true ) { + if ( that->m_type == IODevice && bufsize == 0 && that->m_started && that->m_bufferingFinished == true ) { that->m_eos = true; return -1; } @@ -210,9 +206,7 @@ MediaStream::readDoneCallback ( void *data, const char *cookie, size_t bufferSiz MediaStream* that = static_cast < MediaStream * > ( data ); - if ( ( that->m_type == Stream/* || that->m_type == IODevice*/ ) && buffer != 0 && bufferSize > 0 ) { -// TODO : causes segfault -// tDebug() << "buffer : " << buffer; + if ( ( that->m_type == Stream ) && buffer != 0 && bufferSize > 0 ) { delete static_cast(buffer); }