fix: audio player pause
This commit is contained in:
@@ -8,6 +8,7 @@ interface AudioAnimationProps {
|
||||
maxWidth?: number;
|
||||
scaleFactor?: number;
|
||||
maxBarCount?: number;
|
||||
amplitude?: number;
|
||||
fixedHeight?: boolean;
|
||||
analyserData: {
|
||||
data: Uint8Array;
|
||||
@@ -19,6 +20,7 @@ const AudioAnimation: React.FC<AudioAnimationProps> = (props) => {
|
||||
const {
|
||||
scaleFactor = 1.2,
|
||||
maxBarCount = 128,
|
||||
amplitude = 40,
|
||||
maxWidth,
|
||||
fixedHeight = true,
|
||||
analyserData,
|
||||
@@ -71,7 +73,7 @@ const AudioAnimation: React.FC<AudioAnimationProps> = (props) => {
|
||||
const barSpacing = 6;
|
||||
const centerLine = Math.floor(HEIGHT / 2);
|
||||
|
||||
const jitterAmplitude = 40;
|
||||
const jitterAmplitude = amplitude;
|
||||
const minJitter = 10;
|
||||
|
||||
let lastFrameTime = 0;
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
export type AudioEvent =
|
||||
| 'play'
|
||||
| 'playing'
|
||||
| 'pause'
|
||||
| 'timeupdate'
|
||||
| 'ended'
|
||||
| 'loadedmetadata'
|
||||
| 'audioprocess'
|
||||
| 'canplay'
|
||||
| 'ended'
|
||||
| 'loadeddata'
|
||||
| 'seeked'
|
||||
| 'seeking'
|
||||
| 'volumechange';
|
||||
|
||||
export interface AudioPlayerProps {
|
||||
controls?: boolean;
|
||||
autoplay?: boolean;
|
||||
url: string;
|
||||
speed?: number;
|
||||
ref?: any;
|
||||
height?: number;
|
||||
width?: number;
|
||||
duration?: number;
|
||||
onPlay?: () => void;
|
||||
onPlaying?: () => void;
|
||||
onPause?: () => void;
|
||||
onTimeUpdate?: () => void;
|
||||
onEnded?: () => void;
|
||||
onLoadedMetadata?: (duration: number) => void;
|
||||
onAudioProcess?: (current: number) => void;
|
||||
onCanPlay?: () => void;
|
||||
onLoadedData?: () => void;
|
||||
onSeeked?: () => void;
|
||||
onSeeking?: () => void;
|
||||
onVolumeChange?: () => void;
|
||||
onReady?: (duration: number) => void;
|
||||
onAnalyse?: (analyseData: any, frequencyBinCount: any) => void;
|
||||
}
|
||||
@@ -75,6 +75,7 @@ const AudioPlayer: React.FC<AudioPlayerProps> = forwardRef((props, ref) => {
|
||||
}, []);
|
||||
|
||||
const handleAudioOnPlay = useCallback(() => {
|
||||
console.log('audio play');
|
||||
timer.current = setInterval(() => {
|
||||
setAudioState((prestate) => {
|
||||
return {
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
import React, {
|
||||
forwardRef,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useImperativeHandle,
|
||||
useRef
|
||||
} from 'react';
|
||||
import { AudioPlayerProps } from './config/type';
|
||||
|
||||
const RawAudioPlayer: React.FC<AudioPlayerProps> = forwardRef((props, ref) => {
|
||||
const { autoplay = false } = props;
|
||||
const audioRef = React.useRef<HTMLAudioElement>(null);
|
||||
|
||||
// =================== audio context ======================
|
||||
const audioContext = useRef<any>(null);
|
||||
const analyser = useRef<any>(null);
|
||||
const dataArray = useRef<any>(null);
|
||||
// ========================================================
|
||||
|
||||
const initAudioContext = useCallback(() => {
|
||||
audioContext.current = new (window.AudioContext ||
|
||||
window.webkitAudioContext)();
|
||||
|
||||
analyser.current = audioContext.current.createAnalyser();
|
||||
analyser.current.fftSize = 512;
|
||||
dataArray.current = new Uint8Array(analyser.current.frequencyBinCount);
|
||||
}, []);
|
||||
|
||||
const generateVisualData = useCallback(() => {
|
||||
const source = audioContext.current.createMediaElementSource(
|
||||
audioRef.current
|
||||
);
|
||||
source.connect(analyser.current);
|
||||
analyser.current.connect(audioContext.current.destination);
|
||||
}, []);
|
||||
|
||||
const initEnvents = () => {
|
||||
if (!audioRef.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
audioRef.current.addEventListener('complete', () => {});
|
||||
|
||||
audioRef.current.addEventListener('play', () => {
|
||||
props.onAnalyse?.(dataArray.current, analyser);
|
||||
props.onPlay?.();
|
||||
});
|
||||
|
||||
audioRef.current.addEventListener('pause', () => {
|
||||
props.onAnalyse?.(dataArray.current, analyser);
|
||||
props.onPause?.();
|
||||
});
|
||||
|
||||
audioRef.current.addEventListener('timeupdate', () => {
|
||||
props.onTimeUpdate?.();
|
||||
});
|
||||
|
||||
audioRef.current.addEventListener('ended', () => {
|
||||
props.onEnded?.();
|
||||
});
|
||||
// add all other events
|
||||
|
||||
audioRef.current.addEventListener('canplay', () => {
|
||||
props.onCanPlay?.();
|
||||
});
|
||||
|
||||
audioRef.current.addEventListener('loadeddata', () => {
|
||||
initEnvents();
|
||||
initAudioContext();
|
||||
generateVisualData();
|
||||
props.onLoadedData?.();
|
||||
});
|
||||
|
||||
audioRef.current.addEventListener('seeked', () => {
|
||||
props.onSeeked?.();
|
||||
});
|
||||
|
||||
audioRef.current.addEventListener('seeking', () => {
|
||||
props.onSeeking?.();
|
||||
});
|
||||
|
||||
audioRef.current.addEventListener('volumechange', () => {
|
||||
props.onVolumeChange?.();
|
||||
});
|
||||
|
||||
audioRef.current.addEventListener('audioprocess', () => {
|
||||
const current = audioRef.current?.currentTime || 0;
|
||||
props.onAudioProcess?.(current);
|
||||
});
|
||||
|
||||
audioRef.current.addEventListener('playing', () => {
|
||||
props.onPlaying?.();
|
||||
});
|
||||
|
||||
audioRef.current.addEventListener('loadedmetadata', () => {
|
||||
const duration = audioRef.current?.duration || 0;
|
||||
props.onLoadedMetadata?.(duration);
|
||||
props.onReady?.(duration);
|
||||
});
|
||||
|
||||
audioRef.current.addEventListener('ended', () => {
|
||||
props.onEnded?.();
|
||||
});
|
||||
|
||||
audioRef.current.addEventListener('loadeddata', () => {
|
||||
props.onLoadedData?.();
|
||||
});
|
||||
};
|
||||
|
||||
const handleAudioOnPlay = () => {
|
||||
audioRef.current?.play();
|
||||
};
|
||||
|
||||
const handleLoadedMetadata = () => {};
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
play: () => {
|
||||
audioRef.current?.play();
|
||||
},
|
||||
pause: () => {
|
||||
audioRef.current?.pause();
|
||||
}
|
||||
}));
|
||||
|
||||
useEffect(() => {
|
||||
if (audioRef.current) {
|
||||
}
|
||||
return () => {
|
||||
if (audioContext.current) {
|
||||
audioContext.current.close();
|
||||
}
|
||||
// remove all events
|
||||
|
||||
audioRef.current?.removeEventListener('play', () => {});
|
||||
audioRef.current?.removeEventListener('pause', () => {});
|
||||
audioRef.current?.removeEventListener('timeupdate', () => {});
|
||||
audioRef.current?.removeEventListener('ended', () => {});
|
||||
audioRef.current?.removeEventListener('canplay', () => {});
|
||||
audioRef.current?.removeEventListener('loadeddata', () => {});
|
||||
audioRef.current?.removeEventListener('seeked', () => {});
|
||||
audioRef.current?.removeEventListener('seeking', () => {});
|
||||
audioRef.current?.removeEventListener('volumechange', () => {});
|
||||
audioRef.current?.removeEventListener('audioprocess', () => {});
|
||||
audioRef.current?.removeEventListener('playing', () => {});
|
||||
audioRef.current?.removeEventListener('loadedmetadata', () => {});
|
||||
audioRef.current?.removeEventListener('ended', () => {});
|
||||
audioRef.current?.removeEventListener('loadeddata', () => {});
|
||||
};
|
||||
}, [audioRef.current]);
|
||||
|
||||
return (
|
||||
<audio
|
||||
width={props.width || 300}
|
||||
height={props.height || 40}
|
||||
controls
|
||||
autoPlay={autoplay}
|
||||
src={props.url}
|
||||
ref={audioRef}
|
||||
preload="metadata"
|
||||
></audio>
|
||||
);
|
||||
});
|
||||
|
||||
export default RawAudioPlayer;
|
||||
@@ -50,12 +50,6 @@ const SpeechItem: React.FC<SpeechContentProps> = (props) => {
|
||||
|
||||
const handlePlay = useCallback(async () => {
|
||||
try {
|
||||
console.log(
|
||||
'isPlay:',
|
||||
isPlay,
|
||||
ref.current?.wavesurfer.current?.isPlaying()
|
||||
);
|
||||
ref.current?.pause();
|
||||
if (ref.current?.wavesurfer.current?.isPlaying()) {
|
||||
ref.current?.pause();
|
||||
setIsPlay(false);
|
||||
@@ -124,6 +118,11 @@ const SpeechItem: React.FC<SpeechContentProps> = (props) => {
|
||||
debounceSeek(value);
|
||||
};
|
||||
|
||||
const handleReady = useCallback((duration: number) => {
|
||||
console.log('duration:', duration);
|
||||
setDuration(duration);
|
||||
}, []);
|
||||
|
||||
const handlOnChangeComplete = useCallback((value: number) => {
|
||||
ref.current?.seekTo(value / duration);
|
||||
setCurrentTime(value);
|
||||
@@ -152,8 +151,7 @@ const SpeechItem: React.FC<SpeechContentProps> = (props) => {
|
||||
<AudioPlayer
|
||||
{...props}
|
||||
audioUrl={props.audioUrl}
|
||||
onReady={handleReay}
|
||||
onClick={handleOnClick}
|
||||
onReady={handleReady}
|
||||
onFinish={handleOnFinish}
|
||||
onPlay={handleOnPlay}
|
||||
onPause={handleOnPause}
|
||||
@@ -163,7 +161,8 @@ const SpeechItem: React.FC<SpeechContentProps> = (props) => {
|
||||
></AudioPlayer>
|
||||
{isPlay && (
|
||||
<AudioAnimation
|
||||
maxBarCount={180}
|
||||
maxBarCount={100}
|
||||
amplitude={60}
|
||||
fixedHeight={true}
|
||||
height={82}
|
||||
width={800}
|
||||
|
||||
@@ -29,7 +29,7 @@ const useSetChunkFetch = () => {
|
||||
}
|
||||
|
||||
const chunk = decoder.decode(value, { stream: true });
|
||||
|
||||
console.log('chunk===', chunk);
|
||||
callback(chunk);
|
||||
// console.log('chunkDataRef.current===2', chunkDataRef.current);
|
||||
|
||||
|
||||
@@ -419,14 +419,14 @@ const GroundImages: React.FC<MessageProps> = forwardRef((props, ref) => {
|
||||
useEffect(() => {
|
||||
if (size === 'custom') {
|
||||
form.current?.form?.setFieldsValue({
|
||||
width: 256,
|
||||
height: 256
|
||||
width: 512,
|
||||
height: 512
|
||||
});
|
||||
setParams((pre: object) => {
|
||||
return {
|
||||
...pre,
|
||||
width: 256,
|
||||
height: 256
|
||||
width: 512,
|
||||
height: 512
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@@ -115,9 +115,7 @@ export const ImageParamsConfig: ParamsSchema[] = [
|
||||
{ label: 'playground.params.custom', value: 'custom', locale: true },
|
||||
{ label: '256x256', value: '256x256' },
|
||||
{ label: '512x512', value: '512x512' },
|
||||
{ label: '1024x1024', value: '1024x1024' },
|
||||
{ label: '1792x1024', value: '1792x1024' },
|
||||
{ label: '1024x1792', value: '1024x1792' }
|
||||
{ label: '1024x1024', value: '1024x1024' }
|
||||
],
|
||||
label: {
|
||||
text: 'playground.params.size',
|
||||
@@ -367,7 +365,7 @@ export const ImageCustomSizeConfig: ParamsSchema[] = [
|
||||
},
|
||||
attrs: {
|
||||
min: 256,
|
||||
max: 1792,
|
||||
max: 1024,
|
||||
step: 64,
|
||||
inputnumber: false
|
||||
},
|
||||
@@ -387,7 +385,7 @@ export const ImageCustomSizeConfig: ParamsSchema[] = [
|
||||
},
|
||||
attrs: {
|
||||
min: 256,
|
||||
max: 1792,
|
||||
max: 1024,
|
||||
step: 64,
|
||||
inputnumber: false
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user