Browse Source

MPRIS enhancements

- Add seek support
- Add volume support
- Add repeat support
- Add shuffle support
- Handle play/pause between sonixd/mpris client
- Fix MPRIS identity
master
jeffvli 3 years ago
committed by Jeff
parent
commit
2b79e5c7ff
  1. 27
      src/components/player/PlayerBar.tsx
  2. 59
      src/main.dev.js

27
src/components/player/PlayerBar.tsx

@ -2,6 +2,7 @@ import React, { useEffect, useState, useRef } from 'react';
import axios from 'axios';
import fs from 'fs';
import path from 'path';
import { ipcRenderer } from 'electron';
import { useQueryClient } from 'react-query';
import settings from 'electron-settings';
import { FlexboxGrid, Grid, Row, Col, Whisper } from 'rsuite';
@ -66,6 +67,14 @@ const PlayerBar = () => {
const playersRef = useRef<any>();
const history = useHistory();
ipcRenderer.on('seek-request', (_event, arg) => {
if (arg.currentPlayer === 1) {
playersRef.current.player1.audioEl.current.currentTime = Math.floor(arg.position / 1000000);
} else {
playersRef.current.player2.audioEl.current.currentTime = Math.floor(arg.position / 1000000);
}
});
useEffect(() => {
if (player.status === 'PLAYING') {
const interval = setInterval(() => {
@ -254,6 +263,9 @@ const PlayerBar = () => {
}, [playQueue.playerUpdated]);
useEffect(() => {
// Sets the MPRIS seek slider
ipcRenderer.send('seeked', manualSeek * 1000000);
const debounce = setTimeout(() => {
if (isDragging) {
if (playQueue.currentPlayer === 1) {
@ -301,8 +313,23 @@ const PlayerBar = () => {
if (playQueue[currentEntryList].length > 0) {
if (player.status === 'PAUSED') {
dispatch(setStatus('PLAYING'));
ipcRenderer.send('playpause', {
status: 'PLAYING',
position:
playQueue.currentPlayer === 1
? Math.floor(playersRef.current.player1.audioEl.current.currentTime * 1000000)
: Math.floor(playersRef.current.player2.audioEl.current.currentTime * 1000000),
});
} else {
dispatch(setStatus('PAUSED'));
ipcRenderer.send('playpause', {
status: 'PAUSED',
position:
playQueue.currentPlayer === 1
? Math.floor(playersRef.current.player1.audioEl.current.currentTime * 1000000)
: Math.floor(playersRef.current.player2.audioEl.current.currentTime * 1000000),
});
}
}
};

59
src/main.dev.js

@ -26,6 +26,9 @@ import playQueueReducer, {
incrementCurrentIndex,
fixPlayer2Index,
clearPlayQueue,
toggleShuffle,
toggleRepeat,
setVolume,
} from './redux/playQueueSlice';
import multiSelectReducer from './redux/multiSelectSlice';
import MenuBuilder from './menu';
@ -174,10 +177,13 @@ const previousTrack = () => {
if (isLinux) {
const mprisPlayer = Player({
name: 'Sonixd',
identity: 'A full-featured Subsonic API compatible cross-platform desktop client',
identity: 'Sonixd',
supportedUriSchemes: ['file'],
supportedMimeTypes: ['audio/mpeg', 'application/ogg'],
supportedInterfaces: ['player'],
rate: 1.0,
minimumRate: 1.0,
maximumRate: 1.0,
});
mprisPlayer.on('quit', () => {
@ -232,12 +238,61 @@ if (isLinux) {
}
});
ipcMain.on('current-song', (event, arg) => {
mprisPlayer.on('shuffle', () => {
store.dispatch(toggleShuffle());
settings.setSync('shuffle', !settings.getSync('shuffle'));
mprisPlayer.shuffle = Boolean(settings.getSync('shuffle'));
});
mprisPlayer.on('volume', (event) => {
store.dispatch(setVolume(event));
settings.setSync('volume', event);
});
mprisPlayer.on('loopStatus', () => {
const currentRepeat = settings.getSync('repeat');
const newRepeat = currentRepeat === 'none' ? 'all' : currentRepeat === 'all' ? 'one' : 'none';
store.dispatch(toggleRepeat());
mprisPlayer.loopStatus =
newRepeat === 'none' ? 'None' : newRepeat === 'all' ? 'Playlist' : 'Track';
settings.setSync('repeat', newRepeat);
});
mprisPlayer.on('position', (event) => {
const storeValues = store.getState();
mainWindow.webContents.send('seek-request', {
position: event.position,
currentPlayer: storeValues.playQueue.currentPlayer,
});
});
ipcMain.on('playpause', (_event, arg) => {
if (arg.status === 'PLAYING') {
mprisPlayer.playbackStatus = Player.PLAYBACK_STATUS_PLAYING;
} else {
mprisPlayer.playbackStatus = Player.PLAYBACK_STATUS_PAUSED;
}
setTimeout(() => {
mprisPlayer.seeked(arg.position);
}, 2000);
});
ipcMain.on('seeked', (_event, arg) => {
// Send the position from Sonixd to MPRIS on manual seek
mprisPlayer.seeked(arg);
});
ipcMain.on('current-song', (_event, arg) => {
if (mprisPlayer.playbackStatus !== 'Playing') {
mprisPlayer.playbackStatus = Player.PLAYBACK_STATUS_PLAYING;
}
mprisPlayer.metadata = {
'mpris:trackid': mprisPlayer.objectPath(`track/${arg.id}`),
'mpris:length': arg.duration ? Math.round((arg.duration || 0) * 1000 * 1000) : null,
'mpris:artUrl': arg.image.includes('placeholder') ? null : arg.image,
'xesam:title': arg.title || null,

Loading…
Cancel
Save