/
musicplayer.h
273 lines (211 loc) · 8.46 KB
/
musicplayer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
#ifndef MUSICPLAYER_H_
#define MUSICPLAYER_H_
#include <mythpluginexport.h>
// mythtv
#include <audiooutput.h>
#include <mythobservable.h>
// libmythmetadata
#include <musicmetadata.h>
// mythmusic
#include "decoderhandler.h"
// how long to wait before updating the lastplay and playcount fields
static constexpr std::chrono::seconds LASTPLAY_DELAY { 15s };
class AudioOutput;
class MainVisual;
class Playlist;
class MusicPlayerEvent : public MythEvent
{
public:
MusicPlayerEvent(Type type, int id) :
MythEvent(type), m_trackID(id) {}
MusicPlayerEvent(Type type, uint vol, bool muted) :
MythEvent(type), m_trackID(0), m_volume(vol), m_isMuted(muted) {}
~MusicPlayerEvent() override = default;
MythEvent *clone(void) const override // MythEvent
{ return new MusicPlayerEvent(*this); }
// for track changed/added/deleted/metadata changed/playlist changed events
int m_trackID;
// for volume changed event
uint m_volume {0};
bool m_isMuted {false};
static Type TrackChangeEvent;
static Type VolumeChangeEvent;
static Type TrackAddedEvent;
static Type TrackRemovedEvent;
static Type TrackUnavailableEvent;
static Type AllTracksRemovedEvent;
static Type MetadataChangedEvent;
static Type TrackStatsChangedEvent;
static Type AlbumArtChangedEvent;
static Type CDChangedEvent;
static Type PlaylistChangedEvent;
static Type PlayedTracksChangedEvent;
// No implicit copying.
protected:
MusicPlayerEvent(const MusicPlayerEvent &other) = default;
MusicPlayerEvent &operator=(const MusicPlayerEvent &other) = default;
public:
MusicPlayerEvent(MusicPlayerEvent &&) = delete;
MusicPlayerEvent &operator=(MusicPlayerEvent &&) = delete;
};
class MusicPlayer : public QObject, public MythObservable
{
Q_OBJECT
public:
explicit MusicPlayer(QObject *parent);
~MusicPlayer(void) override;
enum PlayMode
{
PLAYMODE_TRACKSPLAYLIST = 0,
PLAYMODE_TRACKSEDITOR,
PLAYMODE_RADIO,
};
void setPlayMode(PlayMode mode);
PlayMode getPlayMode(void) { return m_playMode; }
void playFile(const MusicMetadata &mdata);
void addListener(QObject *listener);
void removeListener(QObject *listener);
void addVisual(MainVisual *visual);
void removeVisual(MainVisual *visual);
void toggleMute(void);
MuteState getMuteState(void) const;
bool isMuted(void) const { return getMuteState() == kMuteAll; }
void setVolume(int volume);
void incVolume(void);
void decVolume(void);
uint getVolume(void) const;
void setSpeed(float speed);
void incSpeed();
void decSpeed();
float getSpeed() const { return m_playSpeed; }
void play(void);
void stop(bool stopAll = false);
void pause(void);
void next(void);
void previous(void);
void nextAuto(void);
bool isPlaying(void) const { return m_isPlaying; }
bool isPaused(void) { return getOutput() ? getOutput()->IsPaused() : false; }
bool isStopped(void) { return !(isPlaying() || isPaused()); }
bool hasClient(void) { return hasListeners(); }
/// This will allow/disallow the mini player showing on track changes
void autoShowPlayer(bool autoShow) { m_autoShowPlayer = autoShow; }
bool getAutoShowPlayer(void) const { return m_autoShowPlayer; }
/// This will allow/disallow the mini player showing even using its jumppoint
void canShowPlayer(bool canShow) { m_canShowPlayer = canShow; }
bool getCanShowPlayer(void) const { return m_canShowPlayer; }
Decoder *getDecoder(void) { return m_decoderHandler ? m_decoderHandler->getDecoder() : nullptr; }
DecoderHandler *getDecoderHandler(void) { return m_decoderHandler; }
AudioOutput *getOutput(void) { return m_output; }
void loadPlaylist(void);
void loadStreamPlaylist(void);
Playlist *getCurrentPlaylist(void);
static StreamList *getStreamList(void);
// these add and remove tracks from the active playlist
void removeTrack(int trackID);
void addTrack(int trackID, bool updateUI);
void moveTrackUpDown(bool moveUp, int whichTrack);
QList<MusicMetadata*> &getPlayedTracksList(void) { return m_playedList; }
int getCurrentTrackPos(void) const { return m_currentTrack; }
bool setCurrentTrackPos(int pos);
void changeCurrentTrack(int trackNo);
std::chrono::seconds getCurrentTrackTime(void) const { return m_currentTime; }
void activePlaylistChanged(int trackID, bool deleted);
void playlistChanged(int playlistID);
void savePosition(void);
void restorePosition(void);
void setAllowRestorePos(bool allow) { m_allowRestorePos = allow; }
void seek(std::chrono::seconds pos);
MusicMetadata *getCurrentMetadata(void);
MusicMetadata *getNextMetadata(void);
void sendMetadataChangedEvent(int trackID);
void sendTrackStatsChangedEvent(int trackID);
void sendAlbumArtChangedEvent(int trackID);
void sendTrackUnavailableEvent(int trackID);
void sendCDChangedEvent(void);
void toMap(InfoMap &infoMap) const;
void showMiniPlayer(void) const;
enum RepeatMode
{ REPEAT_OFF = 0,
REPEAT_TRACK,
REPEAT_ALL,
MAX_REPEAT_MODES
};
enum ShuffleMode
{ SHUFFLE_OFF = 0,
SHUFFLE_RANDOM,
SHUFFLE_INTELLIGENT,
SHUFFLE_ALBUM,
SHUFFLE_ARTIST,
MAX_SHUFFLE_MODES
};
enum ResumeMode
{ RESUME_OFF,
RESUME_FIRST,
RESUME_TRACK,
RESUME_EXACT,
MAX_RESUME_MODES
};
RepeatMode getRepeatMode(void) { return m_repeatMode; }
void setRepeatMode(RepeatMode mode) { m_repeatMode = mode; }
RepeatMode toggleRepeatMode(void);
ShuffleMode getShuffleMode(void) { return m_shuffleMode; }
void setShuffleMode(ShuffleMode mode);
ShuffleMode toggleShuffleMode(void);
ResumeMode getResumeMode(void);
void getBufferStatus(int *bufferAvailable, int *bufferSize) const;
public slots:
void StartPlayback(void);
void StopPlayback(void);
protected:
void customEvent(QEvent *event) override; // QObject
private:
void loadSettings(void);
void stopDecoder(void);
bool openOutputDevice(void);
void updateLastplay(void);
void updateVolatileMetadata(void);
void sendVolumeChangedEvent(void);
int getNotificationID(const QString &hostname);
void sendNotification(int notificationID, const QString &title, const QString &author, const QString &desc);
void setupDecoderHandler(void);
void decoderHandlerReady(void);
int m_currentTrack {-1};
std::chrono::seconds m_currentTime {0s};
MusicMetadata *m_oneshotMetadata {nullptr};
AudioOutput *m_output {nullptr};
DecoderHandler *m_decoderHandler {nullptr};
QSet<QObject*> m_visualisers;
PlayMode m_playMode {PLAYMODE_TRACKSPLAYLIST};
bool m_isPlaying {false};
bool m_isAutoplay {false};
bool m_canShowPlayer {true};
bool m_autoShowPlayer {true};
bool m_wasPlaying {false};
bool m_updatedLastplay {false};
bool m_allowRestorePos {true};
std::chrono::seconds m_lastplayDelay {LASTPLAY_DELAY};
ShuffleMode m_shuffleMode {SHUFFLE_OFF};
RepeatMode m_repeatMode {REPEAT_OFF};
ResumeMode m_resumeModePlayback {RESUME_EXACT};
ResumeMode m_resumeModeEditor {RESUME_OFF};
ResumeMode m_resumeModeRadio {RESUME_TRACK};
float m_playSpeed {1.0F};
// notification
bool m_showScannerNotifications {true};
QMap<QString, int> m_notificationMap;
// radio stuff
QList<MusicMetadata*> m_playedList;
std::chrono::seconds m_lastTrackStart {0s};
int m_bufferAvailable {0};
int m_bufferSize {0};
int m_errorCount {0};
};
Q_DECLARE_METATYPE(MusicPlayer::ResumeMode);
Q_DECLARE_METATYPE(MusicPlayer::RepeatMode);
Q_DECLARE_METATYPE(MusicPlayer::ShuffleMode);
// This global variable contains the MusicPlayer instance for the application
extern MPLUGIN_PUBLIC MusicPlayer *gPlayer;
// This stores the last MythMediaDevice that was detected:
extern MPLUGIN_PUBLIC QString gCDdevice;
#endif