Factor out a PlayerInterface from Player, and use it in MPRIS1 and MPRIS2

This commit is contained in:
David Sansome 2011-02-13 18:36:29 +00:00
parent b38ce42ff8
commit e18409ebf4
12 changed files with 119 additions and 86 deletions

View File

@ -31,7 +31,7 @@
namespace mpris { namespace mpris {
Mpris1::Mpris1(Player* player, ArtLoader* art_loader, QObject* parent) Mpris1::Mpris1(PlayerInterface* player, ArtLoader* art_loader, QObject* parent)
: QObject(parent) : QObject(parent)
{ {
qDBusRegisterMetaType<DBusStatus>(); qDBusRegisterMetaType<DBusStatus>();
@ -47,13 +47,13 @@ Mpris1::Mpris1(Player* player, ArtLoader* art_loader, QObject* parent)
player_, SLOT(CurrentSongChanged(Song,QString))); player_, SLOT(CurrentSongChanged(Song,QString)));
} }
Mpris1Root::Mpris1Root(Player* player, QObject* parent) Mpris1Root::Mpris1Root(PlayerInterface* player, QObject* parent)
: QObject(parent), player_(player) { : QObject(parent), player_(player) {
new MprisRoot(this); new MprisRoot(this);
QDBusConnection::sessionBus().registerObject("/", this); QDBusConnection::sessionBus().registerObject("/", this);
} }
Mpris1Player::Mpris1Player(Player* player, QObject* parent) Mpris1Player::Mpris1Player(PlayerInterface* player, QObject* parent)
: QObject(parent), player_(player) { : QObject(parent), player_(player) {
new MprisPlayer(this); new MprisPlayer(this);
QDBusConnection::sessionBus().registerObject("/Player", this); QDBusConnection::sessionBus().registerObject("/Player", this);
@ -70,7 +70,7 @@ void Mpris1Player::PlaylistManagerInitialized() {
SLOT(RepeatModeChanged())); SLOT(RepeatModeChanged()));
} }
Mpris1TrackList::Mpris1TrackList(Player* player, QObject* parent) Mpris1TrackList::Mpris1TrackList(PlayerInterface* player, QObject* parent)
: QObject(parent), player_(player) { : QObject(parent), player_(player) {
new MprisTrackList(this); new MprisTrackList(this);
QDBusConnection::sessionBus().registerObject("/TrackList", this); QDBusConnection::sessionBus().registerObject("/TrackList", this);
@ -192,7 +192,7 @@ int Mpris1Player::VolumeGet() const {
} }
void Mpris1Player::PositionSet(int pos_msec) { void Mpris1Player::PositionSet(int pos_msec) {
player_->Seek(pos_msec / 1e3); player_->SeekTo(pos_msec / 1e3);
} }
int Mpris1Player::PositionGet() const { int Mpris1Player::PositionGet() const {

View File

@ -24,7 +24,7 @@
#include <QDBusArgument> #include <QDBusArgument>
#include <QObject> #include <QObject>
class Player; class PlayerInterface;
class Playlist; class Playlist;
struct DBusStatus { // From Amarok. struct DBusStatus { // From Amarok.
@ -79,7 +79,7 @@ class Mpris1 : public QObject {
Q_OBJECT Q_OBJECT
public: public:
Mpris1(Player* player, ArtLoader* art_loader, QObject* parent = 0); Mpris1(PlayerInterface* player, ArtLoader* art_loader, QObject* parent = 0);
static QVariantMap GetMetadata(const Song& song); static QVariantMap GetMetadata(const Song& song);
@ -98,14 +98,14 @@ class Mpris1Root : public QObject {
Q_OBJECT Q_OBJECT
public: public:
Mpris1Root(Player* player, QObject* parent = 0); Mpris1Root(PlayerInterface* player, QObject* parent = 0);
QString Identity(); QString Identity();
void Quit(); void Quit();
Version MprisVersion(); Version MprisVersion();
private: private:
Player* player_; PlayerInterface* player_;
}; };
@ -113,7 +113,7 @@ class Mpris1Player : public QObject {
Q_OBJECT Q_OBJECT
public: public:
Mpris1Player(Player* player, QObject* parent = 0); Mpris1Player(PlayerInterface* player, QObject* parent = 0);
void Pause(); void Pause();
void Stop(); void Stop();
@ -157,7 +157,7 @@ private slots:
void RepeatModeChanged(); void RepeatModeChanged();
private: private:
Player* player_; PlayerInterface* player_;
QVariantMap last_metadata_; QVariantMap last_metadata_;
}; };
@ -167,7 +167,7 @@ class Mpris1TrackList : public QObject {
Q_OBJECT Q_OBJECT
public: public:
Mpris1TrackList(Player* player, QObject* parent = 0); Mpris1TrackList(PlayerInterface* player, QObject* parent = 0);
int AddTrack(const QString&, bool); int AddTrack(const QString&, bool);
void DelTrack(int index); void DelTrack(int index);
@ -187,7 +187,7 @@ private slots:
void PlaylistChanged(Playlist* playlist); void PlaylistChanged(Playlist* playlist);
private: private:
Player* player_; PlayerInterface* player_;
}; };
} // namespace mpris } // namespace mpris

View File

@ -43,7 +43,7 @@ const char* Mpris2::kMprisObjectPath = "/org/mpris/MediaPlayer2";
const char* Mpris2::kServiceName = "org.mpris.MediaPlayer2.clementine"; const char* Mpris2::kServiceName = "org.mpris.MediaPlayer2.clementine";
const char* Mpris2::kFreedesktopPath = "org.freedesktop.DBus.Properties"; const char* Mpris2::kFreedesktopPath = "org.freedesktop.DBus.Properties";
Mpris2::Mpris2(Player* player, ArtLoader* art_loader, Mpris2::Mpris2(PlayerInterface* player, ArtLoader* art_loader,
Mpris1* mpris1, QObject* parent) Mpris1* mpris1, QObject* parent)
: QObject(parent), : QObject(parent),
player_(player), player_(player),
@ -400,7 +400,7 @@ void Mpris2::Play() {
void Mpris2::Seek(qlonglong offset) { void Mpris2::Seek(qlonglong offset) {
if(CanSeek()) { if(CanSeek()) {
player_->Seek(player_->engine()->position_nanosec() / 1e9 + offset / 1e6); player_->SeekTo(player_->engine()->position_nanosec() / 1e9 + offset / 1e6);
} }
} }
@ -409,7 +409,7 @@ void Mpris2::SetPosition(const QDBusObjectPath& trackId, qlonglong offset) {
offset *= 1e3; offset *= 1e3;
if(offset < player_->GetCurrentItem()->Metadata().length_nanosec()) { if(offset < player_->GetCurrentItem()->Metadata().length_nanosec()) {
player_->Seek(offset / 1e9); player_->SeekTo(offset / 1e9);
} }
} }
} }

View File

@ -27,7 +27,7 @@
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
class MainWindow; class MainWindow;
class Player; class PlayerInterface;
typedef QList<QVariantMap> TrackMetadata; typedef QList<QVariantMap> TrackMetadata;
typedef QList<QDBusObjectPath> TrackIds; typedef QList<QDBusObjectPath> TrackIds;
@ -72,7 +72,8 @@ class Mpris2 : public QObject {
Q_PROPERTY( bool CanEditTracks READ CanEditTracks ) Q_PROPERTY( bool CanEditTracks READ CanEditTracks )
public: public:
Mpris2(Player* player, ArtLoader* art_loader, Mpris1* mpris1, QObject* parent = 0); Mpris2(PlayerInterface* player, ArtLoader* art_loader, Mpris1* mpris1,
QObject* parent = 0);
void InitLibIndicate(); void InitLibIndicate();
@ -170,7 +171,7 @@ private:
QVariantMap last_metadata_; QVariantMap last_metadata_;
Player* player_; PlayerInterface* player_;
Mpris1* mpris1_; Mpris1* mpris1_;
}; };

View File

@ -36,16 +36,10 @@
using boost::shared_ptr; using boost::shared_ptr;
Player::Player(PlaylistManager* playlists, Player::Player(PlaylistManager* playlists, LastFMService* lastfm, QObject* parent)
#ifdef HAVE_LIBLASTFM : PlayerInterface(parent),
LastFMService* lastfm,
#endif
QObject* parent)
: QObject(parent),
playlists_(playlists), playlists_(playlists),
#ifdef HAVE_LIBLASTFM
lastfm_(lastfm), lastfm_(lastfm),
#endif
engine_(new GstEngine), engine_(new GstEngine),
stream_change_type_(Engine::First), stream_change_type_(Engine::First),
last_state_(Engine::Empty), last_state_(Engine::Empty),
@ -282,7 +276,7 @@ void Player::CurrentMetadataChanged(const Song& metadata) {
#endif #endif
} }
void Player::Seek(int seconds) { void Player::SeekTo(int seconds) {
qint64 nanosec = qBound(0ll, qint64(seconds) * qint64(1e9), qint64 nanosec = qBound(0ll, qint64(seconds) * qint64(1e9),
engine_->length_nanosec()); engine_->length_nanosec());
engine_->Seek(nanosec); engine_->Seek(nanosec);
@ -294,11 +288,11 @@ void Player::Seek(int seconds) {
} }
void Player::SeekForward() { void Player::SeekForward() {
Seek(engine()->position_nanosec() / 1e9 + 5); SeekTo(engine()->position_nanosec() / 1e9 + 5);
} }
void Player::SeekBackward() { void Player::SeekBackward() {
Seek(engine()->position_nanosec() / 1e9 - 5); SeekTo(engine()->position_nanosec() / 1e9 - 5);
} }
void Player::EngineMetadataReceived(const Engine::SimpleMetaBundle& bundle) { void Player::EngineMetadataReceived(const Engine::SimpleMetaBundle& bundle) {
@ -365,7 +359,7 @@ void Player::Pause() {
void Player::Play() { void Player::Play() {
switch (GetState()) { switch (GetState()) {
case Engine::Playing: case Engine::Playing:
Seek(0); SeekTo(0);
break; break;
case Engine::Paused: case Engine::Paused:
engine_->Unpause(); engine_->Unpause();

View File

@ -29,23 +29,77 @@
#include "engines/engine_fwd.h" #include "engines/engine_fwd.h"
#include "playlist/playlistitem.h" #include "playlist/playlistitem.h"
class LastFMService;
class PlaylistManager; class PlaylistManager;
class Settings; class Settings;
class MainWindow; class MainWindow;
#ifdef HAVE_LIBLASTFM
class LastFMService;
#endif
class Player : public QObject { class PlayerInterface : public QObject {
Q_OBJECT Q_OBJECT
public: public:
Player(PlaylistManager* playlists, PlayerInterface(QObject* parent = 0) : QObject(parent) {}
#ifdef HAVE_LIBLASTFM
LastFMService* lastfm, virtual EngineBase* engine() const = 0;
#endif virtual Engine::State GetState() const = 0;
QObject* parent = 0); virtual int GetVolume() const = 0;
virtual PlaylistItemPtr GetCurrentItem() const = 0;
virtual PlaylistItemPtr GetItemAt(int pos) const = 0;
virtual PlaylistManager* playlists() const = 0;
public slots:
virtual void ReloadSettings() = 0;
// Manual track change to the specified track
virtual void PlayAt(int i, Engine::TrackChangeType change, bool reshuffle) = 0;
// If there's currently a song playing, pause it, otherwise play the track
// that was playing last, or the first one on the playlist
virtual void PlayPause() = 0;
// Skips this track. Might load more of the current radio station.
virtual void Next() = 0;
virtual void Previous() = 0;
virtual void SetVolume(int value) = 0;
virtual void VolumeUp() = 0;
virtual void VolumeDown() = 0;
virtual void SeekTo(int seconds) = 0;
// Moves the position of the currently playing song five seconds forward.
virtual void SeekForward() = 0;
// Moves the position of the currently playing song five seconds backwards.
virtual void SeekBackward() = 0;
virtual void HandleSpecialLoad(const PlaylistItem::SpecialLoadResult& result) = 0;
virtual void CurrentMetadataChanged(const Song& metadata) = 0;
virtual void Mute() = 0;
virtual void Pause() = 0;
virtual void Stop() = 0;
virtual void Play() = 0;
virtual void ShowOSD() = 0;
signals:
void Playing();
void Paused();
void Stopped();
void PlaylistFinished();
void VolumeChanged(int volume);
void Error(const QString& message);
void TrackSkipped(PlaylistItemPtr old_track);
// Emitted when there's a manual change to the current's track position.
void Seeked(qlonglong microseconds);
void ForceShowOSD(Song);
};
class Player : public PlayerInterface {
Q_OBJECT
public:
Player(PlaylistManager* playlists, LastFMService* lastfm, QObject* parent = 0);
~Player(); ~Player();
void Init(); void Init();
@ -58,27 +112,18 @@ class Player : public QObject {
PlaylistItemPtr GetItemAt(int pos) const; PlaylistItemPtr GetItemAt(int pos) const;
PlaylistManager* playlists() const { return playlists_; } PlaylistManager* playlists() const { return playlists_; }
public slots: public slots:
void ReloadSettings(); void ReloadSettings();
// Manual track change to the specified track
void PlayAt(int i, Engine::TrackChangeType change, bool reshuffle); void PlayAt(int i, Engine::TrackChangeType change, bool reshuffle);
// If there's currently a song playing, pause it, otherwise play the track
// that was playing last, or the first one on the playlist
void PlayPause(); void PlayPause();
// Skips this track. Might load more of the current radio station.
void Next(); void Next();
void Previous(); void Previous();
void SetVolume(int value); void SetVolume(int value);
void VolumeUp() { SetVolume(GetVolume() + 5); } void VolumeUp() { SetVolume(GetVolume() + 5); }
void VolumeDown() { SetVolume(GetVolume() - 5); } void VolumeDown() { SetVolume(GetVolume() - 5); }
void Seek(int seconds); void SeekTo(int seconds);
// Moves the position of the currently playing song five seconds forward.
void SeekForward(); void SeekForward();
// Moves the position of the currently playing song five seconds backwards.
void SeekBackward(); void SeekBackward();
void HandleSpecialLoad(const PlaylistItem::SpecialLoadResult& result); void HandleSpecialLoad(const PlaylistItem::SpecialLoadResult& result);
@ -90,19 +135,6 @@ class Player : public QObject {
void Play(); void Play();
void ShowOSD(); void ShowOSD();
signals:
void Playing();
void Paused();
void Stopped();
void PlaylistFinished();
void VolumeChanged(int volume);
void Error(const QString& message);
void TrackSkipped(PlaylistItemPtr old_track);
// Emitted when there's a manual change to the current's track position.
void Seeked(qlonglong microseconds);
void ForceShowOSD(Song);
private slots: private slots:
void EngineStateChanged(Engine::State); void EngineStateChanged(Engine::State);
void EngineMetadataReceived(const Engine::SimpleMetaBundle& bundle); void EngineMetadataReceived(const Engine::SimpleMetaBundle& bundle);
@ -116,9 +148,7 @@ class Player : public QObject {
private: private:
PlaylistManager* playlists_; PlaylistManager* playlists_;
#ifdef HAVE_LIBLASTFM
LastFMService* lastfm_; LastFMService* lastfm_;
#endif
QSettings settings_; QSettings settings_;
PlaylistItemPtr current_item_; PlaylistItemPtr current_item_;

View File

@ -75,6 +75,8 @@ using boost::scoped_ptr;
#ifdef HAVE_LIBLASTFM #ifdef HAVE_LIBLASTFM
#include "radio/lastfmservice.h" #include "radio/lastfmservice.h"
#else
class LastFMService;
#endif #endif
#ifdef HAVE_DBUS #ifdef HAVE_DBUS
@ -292,19 +294,24 @@ int main(int argc, char *argv[]) {
// Seed the random number generator // Seed the random number generator
srand(time(NULL)); srand(time(NULL));
// Create some key objects
scoped_ptr<BackgroundThread<Database> > database( scoped_ptr<BackgroundThread<Database> > database(
new BackgroundThreadImplementation<Database, Database>(NULL)); new BackgroundThreadImplementation<Database, Database>(NULL));
database->Start(true); database->Start(true);
TaskManager task_manager; TaskManager task_manager;
PlaylistManager playlists(&task_manager, NULL); PlaylistManager playlists(&task_manager, NULL);
RadioModel radio_model(database.get(), &task_manager, NULL); RadioModel radio_model(database.get(), &task_manager, NULL);
Player player(&playlists
#ifdef HAVE_LIBLASTFM
,RadioModel::Service<LastFMService>()
#endif
);
// Get the last.fm service if it's available
LastFMService* lastfm_service = NULL;
#ifdef HAVE_LIBLASTFM
lastfm_service = RadioModel::Service<LastFMService>();
#endif
// Create the player
Player player(&playlists, lastfm_service);
// Create the tray icon and OSD
scoped_ptr<SystemTrayIcon> tray_icon(SystemTrayIcon::CreateSystemTrayIcon()); scoped_ptr<SystemTrayIcon> tray_icon(SystemTrayIcon::CreateSystemTrayIcon());
OSD osd(tray_icon.get()); OSD osd(tray_icon.get());

View File

@ -1,4 +1,4 @@
class Player : QObject { class PlayerInterface : QObject {
%TypeHeaderCode %TypeHeaderCode
#include "core/player.h" #include "core/player.h"
@ -29,7 +29,7 @@ public slots:
void VolumeDown(); void VolumeDown();
void Mute(); void Mute();
void Seek(int seconds); void SeekTo(int seconds);
void SeekForward(); void SeekForward();
void SeekBackward(); void SeekBackward();
@ -50,5 +50,5 @@ signals:
void ForceShowOSD(Song); void ForceShowOSD(Song);
private: private:
Player(); PlayerInterface();
}; };

View File

@ -132,7 +132,7 @@ Script* PythonEngine::CreateScript(const ScriptInfo& info) {
if (manager()->data().valid_) { if (manager()->data().valid_) {
AddObject(manager()->data().library_->backend(), sipType_LibraryBackend, "library"); AddObject(manager()->data().library_->backend(), sipType_LibraryBackend, "library");
AddObject(manager()->data().library_view_, sipType_LibraryView, "library_view"); AddObject(manager()->data().library_view_, sipType_LibraryView, "library_view");
AddObject(manager()->data().player_, sipType_Player, "player"); AddObject(manager()->data().player_, sipType_PlayerInterface, "player");
AddObject(manager()->data().playlists_, sipType_PlaylistManager, "playlists"); AddObject(manager()->data().playlists_, sipType_PlaylistManager, "playlists");
AddObject(manager()->data().radio_model_, sipType_RadioModel, "radio_model"); AddObject(manager()->data().radio_model_, sipType_RadioModel, "radio_model");
AddObject(manager()->data().settings_dialog_, sipType_SettingsDialog, "settings_dialog"); AddObject(manager()->data().settings_dialog_, sipType_SettingsDialog, "settings_dialog");

View File

@ -16,7 +16,7 @@ class ScriptInterface : QObject {
CLASS(MergedProxyModel), CLASS(MergedProxyModel),
CLASS(NetworkAccessManager), CLASS(NetworkAccessManager),
CLASS(ParserBase), CLASS(ParserBase),
CLASS(Player), CLASS(PlayerInterface),
CLASS(Playlist), CLASS(Playlist),
CLASS(PlaylistManager), CLASS(PlaylistManager),
CLASS(PlaylistParser), CLASS(PlaylistParser),

View File

@ -28,7 +28,7 @@
class LanguageEngine; class LanguageEngine;
class Library; class Library;
class LibraryView; class LibraryView;
class Player; class PlayerInterface;
class PlaylistManager; class PlaylistManager;
class RadioModel; class RadioModel;
class Script; class Script;
@ -58,9 +58,10 @@ public:
struct GlobalData { struct GlobalData {
GlobalData() : valid_(false) {} GlobalData() : valid_(false) {}
GlobalData(Library* library, LibraryView* library_view, Player* player, GlobalData(Library* library, LibraryView* library_view,
PlaylistManager* playlists, TaskManager* task_manager, PlayerInterface* player, PlaylistManager* playlists,
SettingsDialog* settings_dialog, RadioModel* radio_model) TaskManager* task_manager, SettingsDialog* settings_dialog,
RadioModel* radio_model)
: valid_(true), : valid_(true),
library_(library), library_(library),
library_view_(library_view), library_view_(library_view),
@ -74,7 +75,7 @@ public:
bool valid_; bool valid_;
Library* library_; Library* library_;
LibraryView* library_view_; LibraryView* library_view_;
Player* player_; PlayerInterface* player_;
PlaylistManager* playlists_; PlaylistManager* playlists_;
TaskManager* task_manager_; TaskManager* task_manager_;
SettingsDialog* settings_dialog_; SettingsDialog* settings_dialog_;

View File

@ -401,7 +401,7 @@ MainWindow::MainWindow(
connect(ui_->playlist->view(), SIGNAL(RightClicked(QPoint,QModelIndex)), SLOT(PlaylistRightClick(QPoint,QModelIndex))); connect(ui_->playlist->view(), SIGNAL(RightClicked(QPoint,QModelIndex)), SLOT(PlaylistRightClick(QPoint,QModelIndex)));
connect(ui_->playlist->view(), SIGNAL(SeekTrack(int)), ui_->track_slider, SLOT(Seek(int))); connect(ui_->playlist->view(), SIGNAL(SeekTrack(int)), ui_->track_slider, SLOT(Seek(int)));
connect(ui_->track_slider, SIGNAL(ValueChanged(int)), player_, SLOT(Seek(int))); connect(ui_->track_slider, SIGNAL(ValueChanged(int)), player_, SLOT(SeekTo(int)));
// Database connections // Database connections
connect(database_->Worker().get(), SIGNAL(Error(QString)), SLOT(ShowErrorDialog(QString))); connect(database_->Worker().get(), SIGNAL(Error(QString)), SLOT(ShowErrorDialog(QString)));
@ -1400,9 +1400,9 @@ void MainWindow::CommandlineOptionsReceived(const CommandlineOptions &options) {
player_->SetVolume(player_->GetVolume() + options.volume_modifier()); player_->SetVolume(player_->GetVolume() + options.volume_modifier());
if (options.seek_to() != -1) if (options.seek_to() != -1)
player_->Seek(options.seek_to() * 1e9); player_->SeekTo(options.seek_to() * 1e9);
else if (options.seek_by() != 0) else if (options.seek_by() != 0)
player_->Seek(player_->engine()->position_nanosec() + options.seek_by() * 1e9); player_->SeekTo(player_->engine()->position_nanosec() + options.seek_by() * 1e9);
if (options.play_track_at() != -1) if (options.play_track_at() != -1)
player_->PlayAt(options.play_track_at(), Engine::Manual, true); player_->PlayAt(options.play_track_at(), Engine::Manual, true);