#include "MprisPlugin.h"
#include "MprisPluginRootAdaptor.h"
#include "MprisPluginPlayerAdaptor.h"
namespace mpris
{
const char* MprisPlugin::mprisObjectPath = "/org/mpris/MediaPlayer2";
const char* MprisPlugin::serviceName = "org.mpris.MediaPlayer2.myapp";
const char* MprisPlugin::freedesktopPath = "org.freedesktop.DBus.Properties";
MprisPlugin
::MprisPlugin(QObject* parent
) :{
// DBus connection
new MprisPluginRootAdaptor( this );
new MprisPluginPlayerAdaptor( this );
dbus.registerObject( mprisObjectPath, this );
dbus.registerService( serviceName );
// Listen to volume changes
connect( The::audioEngine(), SIGNAL( volumeChanged( int ) ),
SLOT( onVolumeChanged( int ) ) );
// When a track is added or removed, CanGoNext updated signal is sent
if ( !The::playlist() )
{
connect( The::playlist(), SIGNAL( itemCountChanged( unsigned int ) ),
SLOT( onTrackCountChanged( unsigned int ) ) );
}
// Connect to AudioEngine's seeked signal
connect( The::audioEngine(), SIGNAL( seeked( qint64, bool ) ),
SLOT( onSeeked( qint64, bool ) ) );
connect( The::audioEngine(), SIGNAL( stateChanged(Phonon::State, Phonon::State ) ),
SLOT( engineStateChanged(Phonon::State, Phonon::State ) ) );
connect( The::audioEngine(), SIGNAL( sourceChanged() ),
SLOT( trackChanged() ) );
connect( The::audioEngine(), SIGNAL( seekableChanged(bool) ),
SLOT( seekableChanged(bool) ) );
connect( The::audioEngine(), SIGNAL( trackLengthChanged(qint64) ),
SLOT( trackLengthChanged(qint64) ) );
}
void MprisPlugin::notifyPropertyChanged( const QString& interface, const QString& propertyName )
{
mprisObjectPath,
freedesktopPath,
"PropertiesChanged" );
signal << interface;
QVariantMap changedProps;
changedProps.insert(propertyName, property(propertyName.toLatin1()));
signal << changedProps;
qDebug() << propertyName;
qDebug() << changedProps;
}
// ...
// org.mpris.MediaPlayer2.Player
// ...
qlonglong MprisPlugin::position() const
{
return (qlonglong) ( The::audioEngine()->currentTime() * 1000 );
}
// ...
void MprisPlugin::SetPosition( const QDBusObjectPath& TrackId, qlonglong Position )
{
if ( !canSeek() )
return;
if ( TrackId.
path() != QString( "/track/" ) + QString::number( The
::audioEngine()->currentTrackID
() ) ) return;
if ( ( Position < 0) || ( Position > The::audioEngine()->currentTrackTotalTime() * 1000 ) )
return;
The::audioEngine()->seek( (qint64) (Position / 1000 ) );
}
// ...
void MprisPlugin::Seek( qlonglong Offset )
{
if ( !canSeek() )
return;
qlonglong seekTime = position() + Offset;
if ( seekTime < 0 )
The::audioEngine()->seek( 0 );
else if ( seekTime > The::audioEngine()->currentTrackTotalTime() * 1000 )
Next();
else
The::audioEngine()->seek( (qint64) ( seekTime / 1000 ) );
}
void MprisPlugin::onSeeked( qint64 ms, bool userSeek )
{
if ( userSeek )
emit Seeked( ms * 1000 );
}
void MprisPlugin::engineStateChanged(Phonon::State newState, Phonon::State oldState)
{
if(newState != Phonon::PlayingState && newState != Phonon::PausedState) {
m_lastMetadata= QVariantMap();
notifyPropertyChanged("org.mpris.MediaPlayer2.Player", "Metadata");
}
notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "PlaybackStatus" );
notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "CanGoNext" );
notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "CanGoPrevious" );
notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "CanPause" );
}
// ...
void MprisPlugin::trackChanged()
{
PlaylistItemPtr track = The::audioEngine()->currentTrack();
m_lastMetadata = QVariantMap();
m_lastMetadata.
insert( "mpris:trackid",
QString( "/track/" ) + QString::number( The
::audioEngine()->currentTrackID
() ) );
m_lastMetadata.insert( "mpris:length", static_cast<qlonglong>( The::audioEngine()->currentTrackTotalTime() ) * 1000 );
m_lastMetadata.insert( "xesam:album", track->albumName() );
m_lastMetadata.
insert( "xesam:artist",
QStringList( track
->artistName
() ) );
m_lastMetadata.insert( "xesam:title", track->songName() );
m_lastMetadata.
insert( "mpris:artUrl",
QString( QUrl::fromLocalFile( track
->coverArtFilename
() ).
toEncoded() ) );
notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "Metadata" );
}
void MprisPlugin::seekableChanged( bool seekable )
{
notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "CanSeek");
}
void MprisPlugin::trackLengthChanged( qint64 milliseconds )
{
if ( milliseconds >= 0 )
trackChanged();
}
} //mpris
#include "MprisPlugin.h"
#include "MprisPluginRootAdaptor.h"
#include "MprisPluginPlayerAdaptor.h"
namespace mpris
{
const char* MprisPlugin::mprisObjectPath = "/org/mpris/MediaPlayer2";
const char* MprisPlugin::serviceName = "org.mpris.MediaPlayer2.myapp";
const char* MprisPlugin::freedesktopPath = "org.freedesktop.DBus.Properties";
static QString s_mpInfoIdentifier = QString( "MPRISPLUGIN" );
MprisPlugin::MprisPlugin(QObject* parent) :
QObject(parent)
{
// DBus connection
new MprisPluginRootAdaptor( this );
new MprisPluginPlayerAdaptor( this );
QDBusConnection dbus = QDBusConnection::sessionBus();
dbus.registerObject( mprisObjectPath, this );
dbus.registerService( serviceName );
// Listen to volume changes
connect( The::audioEngine(), SIGNAL( volumeChanged( int ) ),
SLOT( onVolumeChanged( int ) ) );
// When a track is added or removed, CanGoNext updated signal is sent
if ( !The::playlist() )
{
connect( The::playlist(), SIGNAL( itemCountChanged( unsigned int ) ),
SLOT( onTrackCountChanged( unsigned int ) ) );
}
// Connect to AudioEngine's seeked signal
connect( The::audioEngine(), SIGNAL( seeked( qint64, bool ) ),
SLOT( onSeeked( qint64, bool ) ) );
connect( The::audioEngine(), SIGNAL( stateChanged(Phonon::State, Phonon::State ) ),
SLOT( engineStateChanged(Phonon::State, Phonon::State ) ) );
connect( The::audioEngine(), SIGNAL( sourceChanged() ),
SLOT( trackChanged() ) );
connect( The::audioEngine(), SIGNAL( seekableChanged(bool) ),
SLOT( seekableChanged(bool) ) );
connect( The::audioEngine(), SIGNAL( trackLengthChanged(qint64) ),
SLOT( trackLengthChanged(qint64) ) );
}
void MprisPlugin::notifyPropertyChanged( const QString& interface, const QString& propertyName )
{
QDBusMessage signal = QDBusMessage::createSignal(
mprisObjectPath,
freedesktopPath,
"PropertiesChanged" );
signal << interface;
QVariantMap changedProps;
changedProps.insert(propertyName, property(propertyName.toLatin1()));
signal << changedProps;
signal << QStringList();
qDebug() << propertyName;
qDebug() << changedProps;
QDBusConnection::sessionBus().send(signal);
}
// ...
// org.mpris.MediaPlayer2.Player
// ...
qlonglong MprisPlugin::position() const
{
return (qlonglong) ( The::audioEngine()->currentTime() * 1000 );
}
// ...
void MprisPlugin::SetPosition( const QDBusObjectPath& TrackId, qlonglong Position )
{
if ( !canSeek() )
return;
if ( TrackId.path() != QString( "/track/" ) + QString::number( The::audioEngine()->currentTrackID() ) )
return;
if ( ( Position < 0) || ( Position > The::audioEngine()->currentTrackTotalTime() * 1000 ) )
return;
The::audioEngine()->seek( (qint64) (Position / 1000 ) );
}
// ...
void MprisPlugin::Seek( qlonglong Offset )
{
if ( !canSeek() )
return;
qlonglong seekTime = position() + Offset;
if ( seekTime < 0 )
The::audioEngine()->seek( 0 );
else if ( seekTime > The::audioEngine()->currentTrackTotalTime() * 1000 )
Next();
else
The::audioEngine()->seek( (qint64) ( seekTime / 1000 ) );
}
void MprisPlugin::onSeeked( qint64 ms, bool userSeek )
{
if ( userSeek )
emit Seeked( ms * 1000 );
}
void MprisPlugin::engineStateChanged(Phonon::State newState, Phonon::State oldState)
{
if(newState != Phonon::PlayingState && newState != Phonon::PausedState) {
m_lastMetadata= QVariantMap();
notifyPropertyChanged("org.mpris.MediaPlayer2.Player", "Metadata");
}
notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "PlaybackStatus" );
notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "CanGoNext" );
notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "CanGoPrevious" );
notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "CanPause" );
}
// ...
void MprisPlugin::trackChanged()
{
PlaylistItemPtr track = The::audioEngine()->currentTrack();
m_lastMetadata = QVariantMap();
m_lastMetadata.insert( "mpris:trackid", QString( "/track/" ) + QString::number( The::audioEngine()->currentTrackID() ) );
m_lastMetadata.insert( "mpris:length", static_cast<qlonglong>( The::audioEngine()->currentTrackTotalTime() ) * 1000 );
m_lastMetadata.insert( "xesam:album", track->albumName() );
m_lastMetadata.insert( "xesam:artist", QStringList( track->artistName() ) );
m_lastMetadata.insert( "xesam:title", track->songName() );
m_lastMetadata.insert( "mpris:artUrl", QString( QUrl::fromLocalFile( track->coverArtFilename() ).toEncoded() ) );
notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "Metadata" );
}
void MprisPlugin::seekableChanged( bool seekable )
{
notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "CanSeek");
}
void MprisPlugin::trackLengthChanged( qint64 milliseconds )
{
if ( milliseconds >= 0 )
trackChanged();
}
} //mpris
To copy to clipboard, switch view to plain text mode
Bookmarks