fix: speech size 0, do not create url

This commit is contained in:
jialin
2024-11-29 21:09:03 +08:00
parent e622636686
commit 1ac3768468
8 changed files with 77 additions and 18 deletions
+20 -9
View File
@@ -13,24 +13,35 @@ interface AudioPlayerProps {
ref?: any; ref?: any;
height?: number; height?: number;
width?: number; width?: number;
onReady?: () => void;
onClick?: (value: number) => void;
} }
const AudioPlayer: React.FC<AudioPlayerProps> = forwardRef((props, ref) => { const AudioPlayer: React.FC<AudioPlayerProps> = forwardRef((props, ref) => {
const { autoplay, audioUrl, speed = 1, ...rest } = props; const { autoplay, audioUrl, speed = 1, ...rest } = props;
const container = useRef<HTMLDivElement>(null); const container = useRef<HTMLDivElement>(null);
const { createWavesurfer, play, pause, destroyWavesurfer, wavesurfer } = const {
useWavesurfer({ createWavesurfer,
container, play,
autoplay: autoplay, pause,
url: audioUrl, duration,
audioRate: speed, destroyWavesurfer,
...rest wavesurfer
}); } = useWavesurfer({
container,
autoplay: autoplay,
url: audioUrl,
audioRate: speed,
onReady: props.onReady,
onClick: props.onClick,
...rest
});
useImperativeHandle(ref, () => { useImperativeHandle(ref, () => {
return { return {
play, play,
pause pause,
duration
}; };
}); });
@@ -11,6 +11,8 @@ interface Options {
barRadius?: number; barRadius?: number;
autoplay?: boolean; autoplay?: boolean;
audioRate?: number; audioRate?: number;
onReady?: () => void;
onClick: (value: any) => void;
} }
const useWavesurfer = (options: Options) => { const useWavesurfer = (options: Options) => {
const wavesurfer = useRef<WaveSurfer | null>(null); const wavesurfer = useRef<WaveSurfer | null>(null);
@@ -37,6 +39,13 @@ const useWavesurfer = (options: Options) => {
cursorWidth: 0, cursorWidth: 0,
...rest ...rest
}); });
wavesurfer.current?.on('ready', () => {
options.onReady?.();
});
wavesurfer.current?.on('click', (value) => {
options.onClick?.(value);
});
}; };
const destroyWavesurfer = () => { const destroyWavesurfer = () => {
@@ -51,6 +60,13 @@ const useWavesurfer = (options: Options) => {
} }
}; };
const duration = () => {
if (wavesurfer.current) {
return wavesurfer.current.getDuration();
}
return 0;
};
const pause = () => { const pause = () => {
if (wavesurfer.current) { if (wavesurfer.current) {
wavesurfer.current.pause(); wavesurfer.current.pause();
@@ -62,6 +78,7 @@ const useWavesurfer = (options: Options) => {
play, play,
pause, pause,
wavesurfer, wavesurfer,
duration,
destroyWavesurfer destroyWavesurfer
}; };
}; };
Binary file not shown.
+18 -3
View File
@@ -1,4 +1,5 @@
import IconFont from '@/components/icon-font'; import IconFont from '@/components/icon-font';
import { formatTime } from '@/utils/index';
import { import {
DownloadOutlined, DownloadOutlined,
PauseCircleOutlined, PauseCircleOutlined,
@@ -37,7 +38,9 @@ const SpeechItem: React.FC<SpeechContentProps> = (props) => {
const intl = useIntl(); const intl = useIntl();
const [collapsed, setCollapsed] = useState(false); const [collapsed, setCollapsed] = useState(false);
const [isPlay, setIsPlay] = useState(false); const [isPlay, setIsPlay] = useState(false);
const ref = useRef<HTMLAudioElement>(null); const [duration, setDuration] = useState(0);
const [currentTime, setCurrentTime] = useState(0);
const ref = useRef<any>(null);
const handlePlay = () => { const handlePlay = () => {
if (isPlay) { if (isPlay) {
@@ -53,6 +56,15 @@ const SpeechItem: React.FC<SpeechContentProps> = (props) => {
setCollapsed(!collapsed); setCollapsed(!collapsed);
}; };
const handleReay = () => {
const duration = ref.current?.duration?.();
setDuration(duration < 1 ? 1 : duration);
};
const handleOnClick = (value: number) => {
console.log('current:', value);
};
const onDownload = () => { const onDownload = () => {
const url = props.audioUrl || ''; const url = props.audioUrl || '';
const filename = `audio-${dayjs().format('YYYYMMDDHHmmss')}.${props.format}`; const filename = `audio-${dayjs().format('YYYYMMDDHHmmss')}.${props.format}`;
@@ -75,6 +87,8 @@ const SpeechItem: React.FC<SpeechContentProps> = (props) => {
<AudioPlayer <AudioPlayer
{...props} {...props}
audioUrl={props.audioUrl} audioUrl={props.audioUrl}
onReady={handleReay}
onClick={handleOnClick}
ref={ref} ref={ref}
></AudioPlayer> ></AudioPlayer>
</div> </div>
@@ -82,9 +96,8 @@ const SpeechItem: React.FC<SpeechContentProps> = (props) => {
<div className="speech-actions"> <div className="speech-actions">
<span className="tags"> <span className="tags">
<span className="item">{props.format}</span> <span className="item">{props.format}</span>
{/* <span className="item splitor"></span>
<span className="item">{props.speed}x</span> */}
</span> </span>
<span className="duration">{formatTime(duration)}</span>
<div className="actions"> <div className="actions">
<Tooltip <Tooltip
title={ title={
@@ -94,6 +107,7 @@ const SpeechItem: React.FC<SpeechContentProps> = (props) => {
} }
> >
<Button <Button
disabled={!props.audioUrl || duration === 0}
onClick={handlePlay} onClick={handlePlay}
icon={isPlay ? <PauseCircleOutlined /> : <PlayCircleOutlined />} icon={isPlay ? <PauseCircleOutlined /> : <PlayCircleOutlined />}
type="text" type="text"
@@ -106,6 +120,7 @@ const SpeechItem: React.FC<SpeechContentProps> = (props) => {
})} })}
> >
<Button <Button
disabled={!props.audioUrl || duration === 0}
onClick={onDownload} onClick={onDownload}
icon={<DownloadOutlined />} icon={<DownloadOutlined />}
type="text" type="text"
@@ -53,6 +53,7 @@
.speech-actions { .speech-actions {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center;
margin-top: 10px; margin-top: 10px;
padding-left: 80px; padding-left: 80px;
+1 -1
View File
@@ -98,7 +98,7 @@ export const textToSpeech = async (params: any, options?: any) => {
} }
const audioBlob = await res.blob(); const audioBlob = await res.blob();
const audioUrl = URL.createObjectURL(audioBlob); const audioUrl = audioBlob.size > 0 ? URL.createObjectURL(audioBlob) : '';
return { return {
url: audioUrl, url: audioUrl,
type: audioBlob.type type: audioBlob.type
+10 -2
View File
@@ -119,7 +119,7 @@ const GroundLeft: React.FC<MessageProps> = forwardRef((props, ref) => {
errorMessage: errorMessage:
result?.data?.error?.message || result?.data?.error?.message ||
result?.data?.message || result?.data?.message ||
result.error.detail || result?.detail ||
'' ''
}); });
return; return;
@@ -130,8 +130,16 @@ const GroundLeft: React.FC<MessageProps> = forwardRef((props, ref) => {
uid: messageId.current uid: messageId.current
} }
]); ]);
} catch (error) { } catch (error: any) {
console.log('error:', error); console.log('error:', error);
const res = error?.response?.data;
if (res.error) {
setTokenResult({
error: true,
errorMessage:
res?.error?.message || res?.data?.error || res?.error?.detail || ''
});
}
} finally { } finally {
setLoading(false); setLoading(false);
setIsRecording(false); setIsRecording(false);
+10 -3
View File
@@ -130,7 +130,7 @@ const GroundLeft: React.FC<MessageProps> = forwardRef((props, ref) => {
errorMessage: errorMessage:
res?.data?.error?.message || res?.data?.error?.message ||
res?.data?.error || res?.data?.error ||
res.error?.detail || res?.error?.detail ||
'' ''
}); });
setMessageList([]); setMessageList([]);
@@ -148,8 +148,15 @@ const GroundLeft: React.FC<MessageProps> = forwardRef((props, ref) => {
audioUrl: res.url audioUrl: res.url
} }
]); ]);
} catch (error) { } catch (error: any) {
console.log('error:', error); const res = error?.response?.data;
if (res.error) {
setTokenResult({
error: true,
errorMessage:
res?.error?.message || res?.data?.error || res?.error?.detail || ''
});
}
} finally { } finally {
setLoading(false); setLoading(false);
} }