mirror of
https://github.com/jeffvli/feishin.git
synced 2026-06-12 07:12:58 +02:00
fix mediasession breaking on player repeat (#1472)
- switch to single web player instance for loop instead of dual-player - this fixes the issue, but does have a breaking change if using the crossfade player
This commit is contained in:
@@ -23,6 +23,8 @@ export interface WebPlayerEngineHandle extends AudioPlayer {
|
||||
interface WebPlayerEngineProps {
|
||||
isMuted: boolean;
|
||||
isTransitioning: boolean;
|
||||
loopPlayer1: boolean;
|
||||
loopPlayer2: boolean;
|
||||
onEndedPlayer1: () => void;
|
||||
onEndedPlayer2: () => void;
|
||||
onErrorPause: () => void;
|
||||
@@ -55,6 +57,8 @@ export const WebPlayerEngine = (props: WebPlayerEngineProps) => {
|
||||
const {
|
||||
isMuted,
|
||||
isTransitioning,
|
||||
loopPlayer1,
|
||||
loopPlayer2,
|
||||
onEndedPlayer1,
|
||||
onEndedPlayer2,
|
||||
onErrorPause,
|
||||
@@ -292,8 +296,9 @@ export const WebPlayerEngine = (props: WebPlayerEngineProps) => {
|
||||
controls={false}
|
||||
height={0}
|
||||
id="web-player-1"
|
||||
loop={loopPlayer1}
|
||||
muted={isMuted}
|
||||
onEnded={src1 ? () => onEndedPlayer1() : undefined}
|
||||
onEnded={src1 && !loopPlayer1 ? () => onEndedPlayer1() : undefined}
|
||||
onError={handleOnError(
|
||||
player1Ref,
|
||||
() => onEndedPlayer1(),
|
||||
@@ -317,8 +322,9 @@ export const WebPlayerEngine = (props: WebPlayerEngineProps) => {
|
||||
controls={false}
|
||||
height={0}
|
||||
id="web-player-2"
|
||||
loop={loopPlayer2}
|
||||
muted={isMuted}
|
||||
onEnded={src2 ? () => onEndedPlayer2() : undefined}
|
||||
onEnded={src2 && !loopPlayer2 ? () => onEndedPlayer2() : undefined}
|
||||
onError={handleOnError(
|
||||
player2Ref,
|
||||
() => onEndedPlayer2(),
|
||||
|
||||
@@ -4,6 +4,7 @@ import type ReactPlayer from 'react-player';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { eventEmitter } from '/@/renderer/events/event-emitter';
|
||||
import {
|
||||
WebPlayerEngine,
|
||||
WebPlayerEngineHandle,
|
||||
@@ -20,12 +21,13 @@ import {
|
||||
usePlayerData,
|
||||
usePlayerMuted,
|
||||
usePlayerProperties,
|
||||
usePlayerRepeat,
|
||||
usePlayerStoreBase,
|
||||
usePlayerVolume,
|
||||
} from '/@/renderer/store';
|
||||
import { toast } from '/@/shared/components/toast/toast';
|
||||
import { QueueSong } from '/@/shared/types/domain-types';
|
||||
import { CrossfadeStyle, PlayerStatus, PlayerStyle } from '/@/shared/types/types';
|
||||
import { CrossfadeStyle, PlayerRepeat, PlayerStatus, PlayerStyle } from '/@/shared/types/types';
|
||||
|
||||
const PLAY_PAUSE_FADE_DURATION = 300;
|
||||
const PLAY_PAUSE_FADE_INTERVAL = 10;
|
||||
@@ -34,6 +36,8 @@ export function WebPlayer() {
|
||||
const playerRef = useRef<null | WebPlayerEngineHandle>(null);
|
||||
const { t } = useTranslation();
|
||||
const { num, player1, player2, status } = usePlayerData();
|
||||
const repeat = usePlayerRepeat();
|
||||
const repeatOneProgressRef = useRef({ player1: 0, player2: 0 });
|
||||
const { mediaAutoNext, mediaPause, setTimestamp } = usePlayerActions();
|
||||
const playback = useMpvSettings();
|
||||
const { webAudio } = useWebAudio();
|
||||
@@ -97,12 +101,37 @@ export function WebPlayer() {
|
||||
[],
|
||||
);
|
||||
|
||||
const handleRepeatOne = useCallback(
|
||||
(playerId: 1 | 2, playedSeconds: number, duration: number) => {
|
||||
if (repeat !== PlayerRepeat.ONE || duration <= 0 || num !== playerId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const key = playerId === 1 ? 'player1' : 'player2';
|
||||
const last = repeatOneProgressRef.current[key];
|
||||
repeatOneProgressRef.current[key] = playedSeconds;
|
||||
|
||||
if (last > duration * 0.85 && playedSeconds < duration * 0.15) {
|
||||
setTimestamp(0);
|
||||
eventEmitter.emit('PLAYER_REPEATED', {
|
||||
index: usePlayerStoreBase.getState().player.index,
|
||||
});
|
||||
}
|
||||
},
|
||||
[num, repeat, setTimestamp],
|
||||
);
|
||||
|
||||
const onProgressPlayer1 = useCallback(
|
||||
(e: PlayerOnProgressProps) => {
|
||||
if (!playerRef.current?.player1()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (repeat === PlayerRepeat.ONE) {
|
||||
handleRepeatOne(1, e.playedSeconds, getDuration(playerRef.current.player1().ref));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (transitionType) {
|
||||
case PlayerStyle.CROSSFADE:
|
||||
crossfadeHandler({
|
||||
@@ -132,7 +161,17 @@ export function WebPlayer() {
|
||||
break;
|
||||
}
|
||||
},
|
||||
[crossfadeDuration, crossfadeStyle, isTransitioning, num, player2, transitionType, volume],
|
||||
[
|
||||
crossfadeDuration,
|
||||
crossfadeStyle,
|
||||
handleRepeatOne,
|
||||
isTransitioning,
|
||||
num,
|
||||
player2,
|
||||
repeat,
|
||||
transitionType,
|
||||
volume,
|
||||
],
|
||||
);
|
||||
|
||||
const onProgressPlayer2 = useCallback(
|
||||
@@ -141,6 +180,11 @@ export function WebPlayer() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (repeat === PlayerRepeat.ONE) {
|
||||
handleRepeatOne(2, e.playedSeconds, getDuration(playerRef.current.player2().ref));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (transitionType) {
|
||||
case PlayerStyle.CROSSFADE:
|
||||
crossfadeHandler({
|
||||
@@ -170,7 +214,17 @@ export function WebPlayer() {
|
||||
break;
|
||||
}
|
||||
},
|
||||
[crossfadeDuration, crossfadeStyle, isTransitioning, num, player1, transitionType, volume],
|
||||
[
|
||||
crossfadeDuration,
|
||||
crossfadeStyle,
|
||||
handleRepeatOne,
|
||||
isTransitioning,
|
||||
num,
|
||||
player1,
|
||||
repeat,
|
||||
transitionType,
|
||||
volume,
|
||||
],
|
||||
);
|
||||
|
||||
const handleOnEndedPlayer1 = useCallback(() => {
|
||||
@@ -474,10 +528,15 @@ export function WebPlayer() {
|
||||
});
|
||||
}, [mediaPause, t]);
|
||||
|
||||
const loopPlayer1 = repeat === PlayerRepeat.ONE && num === 1;
|
||||
const loopPlayer2 = repeat === PlayerRepeat.ONE && num === 2;
|
||||
|
||||
return (
|
||||
<WebPlayerEngine
|
||||
isMuted={isMuted}
|
||||
isTransitioning={Boolean(isTransitioning)}
|
||||
loopPlayer1={loopPlayer1}
|
||||
loopPlayer2={loopPlayer2}
|
||||
onEndedPlayer1={handleOnEndedPlayer1}
|
||||
onEndedPlayer2={handleOnEndedPlayer2}
|
||||
onErrorPause={handleOnErrorPause}
|
||||
|
||||
@@ -136,6 +136,8 @@ export function RadioWebPlayer() {
|
||||
<WebPlayerEngine
|
||||
isMuted={isMuted}
|
||||
isTransitioning={false}
|
||||
loopPlayer1={false}
|
||||
loopPlayer2={false}
|
||||
onEndedPlayer1={onEndedPlayer1}
|
||||
onEndedPlayer2={() => {}}
|
||||
onErrorPause={() => {}}
|
||||
|
||||
Reference in New Issue
Block a user