add media session/mpris

This commit is contained in:
Kendall Garner 2023-05-22 21:11:26 -07:00 committed by Jeff
parent 76805a0b19
commit 97ccf3bc6d
4 changed files with 105 additions and 11 deletions

View file

@ -130,7 +130,7 @@ ipcMain.on(
}
if (shuffle) {
mprisPlayer.shuffle = shuffle;
mprisPlayer.shuffle = shuffle !== 'none';
}
if (!song) return;

View file

@ -7,6 +7,7 @@ import { AudioPlayer } from '/@/renderer/components';
import {
useCurrentPlayer,
useCurrentStatus,
useMuted,
usePlayer1Data,
usePlayer2Data,
usePlayerControls,
@ -62,6 +63,7 @@ export const Playerbar = () => {
const player2 = usePlayer2Data();
const status = useCurrentStatus();
const player = useCurrentPlayer();
const muted = useMuted();
const { autoNext } = usePlayerControls();
const autoNextFn = useCallback(() => {
@ -92,7 +94,7 @@ export const Playerbar = () => {
crossfadeDuration={settings.crossfadeDuration}
crossfadeStyle={settings.crossfadeStyle}
currentPlayer={player}
muted={settings.muted}
muted={muted}
playbackStyle={settings.style}
player1={player1}
player2={player2}

View file

@ -24,6 +24,7 @@ const mpvPlayerListener = isElectron() ? window.electron.mpvPlayerListener : nul
const ipc = isElectron() ? window.electron.ipc : null;
const utils = isElectron() ? window.electron.utils : null;
const mpris = isElectron() && utils?.isLinux() ? window.electron.mpris : null;
const mediaSession = !isElectron() ? navigator.mediaSession : null;
export const useCenterControls = (args: { playersRef: any }) => {
const { playersRef } = args;
@ -77,16 +78,50 @@ export const useCenterControls = (args: { playersRef: any }) => {
status?: PlayerStatus;
}) => {
const { song, currentTime, status } = args || {};
const time = currentTime || usePlayerStore.getState().current.time;
const playStatus = status || usePlayerStore.getState().current.status;
const track = song || usePlayerStore.getState().current.song;
mpris?.updateSong({
currentTime: currentTime || usePlayerStore.getState().current.time,
currentTime: time,
repeat: usePlayerStore.getState().repeat,
shuffle: usePlayerStore.getState().shuffle,
song: song || usePlayerStore.getState().current.song,
status:
(status || usePlayerStore.getState().current.status) === PlayerStatus.PLAYING
? 'Playing'
: 'Paused',
song: track,
status: playStatus === PlayerStatus.PLAYING ? 'Playing' : 'Paused',
});
if (mediaSession) {
mediaSession.playbackState = playStatus === PlayerStatus.PLAYING ? 'playing' : 'paused';
let metadata: MediaMetadata;
if (track) {
let artwork: MediaImage[];
if (track.imageUrl) {
const image300 = track.imageUrl
?.replace(/&size=\d+/, '&size=300')
.replace(/\?width=\d+/, '?width=300')
.replace(/&height=\d+/, '&height=300');
artwork = [{ sizes: '300x300', src: image300, type: 'image/png' }];
} else {
artwork = [];
}
metadata = new MediaMetadata({
album: track.album ?? '',
artist: track.artistName,
artwork,
title: track.name,
});
} else {
metadata = new MediaMetadata();
}
mediaSession.metadata = metadata;
}
};
const handlePlay = useCallback(() => {
@ -626,6 +661,57 @@ export const useCenterControls = (args: { playersRef: any }) => {
setCurrentTime,
]);
useEffect(() => {
if (!isElectron() && mediaSession) {
mediaSession.setActionHandler('nexttrack', () => {
handleNextTrack();
});
mediaSession.setActionHandler('pause', () => {
handlePause();
});
mediaSession.setActionHandler('play', () => {
handlePlay();
});
mediaSession.setActionHandler('previoustrack', () => {
handlePrevTrack();
});
mediaSession.setActionHandler('seekto', (evt) => {
const time = evt.seekTime;
if (time !== undefined) {
handleSeekSlider(time);
}
});
mediaSession.setActionHandler('stop', () => {
handleStop();
});
return () => {
mediaSession.setActionHandler('nexttrack', null);
mediaSession.setActionHandler('pause', null);
mediaSession.setActionHandler('play', null);
mediaSession.setActionHandler('previoustrack', null);
mediaSession.setActionHandler('seekto', null);
mediaSession.setActionHandler('stop', null);
};
}
return () => {};
}, [
handleNextTrack,
handlePause,
handlePlay,
handlePrevTrack,
handleSeekSlider,
handleStop,
setCurrentTime,
]);
useEffect(() => {
if (utils?.isLinux()) {
const unsubCurrentTime = usePlayerStore.subscribe(
@ -668,10 +754,8 @@ export const useCenterControls = (args: { playersRef: any }) => {
});
mpris.requestVolume((_e: any, data: { volume: number }) => {
const currentVolume = usePlayerStore.getState().volume;
const resultingVolume = data.volume + currentVolume;
let newVolume = data.volume * 100;
let newVolume = resultingVolume;
if (newVolume > 100) {
newVolume = 100;
} else if (newVolume < 0) {

View file

@ -6,6 +6,8 @@ import { useGeneralSettings } from '/@/renderer/store/settings.store';
const mpvPlayer = isElectron() ? window.electron.mpvPlayer : null;
const mpvPlayerListener = isElectron() ? window.electron.mpvPlayerListener : null;
const ipc = isElectron() ? window.electron.ipc : null;
const utils = isElectron() ? window.electron.utils : null;
const mpris = isElectron() && utils?.isLinux() ? window.electron.mpris : null;
const calculateVolumeUp = (volume: number, volumeWheelStep: number) => {
let volumeToSet;
@ -41,6 +43,7 @@ export const useRightControls = () => {
useEffect(() => {
if (isElectron()) {
mpvPlayer.volume(volume);
mpris?.updateVolume(volume / 100);
if (muted) {
mpvPlayer.mute();
@ -52,22 +55,26 @@ export const useRightControls = () => {
const handleVolumeSlider = (e: number) => {
mpvPlayer?.volume(e);
mpris?.updateVolume(e / 100);
setVolume(e);
};
const handleVolumeSliderState = (e: number) => {
mpris?.updateVolume(e / 100);
setVolume(e);
};
const handleVolumeDown = useCallback(() => {
const volumeToSet = calculateVolumeDown(volume, volumeWheelStep);
mpvPlayer?.volume(volumeToSet);
mpris?.updateVolume(volumeToSet / 100);
setVolume(volumeToSet);
}, [setVolume, volume, volumeWheelStep]);
const handleVolumeUp = useCallback(() => {
const volumeToSet = calculateVolumeUp(volume, volumeWheelStep);
mpvPlayer?.volume(volumeToSet);
mpris?.updateVolume(volumeToSet / 100);
setVolume(volumeToSet);
}, [setVolume, volume, volumeWheelStep]);
@ -81,6 +88,7 @@ export const useRightControls = () => {
}
mpvPlayer?.volume(volumeToSet);
mpris?.updateVolume(volumeToSet / 100);
setVolume(volumeToSet);
},
[setVolume, volume, volumeWheelStep],