mirror of
https://github.com/clementine-player/Clementine
synced 2024-12-16 11:19:18 +01:00
Refactor and fix most of the MPRIS code. Fixes issue #374
This commit is contained in:
parent
0186c87bae
commit
987dd8c57a
@ -550,24 +550,24 @@ if(NOT APPLE AND NOT WIN32)
|
||||
# MPRIS DBUS interfaces
|
||||
qt4_add_dbus_adaptor(SOURCES
|
||||
dbus/org.freedesktop.MediaPlayer.player.xml
|
||||
core/mpris.h MPRIS core/mpris_player MprisPlayer)
|
||||
core/mpris.h mpris::Mpris1Player core/mpris_player MprisPlayer)
|
||||
qt4_add_dbus_adaptor(SOURCES
|
||||
dbus/org.freedesktop.MediaPlayer.root.xml
|
||||
core/mpris.h MPRIS core/mpris_root MprisRoot)
|
||||
core/mpris.h mpris::Mpris1Root core/mpris_root MprisRoot)
|
||||
qt4_add_dbus_adaptor(SOURCES
|
||||
dbus/org.freedesktop.MediaPlayer.tracklist.xml
|
||||
core/mpris.h MPRIS core/mpris_tracklist MprisTrackList)
|
||||
core/mpris.h mpris::Mpris1TrackList core/mpris_tracklist MprisTrackList)
|
||||
|
||||
# MPRIS 2.0 DBUS interfaces
|
||||
qt4_add_dbus_adaptor(SOURCES
|
||||
dbus/org.mpris.MediaPlayer2.Player.xml
|
||||
core/mpris2.h MPRIS2 core/mpris2_player Mpris2Player)
|
||||
core/mpris2.h mpris::Mpris2 core/mpris2_player Mpris2Player)
|
||||
qt4_add_dbus_adaptor(SOURCES
|
||||
dbus/org.mpris.MediaPlayer2.xml
|
||||
core/mpris2.h MPRIS2 core/mpris2_root Mpris2Root)
|
||||
core/mpris2.h mpris::Mpris2 core/mpris2_root Mpris2Root)
|
||||
qt4_add_dbus_adaptor(SOURCES
|
||||
dbus/org.mpris.MediaPlayer2.TrackList.xml
|
||||
core/mpris2.h MPRIS2 core/mpris2_tracklist Mpris2TrackList)
|
||||
core/mpris2.h mpris::Mpris2 core/mpris2_tracklist Mpris2TrackList)
|
||||
|
||||
# org.freedesktop.Notifications DBUS interface
|
||||
qt4_add_dbus_interface(SOURCES
|
||||
@ -583,8 +583,8 @@ if(NOT APPLE AND NOT WIN32)
|
||||
dbus/udisksdevice)
|
||||
|
||||
# MPRIS source
|
||||
list(APPEND SOURCES core/mpris.cpp core/mpris2.cpp)
|
||||
list(APPEND HEADERS core/mpris.h core/mpris2.h)
|
||||
list(APPEND SOURCES core/mpris_common.cpp core/mpris.cpp core/mpris2.cpp)
|
||||
list(APPEND HEADERS core/mpris_common.h core/mpris.h core/mpris2.h)
|
||||
|
||||
# Wiimotedev interface classes
|
||||
if(ENABLE_WIIMOTEDEV)
|
||||
@ -683,6 +683,8 @@ list(APPEND OTHER_SOURCES
|
||||
core/macglobalshortcutbackend.h
|
||||
core/macglobalshortcutbackend.mm
|
||||
core/modelfuturewatcher.h
|
||||
core/mpris_common.cpp
|
||||
core/mpris_common.h
|
||||
core/mpris.cpp
|
||||
core/mpris.h
|
||||
core/mpris2.cpp
|
||||
|
@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "mpris.h"
|
||||
#include "mpris_common.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDBusConnection>
|
||||
@ -23,10 +24,271 @@
|
||||
#include "core/mpris_player.h"
|
||||
#include "core/mpris_root.h"
|
||||
#include "core/mpris_tracklist.h"
|
||||
#include "engines/enginebase.h"
|
||||
#include "playlist/playlist.h"
|
||||
#include "playlist/playlistmanager.h"
|
||||
#include "playlist/playlistsequence.h"
|
||||
|
||||
namespace mpris {
|
||||
|
||||
Mpris1::Mpris1(Player* player, ArtLoader* art_loader, QObject* parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
qDBusRegisterMetaType<DBusStatus>();
|
||||
qDBusRegisterMetaType<Version>();
|
||||
|
||||
QDBusConnection::sessionBus().registerService("org.mpris.clementine");
|
||||
root_ = new Mpris1Root(player, this);
|
||||
player_ = new Mpris1Player(player, this);
|
||||
tracklist_ = new Mpris1TrackList(player, this);
|
||||
|
||||
connect(art_loader, SIGNAL(ArtLoaded(Song,QString)),
|
||||
player_, SLOT(CurrentSongChanged(Song,QString)));
|
||||
}
|
||||
|
||||
|
||||
Mpris1Root::Mpris1Root(Player* player, QObject* parent)
|
||||
: QObject(parent), player_(player) {
|
||||
new MprisRoot(this);
|
||||
QDBusConnection::sessionBus().registerObject("/", this);
|
||||
}
|
||||
|
||||
Mpris1Player::Mpris1Player(Player* player, QObject* parent)
|
||||
: QObject(parent), player_(player) {
|
||||
new MprisPlayer(this);
|
||||
QDBusConnection::sessionBus().registerObject("/Player", this);
|
||||
|
||||
connect(player->engine(), SIGNAL(StateChanged(Engine::State)), SLOT(EngineStateChanged()));
|
||||
}
|
||||
|
||||
Mpris1TrackList::Mpris1TrackList(Player* player, QObject* parent)
|
||||
: QObject(parent), player_(player) {
|
||||
new MprisTrackList(this);
|
||||
QDBusConnection::sessionBus().registerObject("/TrackList", this);
|
||||
|
||||
connect(player->playlists(), SIGNAL(PlaylistChanged()), SLOT(PlaylistChanged()));
|
||||
}
|
||||
|
||||
|
||||
void Mpris1TrackList::PlaylistChanged() {
|
||||
emit TrackListChange(GetLength());
|
||||
}
|
||||
|
||||
void Mpris1Player::EngineStateChanged() {
|
||||
emit StatusChange(GetStatus());
|
||||
emit CapsChange(GetCaps());
|
||||
}
|
||||
|
||||
void Mpris1Player::CurrentSongChanged(const Song& song, const QString& art_uri) {
|
||||
last_metadata_ = Mpris1::GetMetadata(song);
|
||||
|
||||
if (!art_uri.isEmpty()) {
|
||||
AddMetadata("arturl", art_uri, &last_metadata_);
|
||||
}
|
||||
|
||||
emit TrackChange(last_metadata_);
|
||||
emit StatusChange(GetStatus());
|
||||
emit CapsChange(GetCaps());
|
||||
}
|
||||
|
||||
|
||||
QString Mpris1Root::Identity() {
|
||||
return QString("%1 %2").arg(
|
||||
QCoreApplication::applicationName(),
|
||||
QCoreApplication::applicationVersion());
|
||||
}
|
||||
|
||||
Version Mpris1Root::MprisVersion() {
|
||||
Version version;
|
||||
version.major = 1;
|
||||
version.minor = 0;
|
||||
return version;
|
||||
}
|
||||
|
||||
void Mpris1Root::Quit() {
|
||||
qApp->quit();
|
||||
}
|
||||
|
||||
void Mpris1Player::Pause() {
|
||||
player_->Pause();
|
||||
}
|
||||
|
||||
void Mpris1Player::Stop() {
|
||||
player_->Stop();
|
||||
}
|
||||
|
||||
void Mpris1Player::Prev() {
|
||||
player_->Prev();
|
||||
}
|
||||
|
||||
void Mpris1Player::Play() {
|
||||
player_->Play();
|
||||
}
|
||||
|
||||
void Mpris1Player::Next() {
|
||||
player_->Next();
|
||||
}
|
||||
|
||||
void Mpris1Player::Repeat(bool repeat) {
|
||||
player_->Repeat(repeat);
|
||||
}
|
||||
|
||||
DBusStatus Mpris1Player::GetStatus() const {
|
||||
DBusStatus status;
|
||||
switch (player_->GetState()) {
|
||||
case Engine::Empty:
|
||||
case Engine::Idle:
|
||||
status.play = DBusStatus::Mpris_Stopped;
|
||||
break;
|
||||
case Engine::Playing:
|
||||
status.play = DBusStatus::Mpris_Playing;
|
||||
break;
|
||||
case Engine::Paused:
|
||||
status.play = DBusStatus::Mpris_Paused;
|
||||
break;
|
||||
}
|
||||
|
||||
PlaylistManager* playlists_ = player_->playlists();
|
||||
PlaylistSequence::RepeatMode repeat_mode = playlists_->sequence()->repeat_mode();
|
||||
|
||||
status.random = playlists_->sequence()->shuffle_mode() == PlaylistSequence::Shuffle_Off ? 0 : 1;
|
||||
status.repeat = repeat_mode == PlaylistSequence::Repeat_Track ? 1 : 0;
|
||||
status.repeat_playlist = (repeat_mode == PlaylistSequence::Repeat_Album ||
|
||||
repeat_mode == PlaylistSequence::Repeat_Playlist ||
|
||||
repeat_mode == PlaylistSequence::Repeat_Track) ? 1 : 0;
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
void Mpris1Player::VolumeSet(int volume) {
|
||||
player_->SetVolume(volume);
|
||||
}
|
||||
|
||||
int Mpris1Player::VolumeGet() const {
|
||||
return player_->VolumeGet();
|
||||
}
|
||||
|
||||
void Mpris1Player::PositionSet(int pos) {
|
||||
player_->Seek(pos/1000);
|
||||
}
|
||||
|
||||
int Mpris1Player::PositionGet() const {
|
||||
return player_->PositionGet();
|
||||
}
|
||||
|
||||
QVariantMap Mpris1Player::GetMetadata() const {
|
||||
return last_metadata_;
|
||||
}
|
||||
|
||||
int Mpris1Player::GetCaps() const {
|
||||
int caps = CAN_HAS_TRACKLIST;
|
||||
Engine::State state = player_->GetState();
|
||||
PlaylistItemPtr current_item = player_->GetCurrentItem();
|
||||
PlaylistManager* playlists = player_->playlists();
|
||||
|
||||
if (playlists->active()->rowCount() != 0) {
|
||||
caps |= CAN_PLAY;
|
||||
}
|
||||
|
||||
if (current_item) {
|
||||
caps |= CAN_PROVIDE_METADATA;
|
||||
if (state == Engine::Playing && (!current_item->options() & PlaylistItem::PauseDisabled)) {
|
||||
caps |= CAN_PAUSE;
|
||||
}
|
||||
if (state != Engine::Empty && current_item->Metadata().filetype() != Song::Type_Stream) {
|
||||
caps |= CAN_SEEK;
|
||||
}
|
||||
}
|
||||
|
||||
if (playlists->active()->next_index() != -1 ||
|
||||
playlists->active()->current_item_options() & PlaylistItem::ContainsMultipleTracks) {
|
||||
caps |= CAN_GO_NEXT;
|
||||
}
|
||||
if (playlists->active()->previous_index() != -1) {
|
||||
caps |= CAN_GO_PREV;
|
||||
}
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
void Mpris1Player::VolumeUp(int vol) {
|
||||
player_->VolumeUp(vol);
|
||||
}
|
||||
|
||||
void Mpris1Player::VolumeDown(int vol) {
|
||||
player_->VolumeDown(vol);
|
||||
}
|
||||
|
||||
void Mpris1Player::Mute() {
|
||||
player_->Mute();
|
||||
}
|
||||
|
||||
void Mpris1Player::ShowOSD() {
|
||||
player_->ShowOSD();
|
||||
}
|
||||
|
||||
int Mpris1TrackList::AddTrack(const QString& track, bool play) {
|
||||
return player_->AddTrack(track, play);
|
||||
}
|
||||
|
||||
void Mpris1TrackList::DelTrack(int index) {
|
||||
player_->DelTrack(index);
|
||||
}
|
||||
|
||||
int Mpris1TrackList::GetCurrentTrack() const {
|
||||
return player_->GetCurrentTrack();
|
||||
}
|
||||
|
||||
int Mpris1TrackList::GetLength() const {
|
||||
return player_->playlists()->active()->rowCount();
|
||||
}
|
||||
|
||||
QVariantMap Mpris1TrackList::GetMetadata(int pos) const {
|
||||
return Mpris1::GetMetadata(player_->GetItemAt(pos)->Metadata());
|
||||
}
|
||||
|
||||
void Mpris1TrackList::SetLoop(bool enable) {
|
||||
player_->SetLoop(enable);
|
||||
}
|
||||
|
||||
void Mpris1TrackList::SetRandom(bool enable) {
|
||||
player_->SetRandom(enable);
|
||||
}
|
||||
|
||||
void Mpris1TrackList::PlayTrack(int index) {
|
||||
player_->PlayAt(index, Engine::Manual, true);
|
||||
}
|
||||
|
||||
QVariantMap Mpris1::GetMetadata(const Song& song) {
|
||||
QVariantMap ret;
|
||||
|
||||
AddMetadata("location", song.filename(), &ret);
|
||||
AddMetadata("title", song.PrettyTitle(), &ret);
|
||||
AddMetadata("artist", song.artist(), &ret);
|
||||
AddMetadata("album", song.album(), &ret);
|
||||
AddMetadata("time", song.length(), &ret);
|
||||
AddMetadata("mtime", song.length() * 1000, &ret);
|
||||
AddMetadata("tracknumber", song.track(), &ret);
|
||||
AddMetadata("year", song.year(), &ret);
|
||||
AddMetadata("genre", song.genre(), &ret);
|
||||
AddMetadata("disc", song.disc(), &ret);
|
||||
AddMetadata("comment", song.comment(), &ret);
|
||||
AddMetadata("audio-bitrate", song.bitrate(), &ret);
|
||||
AddMetadata("audio-samplerate", song.samplerate(), &ret);
|
||||
AddMetadata("bpm", song.bpm(), &ret);
|
||||
AddMetadata("composer", song.composer(), &ret);
|
||||
AddMetadata("artUrl",
|
||||
song.art_manual().isEmpty() ? song.art_automatic() : song.art_manual(), &ret);
|
||||
if (song.rating() != -1.0) {
|
||||
AddMetadata("rating", song.rating() * 5, &ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace mpris
|
||||
|
||||
|
||||
QDBusArgument& operator<< (QDBusArgument& arg, const Version& version) {
|
||||
arg.beginStructure();
|
||||
arg << version.major << version.minor;
|
||||
@ -41,230 +303,22 @@ const QDBusArgument& operator>> (const QDBusArgument& arg, Version& version) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
MPRIS::MPRIS(Player* player, QObject* parent)
|
||||
: QObject(parent),
|
||||
player_(player)
|
||||
{
|
||||
MprisRoot* mpris_root = new MprisRoot(this);
|
||||
MprisPlayer* mpris_player = new MprisPlayer(this);
|
||||
MprisTrackList* mpris_tracklist = new MprisTrackList(this);
|
||||
|
||||
QDBusConnection bus(QDBusConnection::sessionBus());
|
||||
bus.registerService("org.mpris.clementine");
|
||||
bus.registerObject("/", mpris_root, QDBusConnection::ExportAllContents);
|
||||
bus.registerObject("/Player", mpris_player, QDBusConnection::ExportAllContents);
|
||||
bus.registerObject("/TrackList", mpris_tracklist, QDBusConnection::ExportAllContents);
|
||||
QDBusArgument& operator<< (QDBusArgument& arg, const DBusStatus& status) {
|
||||
arg.beginStructure();
|
||||
arg << status.play;
|
||||
arg << status.random;
|
||||
arg << status.repeat;
|
||||
arg << status.repeat_playlist;
|
||||
arg.endStructure();
|
||||
return arg;
|
||||
}
|
||||
|
||||
QString MPRIS::Identity() {
|
||||
return QString("%1 %2").arg(
|
||||
QCoreApplication::applicationName(),
|
||||
QCoreApplication::applicationVersion());
|
||||
}
|
||||
|
||||
Version MPRIS::MprisVersion() {
|
||||
Version version;
|
||||
version.major = 1;
|
||||
version.minor = 0;
|
||||
return version;
|
||||
}
|
||||
|
||||
void MPRIS::Quit() {
|
||||
qApp->quit();
|
||||
}
|
||||
|
||||
void MPRIS::Pause() {
|
||||
player_->Pause();
|
||||
}
|
||||
|
||||
void MPRIS::Stop() {
|
||||
player_->Stop();
|
||||
}
|
||||
|
||||
void MPRIS::Prev() {
|
||||
player_->Prev();
|
||||
}
|
||||
|
||||
void MPRIS::Play() {
|
||||
player_->Prev();
|
||||
}
|
||||
|
||||
void MPRIS::Next() {
|
||||
player_->Next();
|
||||
}
|
||||
|
||||
void MPRIS::Repeat(bool repeat) {
|
||||
player_->Repeat(repeat);
|
||||
}
|
||||
|
||||
DBusStatus MPRIS::GetStatus() const {
|
||||
DBusStatus status;
|
||||
switch (player_->GetState()) {
|
||||
case Engine::Empty:
|
||||
case Engine::Idle:
|
||||
status.play = DBusStatus::Mpris_Stopped;
|
||||
break;
|
||||
case Engine::Playing:
|
||||
status.play = DBusStatus::Mpris_Playing;
|
||||
break;
|
||||
case Engine::Paused:
|
||||
status.play = DBusStatus::Mpris_Paused;
|
||||
break;
|
||||
}
|
||||
|
||||
PlaylistManager* playlists_ = player_->GetPlaylists();
|
||||
PlaylistSequence::RepeatMode repeat_mode = playlists_->sequence()->repeat_mode();
|
||||
|
||||
status.random = playlists_->sequence()->shuffle_mode() == PlaylistSequence::Shuffle_Off ? 0 : 1;
|
||||
status.repeat = repeat_mode == PlaylistSequence::Repeat_Track ? 1 : 0;
|
||||
status.repeat_playlist = (repeat_mode == PlaylistSequence::Repeat_Album ||
|
||||
repeat_mode == PlaylistSequence::Repeat_Playlist ||
|
||||
repeat_mode == PlaylistSequence::Repeat_Track) ? 1 : 0;
|
||||
return status;
|
||||
|
||||
}
|
||||
void MPRIS::VolumeSet(int volume) {
|
||||
player_->SetVolume(volume);
|
||||
}
|
||||
|
||||
int MPRIS::VolumeGet() const {
|
||||
return player_->VolumeGet();
|
||||
}
|
||||
void MPRIS::PositionSet(int pos) {
|
||||
player_->Seek(pos/1000);
|
||||
}
|
||||
|
||||
int MPRIS::PositionGet() const {
|
||||
return player_->PositionGet()*1000;
|
||||
}
|
||||
|
||||
QVariantMap MPRIS::GetMetadata() const {
|
||||
return GetMetadata(player_->GetCurrentItem());
|
||||
}
|
||||
|
||||
int MPRIS::GetCaps() const {
|
||||
int caps = CAN_HAS_TRACKLIST;
|
||||
Engine::State state = player_->GetState();
|
||||
boost::shared_ptr<PlaylistItem> current_item_ = player_->GetCurrentItem();
|
||||
PlaylistManager* playlists_ = player_->GetPlaylists();
|
||||
|
||||
if (state == Engine::Paused) {
|
||||
caps |= CAN_PLAY;
|
||||
}
|
||||
|
||||
if (current_item_) {
|
||||
caps |= CAN_PROVIDE_METADATA;
|
||||
if (state == Engine::Playing && current_item_->options() & PlaylistItem::PauseDisabled) {
|
||||
caps |= CAN_PAUSE;
|
||||
}
|
||||
if (state != Engine::Empty && current_item_->Metadata().filetype() != Song::Type_Stream) {
|
||||
caps |= CAN_SEEK;
|
||||
}
|
||||
}
|
||||
|
||||
if (playlists_->active()->next_index() != -1 ||
|
||||
playlists_->active()->current_item_options() & PlaylistItem::ContainsMultipleTracks) {
|
||||
caps |= CAN_GO_NEXT;
|
||||
}
|
||||
if (playlists_->active()->previous_index() != -1) {
|
||||
caps |= CAN_GO_PREV;
|
||||
}
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
void MPRIS::VolumeUp(int vol) {
|
||||
player_->VolumeUp(vol);
|
||||
}
|
||||
|
||||
void MPRIS::VolumeDown(int vol) {
|
||||
player_->VolumeDown(vol);
|
||||
}
|
||||
|
||||
void MPRIS::Mute() {
|
||||
player_->Mute();
|
||||
}
|
||||
|
||||
void MPRIS::ShowOSD() {
|
||||
player_->ShowOSD();
|
||||
}
|
||||
|
||||
int MPRIS::AddTrack(const QString& track, bool play) {
|
||||
return player_->AddTrack(track, play);
|
||||
}
|
||||
|
||||
void MPRIS::DelTrack(int index) {
|
||||
player_->DelTrack(index);
|
||||
}
|
||||
|
||||
int MPRIS::GetCurrentTrack() const {
|
||||
return player_->GetCurrentTrack();
|
||||
}
|
||||
|
||||
int MPRIS::GetLength() const {
|
||||
return player_->GetLength();
|
||||
}
|
||||
|
||||
QVariantMap MPRIS::GetMetadata(int pos) const {
|
||||
return GetMetadata(player_->GetItemAt(pos));
|
||||
}
|
||||
|
||||
void MPRIS::SetLoop(bool enable) {
|
||||
player_->SetLoop(enable);
|
||||
}
|
||||
|
||||
void MPRIS::SetRandom(bool enable) {
|
||||
player_->SetRandom(enable);
|
||||
}
|
||||
|
||||
void MPRIS::PlayTrack(int index) {
|
||||
player_->PlayAt(index, Engine::Manual, true);
|
||||
}
|
||||
|
||||
void MPRIS::EmitCapsChange(int param) {
|
||||
emit CapsChange(param);
|
||||
}
|
||||
|
||||
void MPRIS::EmitTrackChange(QVariantMap param) {
|
||||
emit TrackChange(param);
|
||||
}
|
||||
|
||||
void MPRIS::EmitStatusChange(DBusStatus param) {
|
||||
emit StatusChange(param);
|
||||
}
|
||||
|
||||
void MPRIS::EmitTrackListChange(int i) {
|
||||
emit TrackListChange(i);
|
||||
}
|
||||
|
||||
|
||||
QVariantMap MPRIS::GetMetadata(PlaylistItemPtr item) const {
|
||||
using metadata::AddMetadata;
|
||||
QVariantMap ret;
|
||||
|
||||
if (!item)
|
||||
return ret;
|
||||
|
||||
Song song = item->Metadata();
|
||||
AddMetadata("location", item->Url().toString(), &ret);
|
||||
AddMetadata("title", song.PrettyTitle(), &ret);
|
||||
AddMetadata("artist", song.artist(), &ret);
|
||||
AddMetadata("album", song.album(), &ret);
|
||||
AddMetadata("time", song.length(), &ret);
|
||||
AddMetadata("tracknumber", song.track(), &ret);
|
||||
AddMetadata("year", song.year(), &ret);
|
||||
AddMetadata("genre", song.genre(), &ret);
|
||||
AddMetadata("disc", song.disc(), &ret);
|
||||
AddMetadata("comment", song.comment(), &ret);
|
||||
AddMetadata("audio-bitrate", song.bitrate(), &ret);
|
||||
AddMetadata("audio-samplerate", song.samplerate(), &ret);
|
||||
AddMetadata("bpm", song.bpm(), &ret);
|
||||
AddMetadata("composer", song.composer(), &ret);
|
||||
AddMetadata("artUrl",
|
||||
song.art_manual().isEmpty() ? song.art_automatic() : song.art_manual(), &ret);
|
||||
if (song.rating() != -1.0) {
|
||||
AddMetadata("rating", song.rating(), &ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
const QDBusArgument& operator>> (const QDBusArgument& arg, DBusStatus& status) {
|
||||
arg.beginStructure();
|
||||
arg >> status.play;
|
||||
arg >> status.random;
|
||||
arg >> status.repeat;
|
||||
arg >> status.repeat_playlist;
|
||||
arg.endStructure();
|
||||
return arg;
|
||||
}
|
||||
|
133
src/core/mpris.h
133
src/core/mpris.h
@ -26,7 +26,6 @@
|
||||
|
||||
class Player;
|
||||
|
||||
|
||||
struct DBusStatus { // From Amarok.
|
||||
int play; // Playing = 0, Paused = 1, Stopped = 2
|
||||
int random; // Linearly = 0, Randomly = 1
|
||||
@ -41,11 +40,21 @@ struct DBusStatus { // From Amarok.
|
||||
};
|
||||
Q_DECLARE_METATYPE(DBusStatus);
|
||||
|
||||
QDBusArgument& operator <<(QDBusArgument& arg, const DBusStatus& status);
|
||||
const QDBusArgument& operator >>(const QDBusArgument& arg, DBusStatus& status);
|
||||
|
||||
|
||||
struct Version {
|
||||
quint16 minor;
|
||||
quint16 major;
|
||||
};
|
||||
Q_DECLARE_METATYPE(Version)
|
||||
Q_DECLARE_METATYPE(Version);
|
||||
|
||||
QDBusArgument& operator <<(QDBusArgument& arg, const Version& version);
|
||||
const QDBusArgument& operator >>(const QDBusArgument& arg, Version& version);
|
||||
|
||||
|
||||
namespace mpris {
|
||||
|
||||
enum DBusCaps {
|
||||
NONE = 0,
|
||||
@ -59,56 +68,48 @@ enum DBusCaps {
|
||||
};
|
||||
|
||||
|
||||
#ifdef Q_WS_X11
|
||||
# include <QDBusArgument>
|
||||
QDBusArgument& operator<< (QDBusArgument& arg, const DBusStatus& status);
|
||||
const QDBusArgument& operator>> (const QDBusArgument& arg, DBusStatus& status);
|
||||
#endif
|
||||
class ArtLoader;
|
||||
class Mpris1Root;
|
||||
class Mpris1Player;
|
||||
class Mpris1TrackList;
|
||||
|
||||
|
||||
namespace metadata {
|
||||
|
||||
inline void AddMetadata(const QString& key, const QString& metadata, QVariantMap* map) {
|
||||
if (!metadata.isEmpty()) {
|
||||
(*map)[key] = metadata;
|
||||
}
|
||||
}
|
||||
|
||||
inline void AddMetadata(const QString& key, int metadata, QVariantMap* map) {
|
||||
if (metadata > 0) {
|
||||
(*map)[key] = metadata;
|
||||
}
|
||||
}
|
||||
|
||||
inline void AddMetadata(const QString& key, const QDateTime& metadata, QVariantMap* map) {
|
||||
if (metadata.isValid()) {
|
||||
(*map)[key] = metadata;
|
||||
}
|
||||
}
|
||||
|
||||
inline void AddMetadata(const QString &key, const QStringList& metadata, QVariantMap *map) {
|
||||
if (!metadata.isEmpty()) {
|
||||
(*map)[key] = metadata;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace metadata
|
||||
|
||||
QDBusArgument& operator<< (QDBusArgument& arg, const Version& version);
|
||||
const QDBusArgument& operator>> (const QDBusArgument& arg, Version& version);
|
||||
|
||||
class MPRIS : public QObject {
|
||||
class Mpris1 : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// Root interface
|
||||
MPRIS(Player* player, QObject* parent);
|
||||
Mpris1(Player* player, ArtLoader* art_loader, QObject* parent);
|
||||
|
||||
static QVariantMap GetMetadata(const Song& song);
|
||||
|
||||
private:
|
||||
Mpris1Root* root_;
|
||||
Mpris1Player* player_;
|
||||
Mpris1TrackList* tracklist_;
|
||||
};
|
||||
|
||||
|
||||
class Mpris1Root : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Mpris1Root(Player* player, QObject* parent);
|
||||
|
||||
QString Identity();
|
||||
void Quit();
|
||||
Version MprisVersion();
|
||||
|
||||
// Player Interface
|
||||
private:
|
||||
Player* player_;
|
||||
};
|
||||
|
||||
|
||||
class Mpris1Player : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Mpris1Player(Player* player, QObject* parent);
|
||||
|
||||
void Pause();
|
||||
void Stop();
|
||||
void Prev();
|
||||
@ -121,16 +122,38 @@ public:
|
||||
void PositionSet(int pos);
|
||||
int PositionGet() const;
|
||||
QVariantMap GetMetadata() const;
|
||||
QVariantMap GetMetadata(PlaylistItemPtr item) const;
|
||||
int GetCaps() const;
|
||||
|
||||
// Amarok Extensions for Player
|
||||
// Amarok extensions
|
||||
void VolumeUp(int vol);
|
||||
void VolumeDown(int vol);
|
||||
void Mute();
|
||||
void ShowOSD();
|
||||
|
||||
// Tracklist Interface
|
||||
public slots:
|
||||
void CurrentSongChanged(const Song& song, const QString& art_uri);
|
||||
|
||||
signals:
|
||||
void CapsChange(int);
|
||||
void TrackChange(const QVariantMap&);
|
||||
void StatusChange(DBusStatus);
|
||||
|
||||
private slots:
|
||||
void EngineStateChanged();
|
||||
|
||||
private:
|
||||
Player* player_;
|
||||
|
||||
QVariantMap last_metadata_;
|
||||
};
|
||||
|
||||
|
||||
class Mpris1TrackList : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Mpris1TrackList(Player* player, QObject* parent);
|
||||
|
||||
int AddTrack(const QString&, bool);
|
||||
void DelTrack(int index);
|
||||
int GetCurrentTrack() const;
|
||||
@ -139,27 +162,19 @@ public:
|
||||
void SetLoop(bool enable);
|
||||
void SetRandom(bool enable);
|
||||
|
||||
// Amarok extension.
|
||||
// Amarok extension
|
||||
void PlayTrack(int index);
|
||||
|
||||
// Signals Emitters
|
||||
void EmitCapsChange(int param);
|
||||
void EmitTrackChange(QVariantMap param);
|
||||
void EmitStatusChange(DBusStatus);
|
||||
void EmitTrackListChange(int i);
|
||||
|
||||
signals:
|
||||
void CapsChange(int);
|
||||
void TrackChange(QVariantMap);
|
||||
void StatusChange(DBusStatus);
|
||||
// TrackList
|
||||
void TrackListChange(int i);
|
||||
|
||||
private slots:
|
||||
void PlaylistChanged();
|
||||
|
||||
private:
|
||||
Player* player_;
|
||||
};
|
||||
|
||||
} // namespace mpris
|
||||
|
||||
#endif // MPRIS_H
|
||||
|
||||
|
||||
|
||||
|
@ -16,13 +16,14 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "mpris_common.h"
|
||||
#include "mpris.h"
|
||||
#include "mpris2.h"
|
||||
#include "core/albumcoverloader.h"
|
||||
#include "core/mpris2_player.h"
|
||||
#include "core/mpris2_root.h"
|
||||
#include "core/mpris2_tracklist.h"
|
||||
#include "core/player.h"
|
||||
#include "engines/enginebase.h"
|
||||
#include "playlist/playlistmanager.h"
|
||||
#include "playlist/playlistsequence.h"
|
||||
#include "ui/mainwindow.h"
|
||||
@ -34,20 +35,18 @@
|
||||
# include <qindicateserver.h>
|
||||
#endif
|
||||
|
||||
const char* MPRIS2::kMprisObjectPath = "/org/mpris/MediaPlayer2";
|
||||
const char* MPRIS2::kServiceName = "org.mpris.MediaPlayer2.clementine";
|
||||
const char* MPRIS2::kFreedesktopPath = "org.freedesktop.DBus.Properties";
|
||||
namespace mpris {
|
||||
|
||||
MPRIS2::MPRIS2(MainWindow* main_window, Player* player, QObject* parent)
|
||||
const char* Mpris2::kMprisObjectPath = "/org/mpris/MediaPlayer2";
|
||||
const char* Mpris2::kServiceName = "org.mpris.MediaPlayer2.clementine";
|
||||
const char* Mpris2::kFreedesktopPath = "org.freedesktop.DBus.Properties";
|
||||
|
||||
Mpris2::Mpris2(MainWindow* main_window, Player* player, ArtLoader* art_loader,
|
||||
QObject* parent)
|
||||
: QObject(parent),
|
||||
cover_loader_(new BackgroundThreadImplementation<AlbumCoverLoader, AlbumCoverLoader>(this)),
|
||||
art_request_id_(0),
|
||||
ui_(main_window),
|
||||
player_(player)
|
||||
{
|
||||
cover_loader_->Start();
|
||||
connect(cover_loader_, SIGNAL(Initialised()), SLOT(Initialised()));
|
||||
|
||||
new Mpris2Root(this);
|
||||
new Mpris2TrackList(this);
|
||||
new Mpris2Player(this);
|
||||
@ -61,9 +60,22 @@ MPRIS2::MPRIS2(MainWindow* main_window, Player* player, QObject* parent)
|
||||
indicate_server->setDesktopFile(DesktopEntry());
|
||||
indicate_server->show();
|
||||
#endif
|
||||
|
||||
connect(art_loader, SIGNAL(ArtLoaded(Song,QString)), SLOT(ArtLoaded(Song,QString)));
|
||||
|
||||
connect(player->engine(), SIGNAL(StateChanged(Engine::State)), SLOT(EngineStateChanged()));
|
||||
connect(player, SIGNAL(VolumeChanged(int)), SLOT(VolumeChanged()));
|
||||
}
|
||||
|
||||
void MPRIS2::emitNotification(const QString& name, const QVariant& val) {
|
||||
void Mpris2::EngineStateChanged() {
|
||||
EmitNotification("PlaybackStatus");
|
||||
}
|
||||
|
||||
void Mpris2::VolumeChanged() {
|
||||
EmitNotification("Volume");
|
||||
}
|
||||
|
||||
void Mpris2::EmitNotification(const QString& name, const QVariant& val) {
|
||||
QDBusMessage msg = QDBusMessage::createSignal(
|
||||
kMprisObjectPath, kFreedesktopPath, "PropertiesChanged");
|
||||
QVariantMap map;
|
||||
@ -76,7 +88,7 @@ void MPRIS2::emitNotification(const QString& name, const QVariant& val) {
|
||||
QDBusConnection::sessionBus().send(msg);
|
||||
}
|
||||
|
||||
void MPRIS2::emitNotification(const QString& name) {
|
||||
void Mpris2::EmitNotification(const QString& name) {
|
||||
QVariant value;
|
||||
if (name == "PlaybackStatus") value = PlaybackStatus();
|
||||
else if (name == "LoopStatus") value = LoopStatus();
|
||||
@ -86,30 +98,30 @@ void MPRIS2::emitNotification(const QString& name) {
|
||||
else if (name == "Position") value = Position();
|
||||
|
||||
if (value.isValid())
|
||||
emitNotification(name, value);
|
||||
EmitNotification(name, value);
|
||||
}
|
||||
|
||||
//------------------Root Interface--------------------------//
|
||||
|
||||
bool MPRIS2::CanQuit() const {
|
||||
bool Mpris2::CanQuit() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MPRIS2::CanRaise() const {
|
||||
bool Mpris2::CanRaise() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MPRIS2::HasTrackList() const {
|
||||
bool Mpris2::HasTrackList() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
QString MPRIS2::Identity() const {
|
||||
QString Mpris2::Identity() const {
|
||||
return QString("%1 %2").arg(
|
||||
QCoreApplication::applicationName(),
|
||||
QCoreApplication::applicationVersion());
|
||||
}
|
||||
|
||||
QString MPRIS2::DesktopEntry() const {
|
||||
QString Mpris2::DesktopEntry() const {
|
||||
QStringList xdg_data_dirs = QString(getenv("XDG_DATA_DIRS")).split(":");
|
||||
xdg_data_dirs.append("/usr/local/share/");
|
||||
xdg_data_dirs.append("/usr/share/");
|
||||
@ -123,7 +135,7 @@ QString MPRIS2::DesktopEntry() const {
|
||||
return QString();
|
||||
}
|
||||
|
||||
QStringList MPRIS2::SupportedUriSchemes() const {
|
||||
QStringList Mpris2::SupportedUriSchemes() const {
|
||||
static QStringList res = QStringList()
|
||||
<< "file"
|
||||
<< "http"
|
||||
@ -133,7 +145,7 @@ QStringList MPRIS2::SupportedUriSchemes() const {
|
||||
return res;
|
||||
}
|
||||
|
||||
QStringList MPRIS2::SupportedMimeTypes() const {
|
||||
QStringList Mpris2::SupportedMimeTypes() const {
|
||||
static QStringList res = QStringList()
|
||||
<< "application/ogg"
|
||||
<< "application/x-ogg"
|
||||
@ -163,16 +175,16 @@ QStringList MPRIS2::SupportedMimeTypes() const {
|
||||
return res;
|
||||
}
|
||||
|
||||
void MPRIS2::Raise() {
|
||||
void Mpris2::Raise() {
|
||||
ui_->show();
|
||||
ui_->activateWindow();
|
||||
}
|
||||
|
||||
void MPRIS2::Quit() {
|
||||
void Mpris2::Quit() {
|
||||
qApp->quit();
|
||||
}
|
||||
|
||||
QString MPRIS2::PlaybackStatus() const {
|
||||
QString Mpris2::PlaybackStatus() const {
|
||||
switch (player_->GetState()) {
|
||||
case Engine::Playing: return "Playing";
|
||||
case Engine::Paused: return "Paused";
|
||||
@ -180,8 +192,8 @@ QString MPRIS2::PlaybackStatus() const {
|
||||
}
|
||||
}
|
||||
|
||||
QString MPRIS2::LoopStatus() const {
|
||||
switch (player_->GetPlaylists()->sequence()->repeat_mode()) {
|
||||
QString Mpris2::LoopStatus() const {
|
||||
switch (player_->playlists()->sequence()->repeat_mode()) {
|
||||
case PlaylistSequence::Repeat_Album:
|
||||
case PlaylistSequence::Repeat_Playlist: return "Playlist";
|
||||
case PlaylistSequence::Repeat_Track: return "Track";
|
||||
@ -189,7 +201,7 @@ QString MPRIS2::LoopStatus() const {
|
||||
}
|
||||
}
|
||||
|
||||
void MPRIS2::SetLoopStatus(const QString& value) {
|
||||
void Mpris2::SetLoopStatus(const QString& value) {
|
||||
if (value == "None") {
|
||||
player_->SetLoop(PlaylistSequence::Repeat_Off);
|
||||
} else if (value == "Track") {
|
||||
@ -197,60 +209,40 @@ void MPRIS2::SetLoopStatus(const QString& value) {
|
||||
} else if (value == "Playlist") {
|
||||
player_->SetLoop(PlaylistSequence::Repeat_Playlist);
|
||||
}
|
||||
emitNotification("LoopStatus", value);
|
||||
EmitNotification("LoopStatus", value);
|
||||
}
|
||||
|
||||
double MPRIS2::Rate() const {
|
||||
double Mpris2::Rate() const {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
void MPRIS2::SetRate(double) {
|
||||
void Mpris2::SetRate(double) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
bool MPRIS2::Shuffle() const {
|
||||
return player_->GetPlaylists()->sequence()->shuffle_mode() !=
|
||||
bool Mpris2::Shuffle() const {
|
||||
return player_->playlists()->sequence()->shuffle_mode() !=
|
||||
PlaylistSequence::Shuffle_Off;
|
||||
}
|
||||
|
||||
void MPRIS2::SetShuffle(bool value) {
|
||||
void Mpris2::SetShuffle(bool value) {
|
||||
player_->SetRandom(value);
|
||||
emitNotification("Shuffle", value);
|
||||
EmitNotification("Shuffle", value);
|
||||
}
|
||||
|
||||
QVariantMap MPRIS2::Metadata() const {
|
||||
QVariantMap Mpris2::Metadata() const {
|
||||
return last_metadata_;
|
||||
}
|
||||
|
||||
void MPRIS2::UpdateMetadata(PlaylistItemPtr item) {
|
||||
void Mpris2::ArtLoaded(const Song& song, const QString& art_uri) {
|
||||
last_metadata_ = QVariantMap();
|
||||
|
||||
// Load the cover art
|
||||
art_request_item_ = item;
|
||||
art_request_id_ = cover_loader_->Worker()->LoadImageAsync(item->Metadata());
|
||||
}
|
||||
|
||||
void MPRIS2::Initialised() {
|
||||
cover_loader_->Worker()->SetPadOutputImage(true);
|
||||
cover_loader_->Worker()->SetDefaultOutputImage(QImage(":nocover.png"));
|
||||
connect(cover_loader_->Worker().get(), SIGNAL(ImageLoaded(quint64,QImage)),
|
||||
SLOT(TempArtLoaded(quint64,QImage)));
|
||||
}
|
||||
|
||||
void MPRIS2::TempArtLoaded(quint64 id, const QImage& image) {
|
||||
if (id != art_request_id_ || !art_request_item_)
|
||||
return;
|
||||
art_request_id_ = 0;
|
||||
last_metadata_ = QVariantMap();
|
||||
|
||||
Song song = art_request_item_->Metadata();
|
||||
|
||||
QString track_id = QString("/org/mpris/MediaPlayer2/Track/%1").
|
||||
arg(QString::number(player_->GetCurrentTrack()));
|
||||
|
||||
using metadata::AddMetadata;
|
||||
using mpris::AddMetadata;
|
||||
AddMetadata("mpris:trackid", track_id, &last_metadata_);
|
||||
AddMetadata("xesam:url", art_request_item_->Url().toString(), &last_metadata_);
|
||||
AddMetadata("xesam:url", song.filename(), &last_metadata_);
|
||||
AddMetadata("xesam:title", song.PrettyTitle(), &last_metadata_);
|
||||
AddMetadata("xesam:artist", QStringList() << song.artist(), &last_metadata_);
|
||||
AddMetadata("xesam:album", song.album(), &last_metadata_);
|
||||
@ -264,132 +256,130 @@ void MPRIS2::TempArtLoaded(quint64 id, const QImage& image) {
|
||||
AddMetadata("xesam:audioBPM", song.bpm(), &last_metadata_);
|
||||
AddMetadata("xesam:composer", song.composer(), &last_metadata_);
|
||||
|
||||
if (!image.isNull()) {
|
||||
temp_art_.reset(new QTemporaryFile(QDir::tempPath() + "/clementine-art-XXXXXX.jpg"));
|
||||
temp_art_->open();
|
||||
image.save(temp_art_->fileName(), "JPEG");
|
||||
AddMetadata("mpris:artUrl", "file://" + temp_art_->fileName(), &last_metadata_);
|
||||
if (!art_uri.isEmpty()) {
|
||||
AddMetadata("mpris:artUrl", art_uri, &last_metadata_);
|
||||
}
|
||||
|
||||
emitNotification("Metadata", last_metadata_);
|
||||
art_request_item_.reset();
|
||||
EmitNotification("Metadata", last_metadata_);
|
||||
}
|
||||
|
||||
double MPRIS2::Volume() const {
|
||||
double Mpris2::Volume() const {
|
||||
return player_->VolumeGet() / 100;
|
||||
}
|
||||
|
||||
void MPRIS2::SetVolume(double value) {
|
||||
void Mpris2::SetVolume(double value) {
|
||||
player_->SetVolume(value * 100);
|
||||
emitNotification("Volume",value);
|
||||
EmitNotification("Volume",value);
|
||||
}
|
||||
|
||||
qlonglong MPRIS2::Position() const {
|
||||
qlonglong Mpris2::Position() const {
|
||||
return player_->PositionGet() * 1e6;
|
||||
}
|
||||
|
||||
double MPRIS2::MaximumRate() const {
|
||||
double Mpris2::MaximumRate() const {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
double MPRIS2::MinimumRate() const {
|
||||
double Mpris2::MinimumRate() const {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
bool MPRIS2::CanGoNext() const {
|
||||
bool Mpris2::CanGoNext() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MPRIS2::CanGoPrevious() const {
|
||||
bool Mpris2::CanGoPrevious() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MPRIS2::CanPlay() const {
|
||||
bool Mpris2::CanPlay() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MPRIS2::CanPause() const {
|
||||
bool Mpris2::CanPause() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MPRIS2::CanSeek() const {
|
||||
bool Mpris2::CanSeek() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MPRIS2::CanControl() const {
|
||||
bool Mpris2::CanControl() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void MPRIS2::Next() {
|
||||
void Mpris2::Next() {
|
||||
player_->Next();
|
||||
emitNotification("PlaybackStatus",PlaybackStatus());
|
||||
emitNotification("Metadata",Metadata());
|
||||
EmitNotification("PlaybackStatus",PlaybackStatus());
|
||||
EmitNotification("Metadata",Metadata());
|
||||
}
|
||||
|
||||
void MPRIS2::Previous() {
|
||||
void Mpris2::Previous() {
|
||||
player_->Previous();
|
||||
emitNotification("PlaybackStatus",PlaybackStatus());
|
||||
emitNotification("Metadata",Metadata());
|
||||
EmitNotification("PlaybackStatus",PlaybackStatus());
|
||||
EmitNotification("Metadata",Metadata());
|
||||
}
|
||||
|
||||
void MPRIS2::Pause() {
|
||||
void Mpris2::Pause() {
|
||||
player_->Pause();
|
||||
emitNotification("PlaybackStatus",PlaybackStatus());
|
||||
emitNotification("Metadata",Metadata());
|
||||
EmitNotification("PlaybackStatus",PlaybackStatus());
|
||||
EmitNotification("Metadata",Metadata());
|
||||
}
|
||||
|
||||
void MPRIS2::PlayPause() {
|
||||
void Mpris2::PlayPause() {
|
||||
player_->PlayPause();
|
||||
emitNotification("PlaybackStatus",PlaybackStatus());
|
||||
emitNotification("Metadata",Metadata());
|
||||
EmitNotification("PlaybackStatus",PlaybackStatus());
|
||||
EmitNotification("Metadata",Metadata());
|
||||
}
|
||||
|
||||
void MPRIS2::Stop() {
|
||||
void Mpris2::Stop() {
|
||||
player_->Stop();
|
||||
emitNotification("PlaybackStatus",PlaybackStatus());
|
||||
emitNotification("Metadata",Metadata());
|
||||
EmitNotification("PlaybackStatus",PlaybackStatus());
|
||||
EmitNotification("Metadata",Metadata());
|
||||
}
|
||||
|
||||
void MPRIS2::Play() {
|
||||
void Mpris2::Play() {
|
||||
player_->Play();
|
||||
emitNotification("PlaybackStatus",PlaybackStatus());
|
||||
emitNotification("Metadata",Metadata());
|
||||
EmitNotification("PlaybackStatus",PlaybackStatus());
|
||||
EmitNotification("Metadata",Metadata());
|
||||
}
|
||||
|
||||
void MPRIS2::Seek(qlonglong offset) {
|
||||
void Mpris2::Seek(qlonglong offset) {
|
||||
player_->Seek(offset*1e6);
|
||||
}
|
||||
|
||||
void MPRIS2::SetPosition(const QDBusObjectPath& trackId, qlonglong offset) {
|
||||
void Mpris2::SetPosition(const QDBusObjectPath& trackId, qlonglong offset) {
|
||||
//TODO
|
||||
}
|
||||
|
||||
void MPRIS2::OpenUri(const QString &uri) {
|
||||
void Mpris2::OpenUri(const QString &uri) {
|
||||
player_->AddTrack(uri,true);
|
||||
}
|
||||
|
||||
TrackIds MPRIS2::Tracks() const {
|
||||
TrackIds Mpris2::Tracks() const {
|
||||
//TODO
|
||||
return TrackIds();
|
||||
}
|
||||
|
||||
bool MPRIS2::CanEditTracks() const {
|
||||
bool Mpris2::CanEditTracks() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
TrackMetadata MPRIS2::GetTracksMetadata(const TrackIds &tracks) const {
|
||||
TrackMetadata Mpris2::GetTracksMetadata(const TrackIds &tracks) const {
|
||||
//TODO
|
||||
return TrackMetadata();
|
||||
}
|
||||
|
||||
void MPRIS2::AddTrack(const QString &uri, const QDBusObjectPath &afterTrack, bool setAsCurrent) {
|
||||
void Mpris2::AddTrack(const QString &uri, const QDBusObjectPath &afterTrack, bool setAsCurrent) {
|
||||
//TODO
|
||||
}
|
||||
|
||||
void MPRIS2::RemoveTrack(const QDBusObjectPath &trackId) {
|
||||
void Mpris2::RemoveTrack(const QDBusObjectPath &trackId) {
|
||||
//TODO
|
||||
}
|
||||
|
||||
void MPRIS2::GoTo(const QDBusObjectPath &trackId) {
|
||||
void Mpris2::GoTo(const QDBusObjectPath &trackId) {
|
||||
//TODO
|
||||
}
|
||||
|
||||
} // namespace mpris
|
||||
|
@ -18,7 +18,6 @@
|
||||
#ifndef MPRIS2_H
|
||||
#define MPRIS2_H
|
||||
|
||||
#include "core/backgroundthread.h"
|
||||
#include "playlist/playlistitem.h"
|
||||
|
||||
#include <QMetaObject>
|
||||
@ -27,17 +26,18 @@
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
class AlbumCoverLoader;
|
||||
class MainWindow;
|
||||
class Player;
|
||||
|
||||
class QTemporaryFile;
|
||||
|
||||
typedef QList<QVariantMap> TrackMetadata;
|
||||
typedef QList<QDBusObjectPath> TrackIds;
|
||||
Q_DECLARE_METATYPE(TrackMetadata)
|
||||
|
||||
class MPRIS2 : public QObject {
|
||||
namespace mpris {
|
||||
|
||||
class ArtLoader;
|
||||
|
||||
class Mpris2 : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
//org.mpris.MediaPlayer2 MPRIS 2.0 Root interface
|
||||
@ -71,9 +71,7 @@ class MPRIS2 : public QObject {
|
||||
Q_PROPERTY( bool CanEditTracks READ CanEditTracks )
|
||||
|
||||
public:
|
||||
MPRIS2(MainWindow* main_window, Player* player, QObject* parent);
|
||||
void emitNotification(const QString& name);
|
||||
void emitNotification(const QString& name, const QVariant& val);
|
||||
Mpris2(MainWindow* main_window, Player* player, ArtLoader* art_loader, QObject* parent);
|
||||
|
||||
// Root Properties
|
||||
bool CanQuit() const;
|
||||
@ -130,9 +128,6 @@ public:
|
||||
void RemoveTrack(const QDBusObjectPath& trackId);
|
||||
void GoTo(const QDBusObjectPath& trackId);
|
||||
|
||||
public slots:
|
||||
void UpdateMetadata(PlaylistItemPtr item);
|
||||
|
||||
signals:
|
||||
// Player
|
||||
void Seeked(qlonglong position);
|
||||
@ -144,23 +139,25 @@ signals:
|
||||
void TrackMetadataChanged(const QDBusObjectPath& trackId, const TrackMetadata& metadata);
|
||||
|
||||
private slots:
|
||||
void Initialised();
|
||||
void TempArtLoaded(quint64 id, const QImage& image);
|
||||
void ArtLoaded(const Song& song, const QString& art_uri);
|
||||
void EngineStateChanged();
|
||||
void VolumeChanged();
|
||||
|
||||
private:
|
||||
void EmitNotification(const QString& name);
|
||||
void EmitNotification(const QString& name, const QVariant& val);
|
||||
|
||||
private:
|
||||
static const char* kMprisObjectPath;
|
||||
static const char* kServiceName;
|
||||
static const char* kFreedesktopPath;
|
||||
|
||||
boost::scoped_ptr<QTemporaryFile> temp_art_;
|
||||
BackgroundThread<AlbumCoverLoader>* cover_loader_;
|
||||
quint64 art_request_id_;
|
||||
PlaylistItemPtr art_request_item_;
|
||||
|
||||
QVariantMap last_metadata_;
|
||||
|
||||
MainWindow* ui_;
|
||||
Player* player_;
|
||||
};
|
||||
|
||||
} // namespace mpris
|
||||
|
||||
#endif
|
||||
|
69
src/core/mpris_common.cpp
Normal file
69
src/core/mpris_common.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
/* This file is part of Clementine.
|
||||
Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
|
||||
Clementine is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Clementine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "albumcoverloader.h"
|
||||
#include "mpris_common.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QTemporaryFile>
|
||||
|
||||
namespace mpris {
|
||||
|
||||
ArtLoader::ArtLoader(QObject* parent)
|
||||
: QObject(parent),
|
||||
cover_loader_(new BackgroundThreadImplementation<AlbumCoverLoader, AlbumCoverLoader>(this)),
|
||||
id_(0)
|
||||
{
|
||||
cover_loader_->Start();
|
||||
connect(cover_loader_, SIGNAL(Initialised()), SLOT(Initialised()));
|
||||
}
|
||||
|
||||
ArtLoader::~ArtLoader() {
|
||||
}
|
||||
|
||||
void ArtLoader::Initialised() {
|
||||
cover_loader_->Worker()->SetPadOutputImage(true);
|
||||
cover_loader_->Worker()->SetDefaultOutputImage(QImage(":nocover.png"));
|
||||
connect(cover_loader_->Worker().get(), SIGNAL(ImageLoaded(quint64,QImage)),
|
||||
SLOT(TempArtLoaded(quint64,QImage)));
|
||||
}
|
||||
|
||||
void ArtLoader::LoadArt(const Song& song) {
|
||||
last_song_ = song;
|
||||
id_ = cover_loader_->Worker()->LoadImageAsync(song);
|
||||
}
|
||||
|
||||
void ArtLoader::TempArtLoaded(quint64 id, const QImage& image) {
|
||||
if (id != id_)
|
||||
return;
|
||||
id_ = 0;
|
||||
|
||||
QString uri;
|
||||
|
||||
if (!image.isNull()) {
|
||||
temp_art_.reset(new QTemporaryFile(QDir::tempPath() + "/clementine-art-XXXXXX.jpg"));
|
||||
temp_art_->open();
|
||||
image.save(temp_art_->fileName(), "JPEG");
|
||||
|
||||
uri = "file://" + temp_art_->fileName();
|
||||
}
|
||||
|
||||
emit ArtLoaded(last_song_, uri);
|
||||
}
|
||||
|
||||
|
||||
} // namespace mpris
|
82
src/core/mpris_common.h
Normal file
82
src/core/mpris_common.h
Normal file
@ -0,0 +1,82 @@
|
||||
/* This file is part of Clementine.
|
||||
Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
|
||||
Clementine is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Clementine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MPRIS_COMMON_H
|
||||
#define MPRIS_COMMON_H
|
||||
|
||||
#include "backgroundthread.h"
|
||||
#include "song.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
#include <QVariantMap>
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
class AlbumCoverLoader;
|
||||
|
||||
class QImage;
|
||||
class QTemporaryFile;
|
||||
|
||||
namespace mpris {
|
||||
|
||||
class ArtLoader : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ArtLoader(QObject* parent);
|
||||
~ArtLoader();
|
||||
|
||||
public slots:
|
||||
void LoadArt(const Song& song);
|
||||
|
||||
signals:
|
||||
void ArtLoaded(const Song& song, const QString& uri);
|
||||
|
||||
private slots:
|
||||
void Initialised();
|
||||
void TempArtLoaded(quint64 id, const QImage& image);
|
||||
|
||||
private:
|
||||
boost::scoped_ptr<QTemporaryFile> temp_art_;
|
||||
BackgroundThread<AlbumCoverLoader>* cover_loader_;
|
||||
quint64 id_;
|
||||
|
||||
Song last_song_;
|
||||
};
|
||||
|
||||
|
||||
inline void AddMetadata(const QString& key, const QString& metadata, QVariantMap* map) {
|
||||
if (!metadata.isEmpty()) (*map)[key] = metadata;
|
||||
}
|
||||
|
||||
inline void AddMetadata(const QString& key, int metadata, QVariantMap* map) {
|
||||
if (metadata > 0) (*map)[key] = metadata;
|
||||
}
|
||||
|
||||
inline void AddMetadata(const QString& key, const QDateTime& metadata, QVariantMap* map) {
|
||||
if (metadata.isValid()) (*map)[key] = metadata;
|
||||
}
|
||||
|
||||
inline void AddMetadata(const QString &key, const QStringList& metadata, QVariantMap *map) {
|
||||
if (!metadata.isEmpty()) (*map)[key] = metadata;
|
||||
}
|
||||
|
||||
} // namespace mpris
|
||||
|
||||
#endif // MPRIS_COMMON_H
|
@ -37,6 +37,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef Q_WS_X11
|
||||
# include "mpris_common.h"
|
||||
# include "mpris.h"
|
||||
# include "mpris2.h"
|
||||
# include <QDBusConnection>
|
||||
@ -50,32 +51,11 @@
|
||||
|
||||
using boost::shared_ptr;
|
||||
|
||||
#ifdef Q_WS_X11
|
||||
QDBusArgument& operator<< (QDBusArgument& arg, const DBusStatus& status) {
|
||||
arg.beginStructure();
|
||||
arg << status.play;
|
||||
arg << status.random;
|
||||
arg << status.repeat;
|
||||
arg << status.repeat_playlist;
|
||||
arg.endStructure();
|
||||
return arg;
|
||||
}
|
||||
|
||||
const QDBusArgument& operator>> (const QDBusArgument& arg, DBusStatus& status) {
|
||||
arg.beginStructure();
|
||||
arg >> status.play;
|
||||
arg >> status.random;
|
||||
arg >> status.repeat;
|
||||
arg >> status.repeat_playlist;
|
||||
arg.endStructure();
|
||||
return arg;
|
||||
}
|
||||
#endif
|
||||
|
||||
Player::Player(MainWindow* main_window, PlaylistManager* playlists,
|
||||
LastFMService* lastfm, Engine::Type engine, QObject* parent)
|
||||
: QObject(parent),
|
||||
mpris_(NULL),
|
||||
mpris1_(NULL),
|
||||
mpris2_(NULL),
|
||||
playlists_(playlists),
|
||||
lastfm_(lastfm),
|
||||
@ -85,15 +65,20 @@ Player::Player(MainWindow* main_window, PlaylistManager* playlists,
|
||||
{
|
||||
#ifdef Q_WS_X11
|
||||
// MPRIS DBus interface.
|
||||
qDBusRegisterMetaType<DBusStatus>();
|
||||
qDBusRegisterMetaType<Version>();
|
||||
qDBusRegisterMetaType<QImage>();
|
||||
qDBusRegisterMetaType<TrackMetadata>();
|
||||
qDBusRegisterMetaType<TrackIds>();
|
||||
|
||||
// Loads album art and saves it to a file in /tmp for MPRIS clients to use
|
||||
mpris::ArtLoader* art_loader = new mpris::ArtLoader(this);
|
||||
connect(playlists, SIGNAL(CurrentSongChanged(Song)),
|
||||
art_loader, SLOT(LoadArt(Song)));
|
||||
|
||||
//MPRIS 1.0 implementation
|
||||
mpris_ = new MPRIS(this, this);
|
||||
mpris1_ = new mpris::Mpris1(this, art_loader, this);
|
||||
|
||||
//MPRIS 2.0 implementation
|
||||
mpris2_ = new MPRIS2(main_window, this, this);
|
||||
mpris2_ = new mpris::Mpris2(main_window, this, art_loader, this);
|
||||
#endif
|
||||
|
||||
settings_.beginGroup("Player");
|
||||
@ -101,7 +86,6 @@ Player::Player(MainWindow* main_window, PlaylistManager* playlists,
|
||||
SetVolume(settings_.value("volume", 50).toInt());
|
||||
|
||||
connect(engine_.get(), SIGNAL(Error(QString)), SIGNAL(Error(QString)));
|
||||
|
||||
}
|
||||
|
||||
Player::~Player() {
|
||||
@ -268,10 +252,6 @@ void Player::PlayPause() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef Q_WS_X11
|
||||
mpris2_->emitNotification("PlaybackStatus");
|
||||
#endif
|
||||
}
|
||||
|
||||
void Player::Stop() {
|
||||
@ -298,13 +278,6 @@ void Player::EngineStateChanged(Engine::State state) {
|
||||
case Engine::Empty:
|
||||
case Engine::Idle: emit Stopped(); break;
|
||||
}
|
||||
|
||||
#ifdef Q_WS_X11
|
||||
mpris_->EmitStatusChange(mpris_->GetStatus());
|
||||
mpris_->EmitCapsChange(mpris_->GetCaps());
|
||||
mpris2_->emitNotification("PlaybackStatus");
|
||||
mpris2_->emitNotification("Metadata");
|
||||
#endif
|
||||
}
|
||||
|
||||
void Player::SetVolume(int value) {
|
||||
@ -316,9 +289,6 @@ void Player::SetVolume(int value) {
|
||||
|
||||
if (volume != old_volume){
|
||||
emit VolumeChanged(volume);
|
||||
#ifdef Q_WS_X11
|
||||
mpris2_->emitNotification("Volume");
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
@ -353,22 +323,10 @@ void Player::PlayAt(int index, Engine::TrackChangeType change, bool reshuffle) {
|
||||
if (lastfm_->IsScrobblingEnabled())
|
||||
lastfm_->NowPlaying(current_item_->Metadata());
|
||||
}
|
||||
|
||||
#ifdef Q_WS_X11
|
||||
mpris_->EmitCapsChange(mpris_->GetCaps());
|
||||
mpris2_->emitNotification("PlaybackStatus");
|
||||
mpris2_->emitNotification("Metadata");
|
||||
#endif
|
||||
}
|
||||
|
||||
void Player::CurrentMetadataChanged(const Song& metadata) {
|
||||
lastfm_->NowPlaying(metadata);
|
||||
|
||||
#ifdef Q_WS_X11
|
||||
PlaylistItemPtr item = playlists_->active()->current_item();
|
||||
mpris_->EmitTrackChange(mpris_->GetMetadata(item));
|
||||
mpris2_->UpdateMetadata(item);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Player::Seek(int seconds) {
|
||||
@ -497,10 +455,6 @@ int Player::GetCurrentTrack() const {
|
||||
return playlists_->active()->current_index();
|
||||
}
|
||||
|
||||
int Player::GetLength() const {
|
||||
return playlists_->active()->rowCount();
|
||||
}
|
||||
|
||||
void Player::SetLoop(bool enable) {
|
||||
playlists_->active()->sequence()->SetRepeatMode(
|
||||
enable ? PlaylistSequence::Repeat_Playlist : PlaylistSequence::Repeat_Off);
|
||||
@ -511,12 +465,6 @@ void Player::SetRandom(bool enable) {
|
||||
enable ? PlaylistSequence::Shuffle_All : PlaylistSequence::Shuffle_Off);
|
||||
}
|
||||
|
||||
void Player::PlaylistChanged() {
|
||||
#ifdef Q_WS_X11
|
||||
mpris_->EmitTrackListChange(GetLength());
|
||||
#endif
|
||||
}
|
||||
|
||||
void Player::TrackAboutToEnd() {
|
||||
if (engine_->is_autocrossfade_enabled()) {
|
||||
// Crossfade is on, so just start playing the next track. The current one
|
||||
|
@ -32,8 +32,11 @@ class PlaylistManager;
|
||||
class Settings;
|
||||
class LastFMService;
|
||||
class MainWindow;
|
||||
class MPRIS;
|
||||
class MPRIS2;
|
||||
|
||||
namespace mpris {
|
||||
class Mpris1;
|
||||
class Mpris2;
|
||||
}
|
||||
|
||||
|
||||
#ifdef Q_WS_X11
|
||||
@ -53,13 +56,13 @@ class Player : public QObject {
|
||||
EngineBase* CreateEngine(Engine::Type engine);
|
||||
void Init();
|
||||
|
||||
EngineBase* GetEngine() { return engine_.get(); }
|
||||
EngineBase* engine() const { return engine_.get(); }
|
||||
Engine::State GetState() const;
|
||||
int GetVolume() const;
|
||||
|
||||
PlaylistItemPtr GetCurrentItem() const { return current_item_; }
|
||||
PlaylistItemPtr GetItemAt(int pos) const;
|
||||
PlaylistManager* GetPlaylists() {return playlists_; }
|
||||
PlaylistManager* playlists() const { return playlists_; }
|
||||
|
||||
public slots:
|
||||
void ReloadSettings();
|
||||
@ -83,8 +86,6 @@ class Player : public QObject {
|
||||
void HandleSpecialLoad(const PlaylistItem::SpecialLoadResult& result);
|
||||
void CurrentMetadataChanged(const Song& metadata);
|
||||
|
||||
void PlaylistChanged();
|
||||
|
||||
// MPRIS /Player
|
||||
void Mute();
|
||||
void Pause();
|
||||
@ -104,7 +105,6 @@ class Player : public QObject {
|
||||
int AddTrack(const QString&, bool);
|
||||
void DelTrack(int index);
|
||||
int GetCurrentTrack() const;
|
||||
int GetLength() const;
|
||||
void SetLoop(bool enable);
|
||||
void SetRandom(bool enable);
|
||||
|
||||
@ -131,8 +131,8 @@ class Player : public QObject {
|
||||
void NextInternal(Engine::TrackChangeType);
|
||||
|
||||
private:
|
||||
MPRIS* mpris_;
|
||||
MPRIS2* mpris2_;
|
||||
mpris::Mpris1* mpris1_;
|
||||
mpris::Mpris2* mpris2_;
|
||||
|
||||
PlaylistManager* playlists_;
|
||||
LastFMService* lastfm_;
|
||||
|
@ -204,12 +204,12 @@ MainWindow::MainWindow(Engine::Type engine, QWidget *parent)
|
||||
|
||||
// Start initialising the player
|
||||
player_->Init();
|
||||
background_streams_ = new BackgroundStreams(player_->GetEngine(), this);
|
||||
background_streams_ = new BackgroundStreams(player_->engine(), this);
|
||||
background_streams_->LoadStreams();
|
||||
|
||||
|
||||
#ifdef HAVE_GSTREAMER
|
||||
if (qobject_cast<GstEngine*>(player_->GetEngine()) == NULL) {
|
||||
if (qobject_cast<GstEngine*>(player_->engine()) == NULL) {
|
||||
ui_->action_transcode->setEnabled(false);
|
||||
}
|
||||
#else // HAVE_GSTREAMER
|
||||
@ -368,7 +368,6 @@ MainWindow::MainWindow(Engine::Type engine, QWidget *parent)
|
||||
connect(playlists_, SIGNAL(CurrentSongChanged(Song)), SLOT(SongChanged(Song)));
|
||||
connect(playlists_, SIGNAL(CurrentSongChanged(Song)), osd_, SLOT(SongChanged(Song)));
|
||||
connect(playlists_, SIGNAL(CurrentSongChanged(Song)), player_, SLOT(CurrentMetadataChanged(Song)));
|
||||
connect(playlists_, SIGNAL(PlaylistChanged()), player_, SLOT(PlaylistChanged()));
|
||||
connect(playlists_, SIGNAL(EditingFinished(QModelIndex)), SLOT(PlaylistEditFinished(QModelIndex)));
|
||||
connect(playlists_, SIGNAL(Error(QString)), SLOT(ShowErrorDialog(QString)));
|
||||
connect(playlists_, SIGNAL(SummaryTextChanged(QString)), ui_->playlist_summary, SLOT(setText(QString)));
|
||||
@ -518,16 +517,16 @@ MainWindow::MainWindow(Engine::Type engine, QWidget *parent)
|
||||
ConnectInfoView(artist_info_view_);
|
||||
|
||||
// Analyzer
|
||||
ui_->analyzer->SetEngine(player_->GetEngine());
|
||||
ui_->analyzer->SetEngine(player_->engine());
|
||||
ui_->analyzer->SetActions(ui_->action_visualisations);
|
||||
|
||||
// Equalizer
|
||||
connect(equalizer_.get(), SIGNAL(ParametersChanged(int,QList<int>)),
|
||||
player_->GetEngine(), SLOT(SetEqualizerParameters(int,QList<int>)));
|
||||
player_->engine(), SLOT(SetEqualizerParameters(int,QList<int>)));
|
||||
connect(equalizer_.get(), SIGNAL(EnabledChanged(bool)),
|
||||
player_->GetEngine(), SLOT(SetEqualizerEnabled(bool)));
|
||||
player_->GetEngine()->SetEqualizerEnabled(equalizer_->is_enabled());
|
||||
player_->GetEngine()->SetEqualizerParameters(
|
||||
player_->engine(), SLOT(SetEqualizerEnabled(bool)));
|
||||
player_->engine()->SetEqualizerEnabled(equalizer_->is_enabled());
|
||||
player_->engine()->SetEqualizerParameters(
|
||||
equalizer_->preamp_value(), equalizer_->gain_values());
|
||||
|
||||
// Statusbar widgets
|
||||
@ -791,8 +790,8 @@ void MainWindow::TrackSkipped(PlaylistItemPtr item) {
|
||||
// the database.
|
||||
if (item && item->IsLocalLibraryItem() && !playlists_->active()->has_scrobbled()) {
|
||||
Song song = item->Metadata();
|
||||
const int position = player_->GetEngine()->position();
|
||||
const int length = player_->GetEngine()->length();
|
||||
const int position = player_->engine()->position();
|
||||
const int length = player_->engine()->length();
|
||||
const float percentage = (length == 0 ? 1 : float(position) / length);
|
||||
|
||||
library_->backend()->IncrementSkipCountAsync(song.id(), percentage);
|
||||
@ -941,7 +940,7 @@ void MainWindow::FilePathChanged(const QString& path) {
|
||||
void MainWindow::UpdateTrackPosition() {
|
||||
// Track position in seconds
|
||||
PlaylistItemPtr item(player_->GetCurrentItem());
|
||||
const int position = std::floor(float(player_->GetEngine()->position()) / 1000.0 + 0.5);
|
||||
const int position = std::floor(float(player_->engine()->position()) / 1000.0 + 0.5);
|
||||
const int length = item->Metadata().length();
|
||||
|
||||
if (length <= 0) {
|
||||
@ -1573,7 +1572,7 @@ void MainWindow::EnsureSettingsDialogCreated() {
|
||||
settings_dialog_->SetLibraryDirectoryModel(library_->model()->directory_model());
|
||||
|
||||
#ifdef HAVE_GSTREAMER
|
||||
if (GstEngine* engine = qobject_cast<GstEngine*>(player_->GetEngine())) {
|
||||
if (GstEngine* engine = qobject_cast<GstEngine*>(player_->engine())) {
|
||||
settings_dialog_->SetGstEngine(engine);
|
||||
}
|
||||
#endif
|
||||
@ -1588,7 +1587,7 @@ void MainWindow::EnsureSettingsDialogCreated() {
|
||||
connect(settings_dialog_.get(), SIGNAL(accepted()), osd_, SLOT(ReloadSettings()));
|
||||
connect(settings_dialog_.get(), SIGNAL(accepted()), library_view_->view(), SLOT(ReloadSettings()));
|
||||
connect(settings_dialog_.get(), SIGNAL(accepted()), song_info_view_, SLOT(ReloadSettings()));
|
||||
connect(settings_dialog_.get(), SIGNAL(accepted()), player_->GetEngine(), SLOT(ReloadSettings()));
|
||||
connect(settings_dialog_.get(), SIGNAL(accepted()), player_->engine(), SLOT(ReloadSettings()));
|
||||
connect(settings_dialog_.get(), SIGNAL(accepted()), ui_->playlist->view(), SLOT(ReloadSettings()));
|
||||
#ifdef ENABLE_WIIMOTEDEV
|
||||
connect(settings_dialog_.get(), SIGNAL(accepted()), wiimotedev_shortcuts_.get(), SLOT(ReloadSettings()));
|
||||
@ -1657,7 +1656,7 @@ void MainWindow::ShowVisualisations() {
|
||||
connect(playlists_, SIGNAL(CurrentSongChanged(Song)), visualisation_.get(), SLOT(SongMetadataChanged(Song)));
|
||||
|
||||
#ifdef HAVE_GSTREAMER
|
||||
if (GstEngine* engine = qobject_cast<GstEngine*>(player_->GetEngine()))
|
||||
if (GstEngine* engine = qobject_cast<GstEngine*>(player_->engine()))
|
||||
visualisation_->SetEngine(engine);
|
||||
#endif
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user