mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-07 04:20:12 +02:00
fix preserve pitch on player start, add to player config (#1349)
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import { UseSuspenseQueryOptions } from '@tanstack/react-query';
|
||||
import { ref } from 'process';
|
||||
|
||||
import { api } from '/@/renderer/api';
|
||||
import { useItemListPaginatedLoader } from '/@/renderer/components/item-list/helpers/item-list-paginated-loader';
|
||||
@@ -77,7 +76,6 @@ export const AlbumArtistListPaginatedGrid = ({
|
||||
itemsPerRow={itemsPerRow}
|
||||
itemType={LibraryItem.ALBUM_ARTIST}
|
||||
onScrollEnd={handleOnScrollEnd}
|
||||
ref={ref}
|
||||
rows={rows}
|
||||
/>
|
||||
</ItemListWithPagination>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { RefObject } from 'react';
|
||||
|
||||
import { useEffect, useImperativeHandle, useRef, useState } from 'react';
|
||||
import { useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
|
||||
import ReactPlayer from 'react-player';
|
||||
|
||||
import { AudioPlayer, PlayerOnProgressProps } from '/@/renderer/features/player/audio-player/types';
|
||||
@@ -153,15 +153,37 @@ export const WebPlayerEngine = (props: WebPlayerEngineProps) => {
|
||||
|
||||
useEffect(() => {
|
||||
const player1 = player1Ref.current?.getInternalPlayer();
|
||||
if (player1) {
|
||||
if (player1 && player1 instanceof HTMLAudioElement) {
|
||||
player1.preservesPitch = preservesPitch;
|
||||
}
|
||||
const player2 = player2Ref.current?.getInternalPlayer();
|
||||
if (player2) {
|
||||
if (player2 && player2 instanceof HTMLAudioElement) {
|
||||
player2.preservesPitch = preservesPitch;
|
||||
}
|
||||
}, [preservesPitch]);
|
||||
|
||||
const handleOnReadyPlayer1 = useCallback(
|
||||
(player: ReactPlayer) => {
|
||||
const internal = player.getInternalPlayer();
|
||||
if (internal && internal instanceof HTMLAudioElement) {
|
||||
internal.preservesPitch = preservesPitch;
|
||||
}
|
||||
onStartedPlayer1(player);
|
||||
},
|
||||
[onStartedPlayer1, preservesPitch],
|
||||
);
|
||||
|
||||
const handleOnReadyPlayer2 = useCallback(
|
||||
(player: ReactPlayer) => {
|
||||
const internal = player.getInternalPlayer();
|
||||
if (internal && internal instanceof HTMLAudioElement) {
|
||||
internal.preservesPitch = preservesPitch;
|
||||
}
|
||||
onStartedPlayer2(player);
|
||||
},
|
||||
[onStartedPlayer2, preservesPitch],
|
||||
);
|
||||
|
||||
return (
|
||||
<div id="web-player-engine" style={{ display: 'none' }}>
|
||||
<ReactPlayer
|
||||
@@ -175,7 +197,7 @@ export const WebPlayerEngine = (props: WebPlayerEngineProps) => {
|
||||
onEnded={src1 ? () => onEndedPlayer1() : undefined}
|
||||
onError={handleOnError(player1Ref, () => onEndedPlayer1())}
|
||||
onProgress={onProgressPlayer1}
|
||||
onReady={onStartedPlayer1}
|
||||
onReady={handleOnReadyPlayer1}
|
||||
playbackRate={speed || 1}
|
||||
playing={playerNum === 1 && playerStatus === PlayerStatus.PLAYING}
|
||||
progressInterval={isTransitioning ? 10 : 250}
|
||||
@@ -195,7 +217,7 @@ export const WebPlayerEngine = (props: WebPlayerEngineProps) => {
|
||||
onEnded={src2 ? () => onEndedPlayer2() : undefined}
|
||||
onError={handleOnError(player2Ref, () => onEndedPlayer2())}
|
||||
onProgress={onProgressPlayer2}
|
||||
onReady={onStartedPlayer2}
|
||||
onReady={handleOnReadyPlayer2}
|
||||
playbackRate={speed || 1}
|
||||
playing={playerNum === 2 && playerStatus === PlayerStatus.PLAYING}
|
||||
progressInterval={isTransitioning ? 10 : 250}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import isElectron from 'is-electron';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { ListConfigTable } from '/@/renderer/features/shared/components/list-config-menu';
|
||||
@@ -11,12 +11,17 @@ import {
|
||||
usePlayerSpeed,
|
||||
usePlayerStatus,
|
||||
} from '/@/renderer/store';
|
||||
import { usePlaybackSettings, useSettingsStoreActions } from '/@/renderer/store/settings.store';
|
||||
import {
|
||||
usePlaybackSettings,
|
||||
useSettingsStore,
|
||||
useSettingsStoreActions,
|
||||
} from '/@/renderer/store/settings.store';
|
||||
import { ActionIcon } from '/@/shared/components/action-icon/action-icon';
|
||||
import { Popover } from '/@/shared/components/popover/popover';
|
||||
import { SegmentedControl } from '/@/shared/components/segmented-control/segmented-control';
|
||||
import { Select } from '/@/shared/components/select/select';
|
||||
import { Slider } from '/@/shared/components/slider/slider';
|
||||
import { Switch } from '/@/shared/components/switch/switch';
|
||||
import { toast } from '/@/shared/components/toast/toast';
|
||||
import {
|
||||
CrossfadeStyle,
|
||||
@@ -42,9 +47,20 @@ export const PlayerConfig = () => {
|
||||
const { crossfadeDuration, crossfadeStyle, transitionType } = usePlayerProperties();
|
||||
const { setCrossfadeDuration, setCrossfadeStyle, setQueueType, setSpeed, setTransitionType } =
|
||||
usePlayerActions();
|
||||
const preservePitch = useSettingsStore((state) => state.playback.preservePitch);
|
||||
|
||||
const playbackSettings = usePlaybackSettings();
|
||||
const { setSettings } = useSettingsStoreActions();
|
||||
|
||||
const setPreservePitch = useCallback(
|
||||
(value: boolean) => {
|
||||
setSettings({
|
||||
playback: { ...playbackSettings, preservePitch: value },
|
||||
});
|
||||
},
|
||||
[playbackSettings, setSettings],
|
||||
);
|
||||
|
||||
const [audioDevices, setAudioDevices] = useState<{ label: string; value: string }[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -288,26 +304,38 @@ export const PlayerConfig = () => {
|
||||
id: 'playbackSpeed',
|
||||
label: t('player.playbackSpeed', { postProcess: 'titleCase' }),
|
||||
},
|
||||
{
|
||||
component: (
|
||||
<Switch
|
||||
defaultChecked={preservePitch}
|
||||
onChange={(e) => setPreservePitch(e.currentTarget.checked)}
|
||||
/>
|
||||
),
|
||||
id: 'preservePitch',
|
||||
label: t('setting.preservePitch', { postProcess: 'titleCase' }),
|
||||
},
|
||||
];
|
||||
|
||||
return allOptions;
|
||||
}, [
|
||||
playbackSettings,
|
||||
audioDevices,
|
||||
status,
|
||||
setSettings,
|
||||
currentSong,
|
||||
speed,
|
||||
setSpeed,
|
||||
t,
|
||||
queueType,
|
||||
setQueueType,
|
||||
playbackSettings,
|
||||
status,
|
||||
audioDevices,
|
||||
transitionType,
|
||||
setTransitionType,
|
||||
crossfadeStyle,
|
||||
crossfadeDuration,
|
||||
setCrossfadeDuration,
|
||||
crossfadeStyle,
|
||||
speed,
|
||||
setSpeed,
|
||||
preservePitch,
|
||||
currentSong?.bpm,
|
||||
setQueueType,
|
||||
setSettings,
|
||||
setTransitionType,
|
||||
setCrossfadeStyle,
|
||||
t,
|
||||
setPreservePitch,
|
||||
]);
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user