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