124 lines
3 KiB
JavaScript
124 lines
3 KiB
JavaScript
|
const dbus = require('dbus-next');
|
||
|
const { info } = require('./render');
|
||
|
|
||
|
const playerName = process.env.BOUNCY_MUSICPLAYER || 'org.mpris.MediaPlayer2.rhythmbox';
|
||
|
|
||
|
const MPRIS_IFACE = 'org.mpris.MediaPlayer2.Player';
|
||
|
const MPRIS_PATH = '/org/mpris/MediaPlayer2';
|
||
|
const PROPERTIES_IFACE = 'org.freedesktop.DBus.Properties';
|
||
|
|
||
|
let artist = '';
|
||
|
let title = '';
|
||
|
let album = '';
|
||
|
|
||
|
let songStart; // timestamps
|
||
|
let songEnd;
|
||
|
let songPauseSpot;
|
||
|
let songPaused;
|
||
|
|
||
|
let infoFunc;
|
||
|
let warningFunc;
|
||
|
let errorFunc;
|
||
|
|
||
|
let lastStatus = '';
|
||
|
|
||
|
async function updateMetadata(metadata, props) {
|
||
|
try {
|
||
|
let artistVariant = metadata.value['xesam:artist'];
|
||
|
let titleVariant = metadata.value['xesam:title'];
|
||
|
artist = artistVariant ? artistVariant.value[0] : 'unknown';
|
||
|
title = titleVariant ? titleVariant.value : 'unknown';
|
||
|
|
||
|
let durationVariant = metadata.value['mpris:length'];
|
||
|
let duration = durationVariant ? durationVariant.value : 0n;
|
||
|
let position = (await props.Get(MPRIS_IFACE, 'Position')).value;
|
||
|
songStart = Date.now() - Number(position / 1000n);
|
||
|
songEnd = songStart + Number(duration / 1000n);
|
||
|
|
||
|
if (metadata.value['xesam:album'] && metadata.value['xesam:album'] !== 'Unknown') {
|
||
|
album = metadata.value['xesam:album'].value;
|
||
|
} else {
|
||
|
album = null;
|
||
|
}
|
||
|
|
||
|
songPaused = (await props.Get(MPRIS_IFACE, 'PlaybackStatus')).value === 'Paused';
|
||
|
if (songPaused) songPauseSpot = Date.now();
|
||
|
} catch(err) {
|
||
|
errorFunc(err.message);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
async function setupProps(props) {
|
||
|
let metadata = await props.Get(MPRIS_IFACE, 'Metadata');
|
||
|
updateMetadata(metadata, props);
|
||
|
|
||
|
props.on('PropertiesChanged', (iface, changed) => {
|
||
|
if (changed.hasOwnProperty('PlaybackStatus')) {
|
||
|
let status = changed['PlaybackStatus'];
|
||
|
if (lastStatus !== status.value) {
|
||
|
lastStatus = status.value;
|
||
|
info(status.value);
|
||
|
updateMetadata(metadata, props);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (changed.hasOwnProperty('Metadata')) {
|
||
|
metadata = changed['Metadata'];
|
||
|
updateMetadata(metadata, props);
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
async function setup() {
|
||
|
try {
|
||
|
let bus = dbus.sessionBus();
|
||
|
|
||
|
let obj = await bus.getProxyObject(playerName, MPRIS_PATH);
|
||
|
let props = obj.getInterface(PROPERTIES_IFACE);
|
||
|
|
||
|
setupProps(props);
|
||
|
|
||
|
infoFunc('connected to mpris')
|
||
|
} catch(err) {
|
||
|
errorFunc(err.message);
|
||
|
setTimeout(setup, 5000);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function init(e, w, i) {
|
||
|
errorFunc = e;
|
||
|
warningFunc = w;
|
||
|
infoFunc = i;
|
||
|
setup();
|
||
|
}
|
||
|
|
||
|
function getArtist() {
|
||
|
return artist;
|
||
|
}
|
||
|
function getTitle() {
|
||
|
return title;
|
||
|
}
|
||
|
function getAlbum() {
|
||
|
return album;
|
||
|
}
|
||
|
function getSongStart() {
|
||
|
return songStart;
|
||
|
}
|
||
|
function getSongEnd() {
|
||
|
return songEnd;
|
||
|
}
|
||
|
function getSongPauseSpot() {
|
||
|
return songPauseSpot;
|
||
|
}
|
||
|
function getSongPaused() {
|
||
|
return songPaused;
|
||
|
}
|
||
|
|
||
|
module.exports.init = init;
|
||
|
module.exports.getArtist = getArtist;
|
||
|
module.exports.getTitle = getTitle;
|
||
|
module.exports.getAlbum = getAlbum;
|
||
|
module.exports.getSongStart = getSongStart;
|
||
|
module.exports.getSongEnd = getSongEnd;
|
||
|
module.exports.getSongPauseSpot = getSongPauseSpot;
|
||
|
module.exports.getSongPaused = getSongPaused;
|