diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index 8e221c729..5a177c08e 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -192,8 +192,9 @@ AudioEngine::AudioEngine() d->audioOutput = new AudioOutput(this); - QObject::connect( d->audioOutput, SIGNAL( stateChanged( AudioOutput::AudioState, AudioOutput::AudioState ) ), d, SLOT( onStateChanged( AudioOutput::AudioState, AudioOutput::AudioState ) ) ); -getchar(); + 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 ) ) ); + qRegisterMetaType< AudioErrorCode >("AudioErrorCode"); qRegisterMetaType< AudioState >("AudioState"); } @@ -1240,16 +1241,14 @@ AudioEngine::setState( AudioState state ) qint64 AudioEngine::currentTime() const { -// TODO return d_func()->mediaObject->currentTime(); - return 0; + return d_func()->audioOutput->currentTime(); } qint64 AudioEngine::currentTrackTotalTime() const { -// TODO return d_func()->mediaObject->totalTime(); - return 0; + return d_func()->audioOutput->totalTime(); } diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp index 34b97854d..c5dcfee14 100644 --- a/src/libtomahawk/audio/AudioOutput.cpp +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include static QString s_aeInfoIdentifier = QString( "AUDIOOUTPUT" ); @@ -49,10 +50,12 @@ AudioOutput::instance() AudioOutput::AudioOutput( QObject* parent ) : QObject( parent ) - , dspPluginCallback( 0 ) , currentState( Stopped ) , muted( false ) , m_volume( 1.0 ) + , m_currentTime( 0 ) + , m_totalTime( 0 ) + , dspPluginCallback( 0 ) { tDebug() << Q_FUNC_INFO; @@ -87,8 +90,38 @@ AudioOutput::AudioOutput( QObject* parent ) if ( !( vlcInstance = libvlc_new( vlcArgs.size(), vlcArgs.constData() ) ) ) { tDebug() << "libVLC: could not initialize"; } + + vlcPlayer = libvlc_media_player_new( vlcInstance ); + libvlc_event_manager_t *manager = libvlc_media_player_event_manager( vlcPlayer ); + libvlc_event_type_t events[] = { + libvlc_MediaPlayerMediaChanged, + libvlc_MediaPlayerNothingSpecial, + libvlc_MediaPlayerOpening, + libvlc_MediaPlayerBuffering, + libvlc_MediaPlayerPlaying, + libvlc_MediaPlayerPaused, + libvlc_MediaPlayerStopped, + libvlc_MediaPlayerForward, + libvlc_MediaPlayerBackward, + libvlc_MediaPlayerEndReached, + libvlc_MediaPlayerEncounteredError, + libvlc_MediaPlayerTimeChanged, + libvlc_MediaPlayerPositionChanged, + libvlc_MediaPlayerSeekableChanged, + libvlc_MediaPlayerPausableChanged, + libvlc_MediaPlayerTitleChanged, + libvlc_MediaPlayerSnapshotTaken, + libvlc_MediaPlayerLengthChanged, + libvlc_MediaPlayerVout + }; + const int eventCount = sizeof(events) / sizeof( *events ); + for ( int i = 0 ; i < eventCount ; i++ ) { + libvlc_event_attach( manager, events[ i ], &AudioOutput::vlcEventCallback, this ); + } + + getchar(); tDebug() << "AudioOutput::AudioOutput OK !\n"; } @@ -144,7 +177,10 @@ AudioOutput::setCurrentSource(MediaStream* stream) libvlc_media_player_set_media( vlcPlayer, vlcMedia ); - if ( stream->type() == MediaStream::Stream ) { + if ( stream->type() == MediaStream::Url ) { + m_totalTime = libvlc_media_get_duration( vlcMedia ); + } + else if ( stream->type() == MediaStream::Stream ) { libvlc_media_add_option_flag(vlcMedia, "imem-cat=4", libvlc_media_option_trusted); libvlc_media_add_option_flag(vlcMedia, (QString("imem-data=") + QString::number((quint64)stream)).toUtf8().data(), libvlc_media_option_trusted); libvlc_media_add_option_flag(vlcMedia, (QString("imem-get=") + QString::number((quint64)&MediaStream::readCallback)).toUtf8().data(), libvlc_media_option_trusted); @@ -179,6 +215,28 @@ AudioOutput::setState( AudioState state ) } +qint64 +AudioOutput::currentTime() +{ + return m_currentTime; +} + + +void +AudioOutput::setCurrentTime( qint64 time ) +{ + m_currentTime = time; + emit tick( time ); +} + + +qint64 +AudioOutput::totalTime() +{ + return m_totalTime; +} + + void AudioOutput::play() { @@ -295,20 +353,55 @@ AudioOutput::setVolume(qreal vol) void -AudioOutput::s_dspCallback( signed short* samples, int nb_channels, int nb_samples ) +AudioOutput::vlcEventCallback( const libvlc_event_t* event, void* opaque ) { - tDebug() << Q_FUNC_INFO; +// tDebug() << Q_FUNC_INFO; - AudioOutput::instance()->dspCallback( samples, nb_channels, nb_samples ); + AudioOutput* that = reinterpret_cast < AudioOutput * > ( opaque ); + Q_ASSERT( that ); + + switch (event->type) { + case libvlc_MediaPlayerTimeChanged: + that->setCurrentTime( event->u.media_player_time_changed.new_time ); + break; + case libvlc_MediaPlayerSeekableChanged: + //TODO, bool event->u.media_player_seekable_changed.new_seekable + break; + case libvlc_MediaPlayerLengthChanged: + that->m_totalTime = event->u.media_player_length_changed.new_length; + break; + case libvlc_MediaPlayerNothingSpecial: + case libvlc_MediaPlayerOpening: + case libvlc_MediaPlayerBuffering: + case libvlc_MediaPlayerPlaying: + case libvlc_MediaPlayerPaused: + case libvlc_MediaPlayerStopped: + case libvlc_MediaPlayerEndReached: + break; + case libvlc_MediaPlayerEncounteredError: + // TODO emit Error + break; + case libvlc_MediaPlayerVout: + case libvlc_MediaPlayerMediaChanged: + case libvlc_MediaPlayerForward: + case libvlc_MediaPlayerBackward: + case libvlc_MediaPlayerPositionChanged: + case libvlc_MediaPlayerPausableChanged: + case libvlc_MediaPlayerTitleChanged: + case libvlc_MediaPlayerSnapshotTaken: + default: + break; + } } void -AudioOutput::dspCallback( signed short* samples, int nb_channels, int nb_samples ) +AudioOutput::s_dspCallback( signed short* samples, int nb_channels, int nb_samples ) { - if ( dspPluginCallback != 0 ) - { - dspPluginCallback( samples, nb_channels, nb_samples ); + tDebug() << Q_FUNC_INFO; + + if ( AudioOutput::instance()->dspPluginCallback ) { + AudioOutput::instance()->dspPluginCallback( samples, nb_channels, nb_samples ); } } diff --git a/src/libtomahawk/audio/AudioOutput.h b/src/libtomahawk/audio/AudioOutput.h index b231b565e..175c4c4bb 100644 --- a/src/libtomahawk/audio/AudioOutput.h +++ b/src/libtomahawk/audio/AudioOutput.h @@ -30,6 +30,7 @@ struct libvlc_instance_t; struct libvlc_media_player_t; struct libvlc_media_t; +struct libvlc_event_t; class DLLEXPORT AudioOutput : public QObject { @@ -55,6 +56,8 @@ public: void setMuted(bool m); void setVolume(qreal vol); qreal volume(); + qint64 currentTime(); + qint64 totalTime(); void setDspCallback( void ( *cb ) ( signed short*, int, int ) ); @@ -64,20 +67,24 @@ public slots: signals: void stateChanged( AudioOutput::AudioState, AudioOutput::AudioState ); + void tick( qint64 ); private: void setState( AudioState state ); + void setCurrentTime( qint64 time ); + static void vlcEventCallback( const libvlc_event_t *event, void *opaque ); static void s_dspCallback( signed short* samples, int nb_channels, int nb_samples ); - void dspCallback( signed short* samples, int nb_channels, int nb_samples ); - - void ( *dspPluginCallback ) ( signed short* samples, int nb_channels, int nb_samples ); static AudioOutput* s_instance; AudioState currentState; MediaStream* currentStream; bool muted; qreal m_volume; + qint64 m_currentTime; + qint64 m_totalTime; + + void ( *dspPluginCallback ) ( signed short* samples, int nb_channels, int nb_samples ); libvlc_instance_t* vlcInstance; libvlc_media_player_t* vlcPlayer; diff --git a/src/libtomahawk/utils/MediaStream.cpp b/src/libtomahawk/utils/MediaStream.cpp index f400e812b..5b7dc7ad1 100644 --- a/src/libtomahawk/utils/MediaStream.cpp +++ b/src/libtomahawk/utils/MediaStream.cpp @@ -70,6 +70,8 @@ MediaStream::url() qint64 MediaStream::streamSize() { + tDebug() << Q_FUNC_INFO; + return m_streamSize; } @@ -77,6 +79,8 @@ MediaStream::streamSize() void MediaStream::setStreamSize( qint64 size ) { + tDebug() << Q_FUNC_INFO; + m_streamSize = size; }