1 /* This file is part of Clementine. 2 Copyright 2009-2012, David Sansome <me@davidsansome.com> 3 Copyright 2010, 2012, 2014, John Maguire <john.maguire@gmail.com> 4 Copyright 2011, Paweł Bara <keirangtp@gmail.com> 5 Copyright 2011, Andrea Decorte <adecorte@gmail.com> 6 Copyright 2012, Anand <anandtp@live.in> 7 Copyright 2013, Andreas <asfa194@gmail.com> 8 Copyright 2013, Kevin Cox <kevincox.ca@gmail.com> 9 Copyright 2014, Arnaud Bienner <arnaud.bienner@gmail.com> 10 Copyright 2014, Mark Furneaux <mark@romaco.ca> 11 Copyright 2014, Krzysztof Sobiecki <sobkas@gmail.com> 12 13 Clementine is free software: you can redistribute it and/or modify 14 it under the terms of the GNU General Public License as published by 15 the Free Software Foundation, either version 3 of the License, or 16 (at your option) any later version. 17 18 Clementine is distributed in the hope that it will be useful, 19 but WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 GNU General Public License for more details. 22 23 You should have received a copy of the GNU General Public License 24 along with Clementine. If not, see <http://www.gnu.org/licenses/>. 25 */ 26 27 #ifndef CORE_PLAYER_H_ 28 #define CORE_PLAYER_H_ 29 30 #include <memory> 31 32 #include <QDateTime> 33 #include <QObject> 34 #include <QSettings> 35 36 #include "config.h" 37 #include "core/song.h" 38 #include "core/urlhandler.h" 39 #include "covers/albumcoverloader.h" 40 #include "engines/engine_fwd.h" 41 #include "playlist/playlistitem.h" 42 43 class Application; 44 class Scrobbler; 45 46 class PlayerInterface : public QObject { 47 Q_OBJECT 48 49 public: QObject(parent)50 explicit PlayerInterface(QObject* parent = nullptr) : QObject(parent) {} 51 52 virtual EngineBase* engine() const = 0; 53 virtual Engine::State GetState() const = 0; 54 virtual int GetVolume() const = 0; 55 56 virtual PlaylistItemPtr GetCurrentItem() const = 0; 57 virtual PlaylistItemPtr GetItemAt(int pos) const = 0; 58 59 virtual void RegisterUrlHandler(UrlHandler* handler) = 0; 60 virtual void UnregisterUrlHandler(UrlHandler* handler) = 0; 61 62 public slots: 63 virtual void ReloadSettings() = 0; 64 65 // Manual track change to the specified track 66 virtual void PlayAt(int i, Engine::TrackChangeFlags change, 67 bool reshuffle) = 0; 68 69 // If there's currently a song playing, pause it, otherwise play the track 70 // that was playing last, or the first one on the playlist 71 virtual void PlayPause() = 0; 72 virtual void RestartOrPrevious() = 0; 73 74 // Skips this track. Might load more of the current radio station. 75 virtual void Next() = 0; 76 77 virtual void Previous() = 0; 78 virtual void SetVolume(int value) = 0; 79 virtual void VolumeUp() = 0; 80 virtual void VolumeDown() = 0; 81 virtual void SeekTo(int seconds) = 0; 82 // Moves the position of the currently playing song five seconds forward. 83 virtual void SeekForward() = 0; 84 // Moves the position of the currently playing song five seconds backwards. 85 virtual void SeekBackward() = 0; 86 87 virtual void CurrentMetadataChanged(const Song& metadata) = 0; 88 89 virtual void Mute() = 0; 90 virtual void Pause() = 0; 91 virtual void Stop(bool stop_after = false) = 0; 92 virtual void Play() = 0; 93 virtual void ShowOSD() = 0; 94 95 signals: 96 void Playing(); 97 void Paused(); 98 void Stopped(); 99 void PlaylistFinished(); 100 void VolumeChanged(int volume); 101 void Error(const QString& message); 102 void TrackSkipped(PlaylistItemPtr old_track); 103 // Emitted when there's a manual change to the current's track position. 104 void Seeked(qlonglong microseconds); 105 106 // Emitted when Player has processed a request to play another song. This 107 // contains 108 // the URL of the song and a flag saying whether it was able to play the song. 109 void SongChangeRequestProcessed(const QUrl& url, bool valid); 110 111 // The toggle parameter is true when user requests to toggle visibility for 112 // Pretty OSD 113 void ForceShowOSD(Song, bool toggle); 114 }; 115 116 class Player : public PlayerInterface { 117 Q_OBJECT 118 119 public: 120 explicit Player(Application* app, QObject* parent = nullptr); 121 ~Player(); 122 123 static const char* kSettingsGroup; 124 125 // Don't change the values: they are saved in preferences 126 enum PreviousBehaviour { 127 PreviousBehaviour_DontRestart = 1, 128 PreviousBehaviour_Restart = 2 129 }; 130 131 void Init(); 132 engine()133 EngineBase* engine() const { return engine_.get(); } GetState()134 Engine::State GetState() const { return last_state_; } 135 int GetVolume() const; 136 GetCurrentItem()137 PlaylistItemPtr GetCurrentItem() const { return current_item_; } 138 PlaylistItemPtr GetItemAt(int pos) const; 139 140 void RegisterUrlHandler(UrlHandler* handler); 141 void UnregisterUrlHandler(UrlHandler* handler); 142 143 const UrlHandler* HandlerForUrl(const QUrl& url) const; 144 145 bool PreviousWouldRestartTrack() const; 146 147 public slots: 148 void ReloadSettings(); 149 150 void PlayAt(int i, Engine::TrackChangeFlags change, bool reshuffle); 151 void PlayPause(); 152 void RestartOrPrevious(); 153 void Next(); 154 void Previous(); 155 void SetVolume(int value); VolumeUp()156 void VolumeUp() { SetVolume(GetVolume() + 5); } VolumeDown()157 void VolumeDown() { SetVolume(GetVolume() - 5); } 158 void SeekTo(int seconds); 159 void SeekForward(); 160 void SeekBackward(); 161 162 void CurrentMetadataChanged(const Song& metadata); 163 164 void Mute(); 165 void Pause(); 166 void Stop(bool stop_after = false); 167 void StopAfterCurrent(); 168 void IntroPointReached(); 169 void Play(); 170 void ShowOSD(); 171 void TogglePrettyOSD(); 172 173 private slots: 174 void EngineStateChanged(Engine::State); 175 void EngineMetadataReceived(const Engine::SimpleMetaBundle& bundle); 176 void TrackAboutToEnd(); 177 void TrackEnded(); 178 // Play the next item on the playlist - disregarding radio stations like 179 // last.fm that might have more tracks. 180 void NextItem(Engine::TrackChangeFlags change); 181 void PreviousItem(Engine::TrackChangeFlags change); 182 183 void NextInternal(Engine::TrackChangeFlags); 184 185 void ValidSongRequested(const QUrl&); 186 void InvalidSongRequested(const QUrl&); 187 188 void UrlHandlerDestroyed(QObject* object); 189 void HandleLoadResult(const UrlHandler::LoadResult& result); 190 191 private: 192 // Returns true if we were supposed to stop after this track. 193 bool HandleStopAfter(); 194 195 private: 196 Application* app_; 197 Scrobbler* lastfm_; 198 QSettings settings_; 199 200 PlaylistItemPtr current_item_; 201 202 std::unique_ptr<EngineBase> engine_; 203 Engine::TrackChangeFlags stream_change_type_; 204 Engine::State last_state_; 205 int nb_errors_received_; 206 207 QMap<QString, UrlHandler*> url_handlers_; 208 209 QUrl loading_async_; 210 211 int volume_before_mute_; 212 213 QDateTime last_pressed_previous_; 214 PreviousBehaviour menu_previousmode_; 215 int seek_step_sec_; 216 }; 217 218 #endif // CORE_PLAYER_H_ 219