-
Notifications
You must be signed in to change notification settings - Fork 54
/
mpris.js
executable file
Β·145 lines (125 loc) Β· 3.5 KB
/
mpris.js
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
#!/usr/bin/env node
let dbus = require('../');
let program = require('commander');
const MPRIS_IFACE = 'org.mpris.MediaPlayer2.Player';
const MPRIS_PATH = '/org/mpris/MediaPlayer2';
const PROPERTIES_IFACE = 'org.freedesktop.DBus.Properties';
async function listAll() {
let bus = dbus.sessionBus();
let obj = await bus.getProxyObject('org.freedesktop.DBus', '/org/freedesktop/DBus');
let iface = obj.getInterface('org.freedesktop.DBus');
let names = await iface.ListNames();
let result = names.filter((n) => n.startsWith('org.mpris.MediaPlayer2'))
return result;
}
function printEpilogue() {
console.log('');
console.log('Commands:');
console.log(' play, pause, stop, metadata, now-playing');
}
program
.version('0.0.1')
.arguments('<command>')
.option('-p, --player <player>', 'The player to control')
.option('-l, --list-all', 'List all players and exit');
program.on('--help', printEpilogue);
program.parse(process.argv)
if (!program.listAll && !program.args.length) {
program.outputHelp();
printEpilogue();
process.exit(0);
}
async function printNames() {
let names = await listAll();
for (let n of names) {
console.log(n);
}
}
function printMetadata(metadata) {
for (k of Object.keys(metadata.value)) {
let value = metadata.value[k].value;
console.log(k.padEnd(23) + value);
}
}
let lastNowPlaying = '';
function printNowPlaying(metadata) {
let artistVariant = metadata.value['xesam:artist'];
let titleVariant = metadata.value['xesam:title'];
let artist = artistVariant ? artistVariant.value : 'unknown';
let title = titleVariant ? titleVariant.value : 'unknown';
let nowPlaying = `${artist} - ${title}`;
if (lastNowPlaying !== nowPlaying) {
console.log(nowPlaying);
lastNowPlaying = nowPlaying;
}
}
async function nowPlaying(obj) {
return new Promise(resolve => {
let props = obj.getInterface(PROPERTIES_IFACE);
props.on('PropertiesChanged', (iface, changed, invalidated) => {
if (changed.hasOwnProperty('Metadata')) {
printNowPlaying(changed['Metadata']);
}
});
});
}
async function main() {
if (program.listAll) {
await printNames();
return 0;
}
let command = program.args[0];
if (['play', 'pause', 'stop', 'metadata', 'now-playing'].indexOf(command) === -1) {
program.outputHelp();
printEpilogue();
return 1;
}
let playerName = program.player;
if (!playerName) {
let names = await listAll();
if (!names.length) {
console.error('no players found');
return 1;
}
playerName = names[0];
}
if (!playerName.startsWith('org.mpris.MediaPlayer2')) {
playerName = `org.mpris.MediaPlayer2.${program.player}`;
}
let bus = dbus.sessionBus();
let obj = await bus.getProxyObject(playerName, MPRIS_PATH);
let player = obj.getInterface(MPRIS_IFACE);
let props = obj.getInterface(PROPERTIES_IFACE);
switch (command) {
case 'play':
await player.Play();
break;
case 'pause':
await player.Pause();
break;
case 'stop':
await player.Stop();
break;
case 'metadata': {
let metadata = await props.Get(MPRIS_IFACE, 'Metadata');
printMetadata(metadata);
break;
}
case 'now-playing': {
let metadata = await props.Get(MPRIS_IFACE, 'Metadata');
printNowPlaying(metadata);
await nowPlaying(obj);
// doesnt return
break;
}
}
return 0;
}
main()
.then(status => {
process.exit(status || 0);
})
.catch(error => {
console.log(error);
process.exit(1);
});