mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-09 15:47:38 +02:00
Implement remaining MPRIS PropertiesChanged update signals, seeking, etc.
This commit is contained in:
@@ -188,40 +188,52 @@ AudioEngine::previous()
|
|||||||
{
|
{
|
||||||
tDebug( LOGEXTRA ) << Q_FUNC_INFO;
|
tDebug( LOGEXTRA ) << Q_FUNC_INFO;
|
||||||
|
|
||||||
if ( m_playlist.isNull() )
|
if( canGoPrevious() )
|
||||||
return;
|
|
||||||
|
|
||||||
if ( m_playlist.data()->skipRestrictions() == PlaylistInterface::NoSkip ||
|
|
||||||
m_playlist.data()->skipRestrictions() == PlaylistInterface::NoSkipBackwards )
|
|
||||||
return;
|
|
||||||
|
|
||||||
loadPreviousTrack();
|
loadPreviousTrack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioEngine::next()
|
AudioEngine::next()
|
||||||
{
|
{
|
||||||
tDebug( LOGEXTRA ) << Q_FUNC_INFO;
|
tDebug( LOGEXTRA ) << Q_FUNC_INFO;
|
||||||
|
|
||||||
|
if( canGoNext() )
|
||||||
|
loadNextTrack();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
AudioEngine::canGoNext()
|
||||||
|
{
|
||||||
if ( m_playlist.isNull() )
|
if ( m_playlist.isNull() )
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
if ( m_playlist.data()->skipRestrictions() == PlaylistInterface::NoSkip ||
|
if ( m_playlist.data()->skipRestrictions() == PlaylistInterface::NoSkip ||
|
||||||
m_playlist.data()->skipRestrictions() == PlaylistInterface::NoSkipForwards )
|
m_playlist.data()->skipRestrictions() == PlaylistInterface::NoSkipForwards )
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
if ( !m_currentTrack.isNull() && !m_playlist.data()->hasNextItem() &&
|
if ( !m_currentTrack.isNull() && !m_playlist.data()->hasNextItem() &&
|
||||||
m_currentTrack->id() == m_playlist.data()->currentItem()->id() )
|
m_currentTrack->id() == m_playlist.data()->currentItem()->id() )
|
||||||
{
|
{
|
||||||
//For instance, when doing a catch-up while listening along, but the person
|
//For instance, when doing a catch-up while listening along, but the person
|
||||||
//you're following hasn't started a new track yet...don't do anything
|
//you're following hasn't started a new track yet...don't do anything
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadNextTrack();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
AudioEngine::canGoPrevious()
|
||||||
|
{
|
||||||
|
if ( m_playlist.isNull() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( m_playlist.data()->skipRestrictions() == PlaylistInterface::NoSkip ||
|
||||||
|
m_playlist.data()->skipRestrictions() == PlaylistInterface::NoSkipBackwards )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioEngine::seek( qint64 ms )
|
AudioEngine::seek( qint64 ms )
|
||||||
|
@@ -81,6 +81,9 @@ public slots:
|
|||||||
void previous();
|
void previous();
|
||||||
void next();
|
void next();
|
||||||
|
|
||||||
|
bool canGoPrevious();
|
||||||
|
bool canGoNext();
|
||||||
|
|
||||||
void seek( qint64 ms );
|
void seek( qint64 ms );
|
||||||
void seek( int ms ); // for compatibility with seekbar in audiocontrols
|
void seek( int ms ); // for compatibility with seekbar in audiocontrols
|
||||||
void setVolume( int percentage );
|
void setVolume( int percentage );
|
||||||
|
@@ -49,6 +49,19 @@ MprisPlugin::MprisPlugin()
|
|||||||
dbus.registerObject("/org/mpris/MediaPlayer2", this);
|
dbus.registerObject("/org/mpris/MediaPlayer2", this);
|
||||||
dbus.registerService("org.mpris.MediaPlayer2.tomahawk");
|
dbus.registerService("org.mpris.MediaPlayer2.tomahawk");
|
||||||
|
|
||||||
|
connect( AudioEngine::instance(), SIGNAL( volumeChanged( int ) ),
|
||||||
|
SLOT( onVolumeChanged( int ) ) );
|
||||||
|
|
||||||
|
// When the playlist changes, signals for several properties are sent
|
||||||
|
connect( AudioEngine::instance(), SIGNAL( playlistChanged( Tomahawk::PlaylistInterface* ) ),
|
||||||
|
SLOT( onPlaylistChanged( Tomahawk::PlaylistInterface* ) ) );
|
||||||
|
|
||||||
|
// When a track is added or removed, CanGoNext updated signal is sent
|
||||||
|
PlaylistInterface *playlist = AudioEngine::instance()->playlist();
|
||||||
|
if( playlist )
|
||||||
|
connect( playlist->object(), SIGNAL( trackCountChanged( unsigned int ) ),
|
||||||
|
SLOT( onTrackCountChanged( unsigned int ) ) );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -128,31 +141,33 @@ MprisPlugin::canControl() const
|
|||||||
bool
|
bool
|
||||||
MprisPlugin::canGoNext() const
|
MprisPlugin::canGoNext() const
|
||||||
{
|
{
|
||||||
return true;
|
return AudioEngine::instance()->canGoNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MprisPlugin::canGoPrevious() const
|
MprisPlugin::canGoPrevious() const
|
||||||
{
|
{
|
||||||
return true;
|
return AudioEngine::instance()->canGoPrevious();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MprisPlugin::canPause() const
|
MprisPlugin::canPause() const
|
||||||
{
|
{
|
||||||
return true;
|
return AudioEngine::instance()->currentTrack();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MprisPlugin::canPlay() const
|
MprisPlugin::canPlay() const
|
||||||
{
|
{
|
||||||
return true;
|
// If there is a currently playing track, or if there is a playlist with at least 1 track, you can hit play
|
||||||
|
PlaylistInterface *p = AudioEngine::instance()->playlist();
|
||||||
|
return AudioEngine::instance()->currentTrack() || ( p && p->trackCount() );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MprisPlugin::canSeek() const
|
MprisPlugin::canSeek() const
|
||||||
{
|
{
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString
|
||||||
@@ -208,7 +223,7 @@ MprisPlugin::metadata() const
|
|||||||
Tomahawk::result_ptr track = AudioEngine::instance()->currentTrack();
|
Tomahawk::result_ptr track = AudioEngine::instance()->currentTrack();
|
||||||
if( track )
|
if( track )
|
||||||
{
|
{
|
||||||
metadataMap.insert( "mpris:trackid", track->id() );
|
metadataMap.insert( "mpris:trackid", QString( "/track/" ) + track->id().replace( "-", "" ) );
|
||||||
metadataMap.insert( "mpris:length", track->duration() );
|
metadataMap.insert( "mpris:length", track->duration() );
|
||||||
metadataMap.insert( "xesam:album", track->album()->name() );
|
metadataMap.insert( "xesam:album", track->album()->name() );
|
||||||
metadataMap.insert( "xesam:artist", track->artist()->name() );
|
metadataMap.insert( "xesam:artist", track->artist()->name() );
|
||||||
@@ -322,23 +337,37 @@ void
|
|||||||
MprisPlugin::Seek( qlonglong Offset )
|
MprisPlugin::Seek( qlonglong Offset )
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
/*
|
|
||||||
qlonglong seekTime = position() + Offset;
|
qlonglong seekTime = position() + Offset;
|
||||||
qDebug() << "seekTime: " << seekTime;
|
qDebug() << "seekTime: " << seekTime;
|
||||||
if( seekTime < 0 )
|
if( seekTime < 0 )
|
||||||
AudioEngine::instance()->seek( 0 );
|
AudioEngine::instance()->seek( 0 );
|
||||||
else if( seekTime > AudioEngine::instance()->currentTrackTotalTime() )
|
else if( seekTime > AudioEngine::instance()->currentTrackTotalTime()*1000 )
|
||||||
Next();
|
Next();
|
||||||
// seekTime is in microseconds, but we work internally in milliseconds
|
// seekTime is in microseconds, but we work internally in milliseconds
|
||||||
else
|
else
|
||||||
AudioEngine::instance()->seek( (qint64) ( seekTime / 1000 ) );
|
AudioEngine::instance()->seek( (qint64) ( seekTime / 1000 ) );
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MprisPlugin::SetPosition( const QDBusObjectPath &TrackId, qlonglong Position )
|
MprisPlugin::SetPosition( const QDBusObjectPath &TrackId, qlonglong Position )
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
qDebug() << "path: " << TrackId.path();
|
||||||
|
qDebug() << "position: " << Position;
|
||||||
|
|
||||||
|
if( TrackId.path() != QString("/track/") + AudioEngine::instance()->currentTrack()->id().replace( "-", "" ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( ( Position < 0) || ( Position > AudioEngine::instance()->currentTrackTotalTime()*1000 ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
qDebug() << "seeking to: " << Position/1000 << "ms";
|
||||||
|
|
||||||
|
AudioEngine::instance()->seek( (qint64) (Position / 1000 ) );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -403,8 +432,6 @@ MprisPlugin::audioStarted( const QVariant &input )
|
|||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
m_playbackStatus = "Playing";
|
|
||||||
|
|
||||||
if ( !input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() )
|
if ( !input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -412,10 +439,13 @@ MprisPlugin::audioStarted( const QVariant &input )
|
|||||||
if ( !hash.contains( "title" ) || !hash.contains( "artist" ) )
|
if ( !hash.contains( "title" ) || !hash.contains( "artist" ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
m_playbackStatus = "Playing";
|
||||||
|
notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "Metadata");
|
||||||
|
|
||||||
//hash["artist"];
|
//hash["artist"];
|
||||||
//hash["title"];
|
//hash["title"];
|
||||||
QString nowPlaying = "";
|
//QString nowPlaying = "";
|
||||||
qDebug() << "nowPlaying: " << nowPlaying;
|
//qDebug() << "nowPlaying: " << nowPlaying;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -445,6 +475,43 @@ MprisPlugin::audioResumed( const QVariant &input )
|
|||||||
audioStarted( input );
|
audioStarted( input );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MprisPlugin::onVolumeChanged( int volume )
|
||||||
|
{
|
||||||
|
Q_UNUSED( volume );
|
||||||
|
notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "Volume");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MprisPlugin::onPlaylistChanged( Tomahawk::PlaylistInterface* playlist )
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
disconnect( this, SLOT( onTrackCountChanged( unsigned int ) ) );
|
||||||
|
qDebug() << "disconnected";
|
||||||
|
if( playlist )
|
||||||
|
qDebug() << "playlist not null";
|
||||||
|
|
||||||
|
if( playlist )
|
||||||
|
connect( playlist->object(), SIGNAL( trackCountChanged( unsigned int ) ),
|
||||||
|
SLOT( onTrackCountChanged( unsigned int ) ) );
|
||||||
|
|
||||||
|
qDebug() << "connected new playlist";
|
||||||
|
|
||||||
|
// Notify relevant changes
|
||||||
|
notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "LoopStatus" );
|
||||||
|
notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "Shuffle" );
|
||||||
|
onTrackCountChanged( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MprisPlugin::onTrackCountChanged( unsigned int tracks )
|
||||||
|
{
|
||||||
|
Q_UNUSED( tracks );
|
||||||
|
notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "CanGoNext" );
|
||||||
|
notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "CanGoPrevious" );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MprisPlugin::notifyPropertyChanged( const QString& interface,
|
MprisPlugin::notifyPropertyChanged( const QString& interface,
|
||||||
const QString& propertyName )
|
const QString& propertyName )
|
||||||
|
@@ -146,6 +146,9 @@ protected slots:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void stateChanged( AudioState newState, AudioState oldState );
|
void stateChanged( AudioState newState, AudioState oldState );
|
||||||
|
void onVolumeChanged( int volume );
|
||||||
|
void onPlaylistChanged( Tomahawk::PlaylistInterface* playlist);
|
||||||
|
void onTrackCountChanged( unsigned int tracks );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Get Info
|
// Get Info
|
||||||
|
@@ -103,7 +103,6 @@ enum InfoType { // as items are saved in cache, mark them here to not change the
|
|||||||
InfoNowResumed = 82,
|
InfoNowResumed = 82,
|
||||||
InfoNowStopped = 83,
|
InfoNowStopped = 83,
|
||||||
|
|
||||||
|
|
||||||
InfoLove = 90,
|
InfoLove = 90,
|
||||||
InfoUnLove = 91,
|
InfoUnLove = 91,
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user