@jellybrick/mpris-service 2.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +1 -0
- package/.idea/discord.xml +7 -0
- package/.idea/jsLibraryMappings.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/mpris-service.iml +12 -0
- package/.idea/vcs.xml +6 -0
- package/.travis.yml +9 -0
- package/Dockerfile +31 -0
- package/LICENSE +22 -0
- package/Makefile +14 -0
- package/README.md +129 -0
- package/dist/constants.js +20 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.js +452 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/mpris-interface.js +57 -0
- package/dist/interfaces/mpris-interface.js.map +1 -0
- package/dist/interfaces/player.js +409 -0
- package/dist/interfaces/player.js.map +1 -0
- package/dist/interfaces/playlists.js +143 -0
- package/dist/interfaces/playlists.js.map +1 -0
- package/dist/interfaces/root.js +221 -0
- package/dist/interfaces/root.js.map +1 -0
- package/dist/interfaces/tracklist.js +164 -0
- package/dist/interfaces/tracklist.js.map +1 -0
- package/dist/interfaces/types.js +78 -0
- package/dist/interfaces/types.js.map +1 -0
- package/dist/logging.js +14 -0
- package/dist/logging.js.map +1 -0
- package/package.json +53 -0
- package/src/constants.js +31 -0
- package/src/index.js +477 -0
- package/src/interfaces/mpris-interface.js +57 -0
- package/src/interfaces/player.js +201 -0
- package/src/interfaces/playlists.js +82 -0
- package/src/interfaces/root.js +98 -0
- package/src/interfaces/tracklist.js +84 -0
- package/src/interfaces/types.js +75 -0
- package/src/logging.js +13 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
const dbus = require('dbus-next');
|
|
2
|
+
const MprisInterface = require('./mpris-interface');
|
|
3
|
+
const Variant = dbus.Variant;
|
|
4
|
+
const constants = require('../constants');
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
property, method, signal, DBusError,
|
|
8
|
+
ACCESS_READ, ACCESS_WRITE, ACCESS_READWRITE
|
|
9
|
+
} = dbus.interface;
|
|
10
|
+
|
|
11
|
+
class PlayerInterface extends MprisInterface {
|
|
12
|
+
constructor(player) {
|
|
13
|
+
super('org.mpris.MediaPlayer2.Player', player);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
_CanControl = true;
|
|
17
|
+
_CanPause = true;
|
|
18
|
+
_CanPlay = true;
|
|
19
|
+
_CanSeek = true;
|
|
20
|
+
_CanGoNext = true;
|
|
21
|
+
_CanGoPrevious = true;
|
|
22
|
+
_Metadata = {};
|
|
23
|
+
_MaximumRate = 1;
|
|
24
|
+
_MinimumRate = 1;
|
|
25
|
+
_Rate = 1;
|
|
26
|
+
_Shuffle = false;
|
|
27
|
+
_Volume = 0;
|
|
28
|
+
_LoopStatus = constants.LOOP_STATUS_NONE;
|
|
29
|
+
_PlaybackStatus = constants.PLAYBACK_STATUS_STOPPED;
|
|
30
|
+
|
|
31
|
+
@property({signature: 'b', access: ACCESS_READ})
|
|
32
|
+
get CanControl() {
|
|
33
|
+
return this._CanControl;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@property({signature: 'b', access: ACCESS_READ})
|
|
37
|
+
get CanPause() {
|
|
38
|
+
return this._CanPause;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@property({signature: 'b', access: ACCESS_READ})
|
|
42
|
+
get CanPlay() {
|
|
43
|
+
return this._CanPlay;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@property({signature: 'b', access: ACCESS_READ})
|
|
47
|
+
get CanSeek() {
|
|
48
|
+
return this._CanSeek;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@property({signature: 'b', access: ACCESS_READ})
|
|
52
|
+
get CanGoNext() {
|
|
53
|
+
return this._CanGoNext;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@property({signature: 'b', access: ACCESS_READ})
|
|
57
|
+
get CanGoPrevious() {
|
|
58
|
+
return this._CanGoPrevious;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@property({signature: 'a{sv}', access: ACCESS_READ})
|
|
62
|
+
get Metadata() {
|
|
63
|
+
return this._Metadata;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@property({signature: 'd', access: ACCESS_READ})
|
|
67
|
+
get MaximumRate() {
|
|
68
|
+
return this._MaximumRate;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@property({signature: 'd', access: ACCESS_READ})
|
|
72
|
+
get MinimumRate() {
|
|
73
|
+
return this._MinimumRate;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@property({signature: 'd'})
|
|
77
|
+
get Rate() {
|
|
78
|
+
return this._Rate;
|
|
79
|
+
}
|
|
80
|
+
set Rate(value) {
|
|
81
|
+
this._setPropertyInternal('Rate', value);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@property({signature: 'b'})
|
|
85
|
+
get Shuffle() {
|
|
86
|
+
return this._Shuffle;
|
|
87
|
+
}
|
|
88
|
+
set Shuffle(value) {
|
|
89
|
+
this._setPropertyInternal('Shuffle', value);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@property({signature: 'd'})
|
|
93
|
+
get Volume() {
|
|
94
|
+
return this._Volume;
|
|
95
|
+
}
|
|
96
|
+
set Volume(value) {
|
|
97
|
+
this._setPropertyInternal('Volume', value);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
@property({signature: 'x', access: ACCESS_READ})
|
|
101
|
+
get Position() {
|
|
102
|
+
let playerPosition = this.player.getPosition();
|
|
103
|
+
let position = Math.floor(playerPosition || 0);
|
|
104
|
+
if (isNaN(position)) {
|
|
105
|
+
const err = 'github.mpris_service.InvalidPositionError';
|
|
106
|
+
const message = `The player has set an invalid position: ${playerPosition}`;
|
|
107
|
+
throw new DBusError(err, message);
|
|
108
|
+
}
|
|
109
|
+
return position;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
@property({signature: 's'})
|
|
113
|
+
get LoopStatus() {
|
|
114
|
+
if (!constants.isLoopStatusValid(this._LoopStatus)) {
|
|
115
|
+
const err = 'github.mpris_service.InvalidLoopStatusError';
|
|
116
|
+
const message = `The player has set an invalid loop status: ${this._LoopStatus}`;
|
|
117
|
+
throw new DBusError(err, message);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return this._LoopStatus;
|
|
121
|
+
}
|
|
122
|
+
set LoopStatus(value) {
|
|
123
|
+
if (!constants.isLoopStatusValid(value)) {
|
|
124
|
+
const err = 'github.mpris_service.InvalidLoopStatusError';
|
|
125
|
+
const message = `Tried to set loop status to an invalid value: ${value}`;
|
|
126
|
+
throw new DBusError(err, message);
|
|
127
|
+
}
|
|
128
|
+
this._setPropertyInternal('LoopStatus', value);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
@property({signature: 's', access: ACCESS_READ})
|
|
132
|
+
get PlaybackStatus() {
|
|
133
|
+
if (!constants.isPlaybackStatusValid(this._PlaybackStatus)) {
|
|
134
|
+
const err = 'github.mpris_service.InvalidPlaybackStatusError';
|
|
135
|
+
const message = `The player has set an invalid playback status: ${this._PlaybackStatus}`;
|
|
136
|
+
throw new DBusError(err, message);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return this._PlaybackStatus;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
@method({})
|
|
143
|
+
Next() {
|
|
144
|
+
this.player.emit('next');
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
@method({})
|
|
148
|
+
Previous() {
|
|
149
|
+
this.player.emit('previous');
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
@method({})
|
|
153
|
+
Pause() {
|
|
154
|
+
this.player.emit('pause');
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
@method({})
|
|
158
|
+
PlayPause() {
|
|
159
|
+
this.player.emit('playpause');
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
@method({})
|
|
163
|
+
Stop() {
|
|
164
|
+
this.player.emit('stop');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
@method({})
|
|
168
|
+
Play() {
|
|
169
|
+
this.player.emit('play');
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
@method({inSignature: 'x'})
|
|
173
|
+
Seek(offset) {
|
|
174
|
+
// XXX overflow
|
|
175
|
+
offset = Number(offset);
|
|
176
|
+
this.player.emit('seek', offset);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
@method({inSignature: 'ox'})
|
|
180
|
+
SetPosition(trackId, position) {
|
|
181
|
+
let e = {
|
|
182
|
+
trackId: trackId,
|
|
183
|
+
// XXX overflow
|
|
184
|
+
position: Number(position)
|
|
185
|
+
};
|
|
186
|
+
this.player.emit('position', e);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
@method({inSignature: 's'})
|
|
190
|
+
OpenUri(uri) {
|
|
191
|
+
let e = { uri };
|
|
192
|
+
this.player.emit('open', e);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
@signal({signature: 'x'})
|
|
196
|
+
Seeked(position) {
|
|
197
|
+
return position;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
module.exports = PlayerInterface;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// TODO proper import
|
|
2
|
+
let MprisInterface = require('./mpris-interface');
|
|
3
|
+
let dbus = require('dbus-next');
|
|
4
|
+
let Variant = dbus.Variant;
|
|
5
|
+
let types = require('./types');
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
property, method, signal, DBusError,
|
|
9
|
+
ACCESS_READ, ACCESS_WRITE, ACCESS_READWRITE
|
|
10
|
+
} = dbus.interface;
|
|
11
|
+
|
|
12
|
+
class PlaylistsInterface extends MprisInterface {
|
|
13
|
+
constructor(player) {
|
|
14
|
+
super('org.mpris.MediaPlayer2.Playlists', player);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
_ActivePlaylist = [ false, types.emptyPlaylist ];
|
|
18
|
+
_PlaylistCount = 0;
|
|
19
|
+
|
|
20
|
+
@property({signature: 'u', access: ACCESS_READ})
|
|
21
|
+
get PlaylistCount() {
|
|
22
|
+
return this._PlaylistCount;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@property({signature: 'as', access: ACCESS_READ})
|
|
26
|
+
get Orderings() {
|
|
27
|
+
return ['Alphabetical', 'UserDefined'];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@property({signature: '(b(oss))', access: ACCESS_READ})
|
|
31
|
+
get ActivePlaylist() {
|
|
32
|
+
return this._ActivePlaylist;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
setActivePlaylistId(playlistId) {
|
|
36
|
+
let i = this.player.getPlaylistIndex(playlistId);
|
|
37
|
+
|
|
38
|
+
this.setProperty('ActivePlaylist', this.player.playlists[i] || null);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@method({inSignature: 'o'})
|
|
42
|
+
ActivatePlaylist(playlistId) {
|
|
43
|
+
this.player.emit('activatePlaylist', playlistId);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@method({inSignature: 'uusb', outSignature: 'a(oss)'})
|
|
47
|
+
GetPlaylists(index, maxCount, order, reverseOrder) {
|
|
48
|
+
if (!this.player.playlists) {
|
|
49
|
+
return [];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
let result = this.player.playlists.sort(function(a, b) {
|
|
53
|
+
let ret = 1;
|
|
54
|
+
switch (order) {
|
|
55
|
+
case 'Alphabetical':
|
|
56
|
+
ret = (a.Name > b.Name) ? 1 : -1;
|
|
57
|
+
break;
|
|
58
|
+
//case 'CreationDate':
|
|
59
|
+
//case 'ModifiedDate':
|
|
60
|
+
//case 'LastPlayDate':
|
|
61
|
+
case 'UserDefined':
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
return ret;
|
|
65
|
+
})
|
|
66
|
+
.slice(index, maxCount + index)
|
|
67
|
+
.map(types.playlistToDbus);
|
|
68
|
+
|
|
69
|
+
if (reverseOrder) {
|
|
70
|
+
result.reverse();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@signal({signature: '(oss)'})
|
|
77
|
+
PlaylistChanged(playlist) {
|
|
78
|
+
return types.playlistToDbus(playlist);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
module.exports = PlaylistsInterface;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
let MprisInterface = require('./mpris-interface');
|
|
2
|
+
let dbus = require('dbus-next');
|
|
3
|
+
let Variant = dbus.Variant;
|
|
4
|
+
|
|
5
|
+
let {
|
|
6
|
+
property, method, signal, DBusError,
|
|
7
|
+
ACCESS_READ, ACCESS_WRITE, ACCESS_READWRITE
|
|
8
|
+
} = dbus.interface;
|
|
9
|
+
|
|
10
|
+
class RootInterface extends MprisInterface {
|
|
11
|
+
constructor(player, opts={}) {
|
|
12
|
+
super('org.mpris.MediaPlayer2', player);
|
|
13
|
+
|
|
14
|
+
if (opts.hasOwnProperty('identity')) {
|
|
15
|
+
this._Identity = opts.identity;
|
|
16
|
+
}
|
|
17
|
+
if (opts.hasOwnProperty('supportedUriSchemes')) {
|
|
18
|
+
this._SupportedUriSchemes = opts.supportedUriSchemes;
|
|
19
|
+
}
|
|
20
|
+
if (opts.hasOwnProperty('supportedMimeTypes')) {
|
|
21
|
+
this._SupportedMimeTypes = opts.supportedMimeTypes;
|
|
22
|
+
}
|
|
23
|
+
if (opts.hasOwnProperty('desktopEntry')) {
|
|
24
|
+
this._DesktopEntry = opts.desktopEntry;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
_CanQuit = true;
|
|
29
|
+
_Fullscreen = false;
|
|
30
|
+
_CanSetFullscreen = false;
|
|
31
|
+
_CanRaise = true;
|
|
32
|
+
_HasTrackList = false;
|
|
33
|
+
_Identity = '';
|
|
34
|
+
// TODO optional properties
|
|
35
|
+
_DesktopEntry = '';
|
|
36
|
+
_SupportedUriSchemes = [];
|
|
37
|
+
_SupportedMimeTypes = [];
|
|
38
|
+
|
|
39
|
+
@property({signature: 'b', access: ACCESS_READ})
|
|
40
|
+
get CanQuit() {
|
|
41
|
+
return this._CanQuit;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@property({signature: 'b'})
|
|
45
|
+
get Fullscreen() {
|
|
46
|
+
return this._Fullscreen;
|
|
47
|
+
}
|
|
48
|
+
set Fullscreen(value) {
|
|
49
|
+
this._setPropertyInternal('Fullscreen', value);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@property({signature: 'b', access: ACCESS_READ})
|
|
53
|
+
get CanSetFullscreen() {
|
|
54
|
+
return this._CanSetFullscreen;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@property({signature: 'b', access: ACCESS_READ})
|
|
58
|
+
get CanRaise() {
|
|
59
|
+
return this._CanRaise;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@property({signature: 'b', access: ACCESS_READ})
|
|
63
|
+
get HasTrackList() {
|
|
64
|
+
return this._HasTrackList;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@property({signature: 's', access: ACCESS_READ})
|
|
68
|
+
get Identity() {
|
|
69
|
+
return this._Identity;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@property({signature: 's', access: ACCESS_READ})
|
|
73
|
+
get DesktopEntry() {
|
|
74
|
+
return this._DesktopEntry;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@property({signature: 'as', access: ACCESS_READ})
|
|
78
|
+
get SupportedUriSchemes() {
|
|
79
|
+
return this._SupportedUriSchemes;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@property({signature: 'as', access: ACCESS_READ})
|
|
83
|
+
get SupportedMimeTypes() {
|
|
84
|
+
return this._SupportedMimeTypes;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@method({})
|
|
88
|
+
Raise() {
|
|
89
|
+
this.player.emit('raise');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@method({})
|
|
93
|
+
Quit() {
|
|
94
|
+
this.player.emit('quit');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
module.exports = RootInterface;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
let MprisInterface = require('./mpris-interface');
|
|
2
|
+
let dbus = require('dbus-next');
|
|
3
|
+
let Variant = dbus.Variant;
|
|
4
|
+
let types = require('./types');
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
property, method, signal, DBusError,
|
|
8
|
+
ACCESS_READ, ACCESS_WRITE, ACCESS_READWRITE
|
|
9
|
+
} = dbus.interface;
|
|
10
|
+
|
|
11
|
+
class TracklistInterface extends MprisInterface {
|
|
12
|
+
constructor(player) {
|
|
13
|
+
super('org.mpris.MediaPlayer2.TrackList', player);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
_Tracks = [];
|
|
17
|
+
_CanEditTracks = false;
|
|
18
|
+
|
|
19
|
+
setTracks(tracksPlain) {
|
|
20
|
+
this.setProperty('Tracks', tracksPlain);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@property({signature: 'ao', access: ACCESS_READ})
|
|
24
|
+
get Tracks() {
|
|
25
|
+
return this._Tracks;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@property({signature: 'b', access: ACCESS_READ})
|
|
29
|
+
get CanEditTracks() {
|
|
30
|
+
return this._CanEditTracks;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@method({inSignature: 'ao', outSignature: 'aa{sv}'})
|
|
34
|
+
GetTracksMetadata(trackIds) {
|
|
35
|
+
return this.player.tracks.filter((t) => {
|
|
36
|
+
return trackIds.some((id) => id === t['mpris:trackid']);
|
|
37
|
+
}).map(types.metadataToDbus);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@method({inSignature: 'sob'})
|
|
41
|
+
AddTrack(uri, afterTrack, setAsCurrent) {
|
|
42
|
+
this.player.emit('addTrack', { uri, afterTrack, setAsCurrent });
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@method({inSignature: 'o'})
|
|
46
|
+
RemoveTrack(trackId) {
|
|
47
|
+
this.player.emit('removeTrack', trackId);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@method({inSignature: 'o'})
|
|
51
|
+
GoTo(trackId) {
|
|
52
|
+
this.player.emit('goTo', trackId);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@signal({signature: 'aoo'})
|
|
56
|
+
TrackListReplaced(replacedPlain) {
|
|
57
|
+
this.setTracks(replacedPlain);
|
|
58
|
+
// TODO what's the active track?
|
|
59
|
+
return [
|
|
60
|
+
this._Tracks,
|
|
61
|
+
'/org/mpris/MediaPlayer2/TrackList/NoTrack'
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@signal({signature: 'a{sv}'})
|
|
66
|
+
TrackAdded(metadata) {
|
|
67
|
+
return types.metadataToDbus(metadata);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@signal({signature: 'o'})
|
|
71
|
+
TrackRemoved(path) {
|
|
72
|
+
return path;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
@signal({signature: 'oa{sv}'})
|
|
76
|
+
TrackMetadataChanged(path, metadata){
|
|
77
|
+
return [
|
|
78
|
+
path,
|
|
79
|
+
types.metadataToDbus(metadata)
|
|
80
|
+
];
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
module.exports = TracklistInterface;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
let Variant = require('dbus-next').Variant;
|
|
2
|
+
let logging = require('../logging');
|
|
3
|
+
|
|
4
|
+
function guessMetadataSignature(key, value) {
|
|
5
|
+
if (key === 'mpris:trackid') {
|
|
6
|
+
return 'o';
|
|
7
|
+
} else if (key === 'mpris:length') {
|
|
8
|
+
return 'x';
|
|
9
|
+
} else if (typeof value === 'string') {
|
|
10
|
+
return 's';
|
|
11
|
+
} else if (typeof value === 'boolean') {
|
|
12
|
+
return 'b';
|
|
13
|
+
} else if (typeof value === 'number') {
|
|
14
|
+
return 'd';
|
|
15
|
+
} else if (Array.isArray(value) && value.every((v) => typeof v === 'string')) {
|
|
16
|
+
return 'as';
|
|
17
|
+
} else {
|
|
18
|
+
// type not supported yet
|
|
19
|
+
logging.warn(`could not determine metadata type for ${key}: ${value}`);
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function metadataToPlain(metadataVariant) {
|
|
25
|
+
let metadataPlain = {};
|
|
26
|
+
for (let k of Object.keys(metadataVariant)) {
|
|
27
|
+
let value = metadataVariant[k];
|
|
28
|
+
if (value === undefined || value === null) {
|
|
29
|
+
logging.warn(`ignoring a null metadata value for key ${k}`);
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (value.constructor === Variant) {
|
|
33
|
+
metadataPlain[k] = value.value;
|
|
34
|
+
} else {
|
|
35
|
+
metadataPlain[k] = value;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return metadataPlain;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function metadataToDbus(metadataPlain) {
|
|
42
|
+
let metadataVariant = {};
|
|
43
|
+
for (let k of Object.keys(metadataPlain)) {
|
|
44
|
+
let value = metadataPlain[k];
|
|
45
|
+
let signature = guessMetadataSignature(k, value);
|
|
46
|
+
if (signature) {
|
|
47
|
+
metadataVariant[k] = new Variant(signature, value);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return metadataVariant;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
let emptyPlaylist = ['/', '', ''];
|
|
54
|
+
|
|
55
|
+
function playlistToDbus(playlist) {
|
|
56
|
+
if (!playlist) {
|
|
57
|
+
return emptyPlaylist;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let { Id, Name, Icon } = playlist;
|
|
61
|
+
return [ Id, Name, Icon ];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function playlistToPlain(wire) {
|
|
65
|
+
let [ Id, Name, Icon ] = wire;
|
|
66
|
+
return { Id, Name, Icon };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
module.exports = {
|
|
70
|
+
metadataToPlain,
|
|
71
|
+
metadataToDbus,
|
|
72
|
+
playlistToPlain,
|
|
73
|
+
playlistToDbus,
|
|
74
|
+
emptyPlaylist
|
|
75
|
+
};
|
package/src/logging.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
let loggingEnabled = (process.env.MPRIS_SERVICE_DEBUG !== undefined && process.env.MPRIS_SERVICE_DEBUG !== '0');
|
|
2
|
+
|
|
3
|
+
module.exports.debug = function(message) {
|
|
4
|
+
if (loggingEnabled) {
|
|
5
|
+
console.log(message);
|
|
6
|
+
}
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
module.exports.warn = function(message) {
|
|
10
|
+
if (loggingEnabled) {
|
|
11
|
+
console.warn(message);
|
|
12
|
+
}
|
|
13
|
+
};
|