diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index 3c572ab1a..db1fa2dee 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -55,7 +55,7 @@ static QString s_aeInfoIdentifier = QString( "AUDIOENGINE" ); void AudioEnginePrivate::onStateChanged( AudioOutput::AudioState newState, AudioOutput::AudioState oldState ) { - tDebug() << Q_FUNC_INFO << oldState << newState << expectStop << q_ptr->state(); + tDebug() << Q_FUNC_INFO << oldState << newState << q_ptr->state(); if ( newState == AudioOutput::Loading ) { @@ -127,9 +127,8 @@ AudioEnginePrivate::onStateChanged( AudioOutput::AudioState newState, AudioOutpu break; } - if ( stopped && expectStop ) + if ( stopped ) { - expectStop = false; tDebug() << "Finding next track."; if ( q_ptr->canGoNext() ) { @@ -143,6 +142,8 @@ AudioEnginePrivate::onStateChanged( AudioOutput::AudioState newState, AudioOutpu q_ptr->stop(); } } +#if 0 + //This is obsolete, we always expect stop else if ( stopped ) { // We did not expect a Stop here, so do not go to the next track @@ -152,6 +153,7 @@ AudioEnginePrivate::onStateChanged( AudioOutput::AudioState newState, AudioOutpu // an stream that cannot be paused. q_ptr->setState( AudioEngine::Stopped ); } +#endif } } @@ -173,7 +175,6 @@ AudioEngine::AudioEngine() Q_D( AudioEngine ); d->timeElapsed = 0; - d->expectStop = false; d->waitingOnNewTrack = false; d->state = Stopped; d->coverTempFile = 0; @@ -185,7 +186,6 @@ AudioEngine::AudioEngine() connect( d->audioOutput, SIGNAL( stateChanged( AudioOutput::AudioState, AudioOutput::AudioState ) ), d_func(), SLOT( onStateChanged( AudioOutput::AudioState, AudioOutput::AudioState ) ) ); connect( d->audioOutput, SIGNAL( tick( qint64 ) ), SLOT( timerTriggered( qint64 ) ) ); - connect( d->audioOutput, SIGNAL( aboutToFinish() ), SLOT( onAboutToFinish() ) ); setVolume( TomahawkSettings::instance()->volume() ); @@ -401,10 +401,6 @@ AudioEngine::canSeek() { Q_D( AudioEngine ); - if ( !d->audioOutput->isSeekable() ) { - return false; - } - return !d->playlist.isNull() && ( d->playlist.data()->seekRestrictions() != PlaylistModes::NoSeek ); } @@ -606,6 +602,11 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result ) } } +void AudioEngine::positionChanged(float new_position) +{ + emit trackPosition( new_position ); +} + void AudioEngine::performLoadIODevice( const result_ptr& result, const QString& url ) @@ -1037,13 +1038,6 @@ AudioEngine::onPlaylistNextTrackAvailable() } -void -AudioEngine::onAboutToFinish() -{ - tDebug( LOGVERBOSE ) << Q_FUNC_INFO; - d_func()->expectStop = true; -} - void AudioEngine::timerTriggered( qint64 time ) { diff --git a/src/libtomahawk/audio/AudioEngine.h b/src/libtomahawk/audio/AudioEngine.h index 168b540a2..b165c5b2b 100644 --- a/src/libtomahawk/audio/AudioEngine.h +++ b/src/libtomahawk/audio/AudioEngine.h @@ -147,6 +147,8 @@ public slots: void setRepeatMode( Tomahawk::PlaylistModes::RepeatMode mode ); void setShuffled( bool enabled ); + void positionChanged(float new_position); + signals: void loading( const Tomahawk::result_ptr track ); void started( const Tomahawk::result_ptr track ); @@ -171,6 +173,7 @@ signals: void timerMilliSeconds( qint64 msElapsed ); void timerSeconds( unsigned int secondsElapsed ); void timerPercentage( unsigned int percentage ); + void trackPosition( float position ); void playlistChanged( Tomahawk::playlistinterface_ptr playlist ); void currentTrackPlaylistChanged( Tomahawk::playlistinterface_ptr playlist ); @@ -184,7 +187,6 @@ private slots: void loadPreviousTrack(); void loadNextTrack(); - void onAboutToFinish(); void onVolumeChanged( qreal volume ); void timerTriggered( qint64 time ); diff --git a/src/libtomahawk/audio/AudioEngine_p.h b/src/libtomahawk/audio/AudioEngine_p.h index 824b85a53..f1ea033e3 100644 --- a/src/libtomahawk/audio/AudioEngine_p.h +++ b/src/libtomahawk/audio/AudioEngine_p.h @@ -37,7 +37,6 @@ private: AudioOutput* audioOutput; unsigned int timeElapsed; - bool expectStop; bool waitingOnNewTrack; AudioState state; diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp index 8ce2a467e..921647af5 100644 --- a/src/libtomahawk/audio/AudioOutput.cpp +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -37,8 +37,6 @@ #include #include -static const int ABOUT_TO_FINISH_TIME = 2000; - AudioOutput* AudioOutput::s_instance = 0; @@ -53,13 +51,12 @@ AudioOutput::AudioOutput( QObject* parent ) : QObject( parent ) , m_currentState( Stopped ) , m_currentStream( nullptr ) - , m_seekable( true ) , m_muted( false ) + , m_seekable( true ) , m_autoDelete ( true ) , m_volume( 1.0 ) , m_currentTime( 0 ) , m_totalTime( 0 ) - , m_aboutToFinish( false ) , m_justSeeked( false ) , dspPluginCallback( nullptr ) , m_vlcInstance( nullptr ) @@ -278,7 +275,6 @@ AudioOutput::setCurrentSource( MediaStream* stream ) libvlc_media_add_option_flag(m_vlcMedia, imemSeek, libvlc_media_option_trusted); } - m_aboutToFinish = false; setState( Stopped ); } @@ -306,6 +302,13 @@ AudioOutput::currentTime() const return m_currentTime; } +void +AudioOutput::setCurrentPosition( float position ) +{ + //tDebug() << Q_FUNC_INFO << position; + AudioEngine::instance()->positionChanged(position); + m_havePosition = position > 0.0; +} void AudioOutput::setCurrentTime( qint64 time ) @@ -315,7 +318,6 @@ AudioOutput::setCurrentTime( qint64 time ) if ( m_totalTime == 0 ) { m_totalTime = AudioEngine::instance()->currentTrackTotalTime(); - m_seekable = true; } m_currentTime = time; @@ -331,14 +333,11 @@ AudioOutput::setCurrentTime( qint64 time ) total = AudioEngine::instance()->currentTrackTotalTime(); } - if ( time < total - ABOUT_TO_FINISH_TIME ) + if ( time <= 0 ) { - m_aboutToFinish = false; - } - if ( !m_aboutToFinish && total > 0 && time >= total - ABOUT_TO_FINISH_TIME ) - { - m_aboutToFinish = true; - emit aboutToFinish(); + m_seekable = false; + } else { + m_seekable = true; } } @@ -355,13 +354,9 @@ AudioOutput::setTotalTime( qint64 time ) { // tDebug() << Q_FUNC_INFO << time; - if ( time <= 0 ) - { - m_seekable = false; - } else + if ( time > 0 ) { m_totalTime = time; - m_seekable = true; // emit current time to refresh total time emit tick( time ); } @@ -411,12 +406,6 @@ AudioOutput::seek( qint64 milliseconds ) { tDebug() << Q_FUNC_INFO; - // Even seek if reported as not seekable. VLC can seek in some cases where - // it tells us it can't. - // if ( !seekable ) { - // return; - // } - switch ( m_currentState ) { case Playing: @@ -428,18 +417,29 @@ AudioOutput::seek( qint64 milliseconds ) return; } - // tDebug() << Q_FUNC_INFO << "AudioOutput:: seeking" << milliseconds << "msec"; + if ( m_seekable ) + { + // tDebug() << Q_FUNC_INFO << "AudioOutput:: seeking" << milliseconds << "msec"; + libvlc_media_player_set_time( m_vlcPlayer, milliseconds ); + setCurrentTime( milliseconds ); + } + else + { + qint64 duration = AudioEngine::instance()->currentTrackTotalTime(); + float position = float(float(milliseconds) / duration); + libvlc_media_player_set_position(m_vlcPlayer, position); + tDebug() << Q_FUNC_INFO << "AudioOutput:: seeking via position" << position << "pos"; + } m_justSeeked = true; - libvlc_media_player_set_time( m_vlcPlayer, milliseconds ); - setCurrentTime( milliseconds ); } bool AudioOutput::isSeekable() const { - return m_seekable; + tDebug() << Q_FUNC_INFO << m_seekable << m_havePosition << m_totalTime << libvlc_media_player_is_seekable( m_vlcPlayer ); + return !m_havePosition || (libvlc_media_player_is_seekable( m_vlcPlayer ) && m_totalTime > 0); } @@ -495,6 +495,9 @@ AudioOutput::onVlcEvent( const libvlc_event_t* event ) case libvlc_MediaPlayerTimeChanged: setCurrentTime( event->u.media_player_time_changed.new_time ); break; + case libvlc_MediaPlayerPositionChanged: + setCurrentPosition(event->u.media_player_position_changed.new_position); + break; case libvlc_MediaPlayerSeekableChanged: // tDebug() << Q_FUNC_INFO << " : seekable changed : " << event->u.media_player_seekable_changed.new_seekable; break; @@ -526,7 +529,6 @@ AudioOutput::onVlcEvent( const libvlc_event_t* event ) case libvlc_MediaPlayerMediaChanged: case libvlc_MediaPlayerForward: case libvlc_MediaPlayerBackward: - case libvlc_MediaPlayerPositionChanged: case libvlc_MediaPlayerPausableChanged: case libvlc_MediaPlayerTitleChanged: case libvlc_MediaPlayerSnapshotTaken: diff --git a/src/libtomahawk/audio/AudioOutput.h b/src/libtomahawk/audio/AudioOutput.h index cf643f7a2..b024abe2d 100644 --- a/src/libtomahawk/audio/AudioOutput.h +++ b/src/libtomahawk/audio/AudioOutput.h @@ -74,11 +74,11 @@ public slots: signals: void stateChanged( AudioOutput::AudioState, AudioOutput::AudioState ); void tick( qint64 ); - void aboutToFinish(); private: void setState( AudioState state ); void setCurrentTime( qint64 time ); + void setCurrentPosition( float position ); void setTotalTime( qint64 time ); void onVlcEvent( const libvlc_event_t* event ); @@ -91,10 +91,11 @@ private: bool m_seekable; bool m_muted; bool m_autoDelete; + bool m_havePosition; + bool m_haveTiming; qreal m_volume; qint64 m_currentTime; qint64 m_totalTime; - bool m_aboutToFinish; bool m_justSeeked; std::function< void( int state, int frameNumber, float* samples, int nb_channels, int nb_samples ) > dspPluginCallback; diff --git a/src/tomahawk/AudioControls.cpp b/src/tomahawk/AudioControls.cpp index ed6dc7df0..9bf45f75c 100644 --- a/src/tomahawk/AudioControls.cpp +++ b/src/tomahawk/AudioControls.cpp @@ -56,6 +56,7 @@ AudioControls::AudioControls( QWidget* parent ) , ui( new Ui::AudioControls ) , m_repeatMode( PlaylistModes::NoRepeat ) , m_shuffled( false ) + , m_haveTiming ( false ) , m_lastSliderCheck( 0 ) , m_parent( parent ) { @@ -166,6 +167,7 @@ AudioControls::AudioControls( QWidget* parent ) connect( AudioEngine::instance(), SIGNAL( stopped() ), SLOT( onPlaybackStopped() ) ); connect( AudioEngine::instance(), SIGNAL( seeked( qint64 ) ), SLOT( onPlaybackSeeked( qint64 ) ) ); connect( AudioEngine::instance(), SIGNAL( timerMilliSeconds( qint64 ) ), SLOT( onPlaybackTimer( qint64 ) ) ); + connect( AudioEngine::instance(), SIGNAL( trackPosition( float ) ), SLOT( onTrackPosition( float ) ) ); connect( AudioEngine::instance(), SIGNAL( volumeChanged( int ) ), SLOT( onVolumeChanged( int ) ) ); connect( AudioEngine::instance(), SIGNAL( mutedChanged( bool ) ), SLOT( onMutedChanged( bool ) ) ); connect( AudioEngine::instance(), SIGNAL( controlStateChanged() ), SLOT( onControlStateChanged() ) ); @@ -469,7 +471,10 @@ AudioControls::onPlaybackSeeked( qint64 msec ) { tDebug( LOGEXTRA ) << Q_FUNC_INFO; m_seeked = true; - onPlaybackTimer( msec ); + if ( m_haveTiming ) + { + onPlaybackTimer( msec ); + } } @@ -517,6 +522,20 @@ AudioControls::onPlaybackStopped() } +void +AudioControls::onTrackPosition( float position ) +{ + if (!m_haveTiming) + { + qint64 duration = AudioEngine::instance()->currentTrackTotalTime(); + ui->seekSlider->blockSignals( true ); + ui->seekSlider->setSliderPosition( position * duration ); + ui->seekSlider->blockSignals( false ); + m_sliderTimeLine.stop(); + } +} + + void AudioControls::onPlaybackTimer( qint64 msElapsed ) { @@ -541,7 +560,11 @@ AudioControls::onPlaybackTimer( qint64 msElapsed ) m_phononTickCheckTimer.start( 500 ); if ( msElapsed == 0 ) + { + m_haveTiming = false; return; + } + m_haveTiming = true; int currentTime = m_sliderTimeLine.currentTime(); //tDebug( LOGEXTRA ) << Q_FUNC_INFO << "msElapsed =" << msElapsed << "and timer current time =" << currentTime << "and audio engine state is" << (int)AudioEngine::instance()->state(); diff --git a/src/tomahawk/AudioControls.h b/src/tomahawk/AudioControls.h index 4f16784fa..75325f828 100644 --- a/src/tomahawk/AudioControls.h +++ b/src/tomahawk/AudioControls.h @@ -75,6 +75,7 @@ private slots: void onPlaybackStopped(); void onPlaybackTimer( qint64 msElapsed ); + void onTrackPosition( float position ); void onVolumeChanged( int volume ); void onMutedChanged( bool muted ); void onControlStateChanged(); @@ -111,6 +112,7 @@ private: QTimer m_phononTickCheckTimer; QTimeLine m_sliderTimeLine; bool m_seeked; + bool m_haveTiming; qint64 m_lastSliderCheck; qint64 m_lastTextSecondShown;