+
{textInfo.target.ipa || ''}
{
if (textInfo.target.text && textInfo.target.text.length !== 0)
await navigator.clipboard.writeText(textInfo.target.text);
- }} src={'/copy_all_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg'} alt="copy">
-
+ }} src={IMAGES.copy_all} alt="copy">
+
diff --git a/src/components/IconClick.tsx b/src/components/IconClick.tsx
index 1a5b2d1..ebad2b6 100644
--- a/src/components/IconClick.tsx
+++ b/src/components/IconClick.tsx
@@ -2,20 +2,22 @@ import Image from "next/image";
interface IconClickProps {
- src: string;
- alt: string;
- onClick?: () => void;
+ src: string;
+ alt: string;
+ onClick?: () => void;
+ className?: string;
+ size?: number
}
export default function IconClick(
- { src, alt, onClick = () => { } }: IconClickProps) {
- return (<>
-
-
-
- >);
+ { src, alt, onClick = () => { }, className = '', size = 32 }: IconClickProps) {
+ return (<>
+
+
+
+ >);
}
diff --git a/src/config/images.ts b/src/config/images.ts
new file mode 100644
index 0000000..18b7f5c
--- /dev/null
+++ b/src/config/images.ts
@@ -0,0 +1,14 @@
+const IMAGES = {
+ speed_1_5x: '/images/speed_1_5x_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg',
+ speed_1_2_x: '/images/speed_1_2x_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg',
+ speed_0_7x: '/images/speed_0_7x_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg',
+ pause: '/images/pause_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg',
+ speed_0_5x: '/images/speed_0_5x_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg',
+ copy_all: '/images/copy_all_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg',
+ autoplay: '/images/autoplay_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg',
+ autopause: '/images/autopause_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg',
+ speed_1x: '/images/1x_mobiledata_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg',
+ play_arrow: '/images/play_arrow_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg'
+}
+
+export default IMAGES;
\ No newline at end of file
diff --git a/src/hooks/useAudioPlayer.ts b/src/hooks/useAudioPlayer.ts
index 29b0536..0fa89b7 100644
--- a/src/hooks/useAudioPlayer.ts
+++ b/src/hooks/useAudioPlayer.ts
@@ -5,36 +5,30 @@ export function useAudioPlayer() {
const audioRef = useRef
(null);
useEffect(() => {
audioRef.current = new Audio();
-
return () => {
- if (audioRef.current) {
- audioRef.current.pause();
- audioRef.current = null;
- }
+ audioRef.current!.pause();
+ audioRef.current = null;
};
}, []);
- const playAudio = (audioUrl: string) => {
- if (audioRef.current) {
- audioRef.current.src = audioUrl;
- audioRef.current.play().catch(error => {
- console.error('播放失败:', error);
- });
+ const playAudio = async (audioUrl: string) => {
+ audioRef.current!.src = audioUrl;
+ try {
+ await audioRef.current!.play();
+ } catch (e) {
+ return e;
}
};
const pauseAudio = () => {
- if (audioRef.current) {
- audioRef.current.pause();
- }
+ audioRef.current!.pause();
};
const stopAudio = () => {
- if (audioRef.current) {
- audioRef.current.pause();
- audioRef.current.currentTime = 0;
- }
+ audioRef.current!.pause();
+ audioRef.current!.currentTime = 0;
};
return {
playAudio,
pauseAudio,
- stopAudio
+ stopAudio,
+ audioRef
};
}
diff --git a/src/utils.ts b/src/utils.ts
index 4c82ffe..1a068c3 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -1,3 +1,4 @@
+import { EdgeTTS, ProsodyOptions } from "edge-tts-universal/browser";
import { env } from "process";
export function inspect(word: string) {
@@ -40,3 +41,12 @@ export async function callZhipuAPI(messages: { role: string; content: string; }[
return await response.json();
}
+export async function getTTSAudioUrl(text: string, short_name: string, options: ProsodyOptions | undefined = undefined) {
+ const tts = new EdgeTTS(text, short_name, options);
+ try {
+ const result = await tts.synthesize();
+ return URL.createObjectURL(result.audio);
+ } catch (e) {
+ throw e;
+ }
+}
\ No newline at end of file