refactor: upgrade wavesurfer.js
This commit is contained in:
@@ -17,62 +17,47 @@ export type VoiceMessageProps = {
|
||||
// 全局存储Voice信息
|
||||
const VoiceMap: { [key: string]: WaveSurfer | null } = {};
|
||||
const VoiceMessage = ({ file_path }: { file_path: string }) => {
|
||||
// const waveRef = useRef<WaveSurfer | null>(null);
|
||||
const containerRef = useRef(null);
|
||||
const [status, setStatus] = useState<"loading" | "error" | "ready">("loading");
|
||||
const [playing, setPlaying] = useState(false);
|
||||
const [duration, setDuration] = useState("");
|
||||
// const [audio, setAudio] = useState<HTMLAudioElement>(new Audio(`${BASE_URL}/resource/file?file_path=${encodeURIComponent(
|
||||
// file_path
|
||||
// )}`));
|
||||
const initWave = (file_path: string) => {
|
||||
const initWave = async (file_path: string) => {
|
||||
let wave: WaveSurfer | null = null;
|
||||
const audioSrc = `${BASE_URL}/resource/file?file_path=${encodeURIComponent(file_path)}`;
|
||||
wave = WaveSurfer.create({
|
||||
container: containerRef.current ?? "",
|
||||
// maxCanvasWidth: 200,
|
||||
height: 32,
|
||||
waveColor: "#0BA5EC",
|
||||
cursorColor: "#0BA5AA",
|
||||
progressColor: "#0BA5AA",
|
||||
hideScrollbar: true,
|
||||
// mediaControls: true,
|
||||
normalize: true,
|
||||
responsive: true
|
||||
});
|
||||
wave.load(audioSrc);
|
||||
|
||||
wave.on("error", function (err) {
|
||||
console.log("voice message error", err);
|
||||
console.log("audioSrc", audioSrc);
|
||||
try {
|
||||
// 先检测资源是否存在
|
||||
await fetch(audioSrc);
|
||||
wave = WaveSurfer.create({
|
||||
container: containerRef.current ?? "",
|
||||
height: 32,
|
||||
waveColor: "#0BA5EC",
|
||||
cursorColor: "#0BA5AA",
|
||||
progressColor: "#0BA5AA",
|
||||
hideScrollbar: true,
|
||||
normalize: true
|
||||
});
|
||||
wave.load(audioSrc);
|
||||
wave.on("play", function () {
|
||||
setPlaying(true);
|
||||
});
|
||||
wave.on("pause", function () {
|
||||
setPlaying(false);
|
||||
});
|
||||
wave.on("ready", function () {
|
||||
setStatus("ready");
|
||||
const current = VoiceMap[file_path];
|
||||
if (current) {
|
||||
const dur = current.getDuration();
|
||||
const num = Math.ceil(dur);
|
||||
const durDisplay = dayjs.duration(num, "seconds").format("mm:ss");
|
||||
setDuration(durDisplay);
|
||||
}
|
||||
});
|
||||
VoiceMap[file_path] = wave;
|
||||
} catch (error) {
|
||||
setStatus("error");
|
||||
const current = VoiceMap[file_path];
|
||||
if (current) {
|
||||
current.destroy();
|
||||
}
|
||||
});
|
||||
wave.on("play", function () {
|
||||
setPlaying(true);
|
||||
});
|
||||
wave.on("pause", function () {
|
||||
setPlaying(false);
|
||||
});
|
||||
wave.on("ready", function () {
|
||||
setStatus("ready");
|
||||
const current = VoiceMap[file_path];
|
||||
if (current) {
|
||||
const dur = current.getDuration();
|
||||
const num = Math.ceil(dur);
|
||||
const durDisplay = dayjs.duration(num, "seconds").format("mm:ss");
|
||||
setDuration(durDisplay);
|
||||
}
|
||||
// tricky
|
||||
if (containerRef.current) {
|
||||
const container = containerRef.current as HTMLDivElement;
|
||||
const w = (container.querySelector("wave>canvas") as HTMLCanvasElement)?.width;
|
||||
container.style.width = `${w}px`;
|
||||
}
|
||||
});
|
||||
VoiceMap[file_path] = wave;
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
if (containerRef.current && file_path) {
|
||||
@@ -93,7 +78,7 @@ const VoiceMessage = ({ file_path }: { file_path: string }) => {
|
||||
Object.keys(VoiceMap).forEach((key) => {
|
||||
try {
|
||||
const item = VoiceMap[key];
|
||||
if (item && item.backend && item.isPlaying()) {
|
||||
if (item && item.isPlaying()) {
|
||||
item.stop();
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -104,9 +89,7 @@ const VoiceMessage = ({ file_path }: { file_path: string }) => {
|
||||
current.playPause();
|
||||
}
|
||||
};
|
||||
// const handleReload = () => {
|
||||
// initWave(file_path);
|
||||
// };
|
||||
|
||||
const notReady = status !== "ready";
|
||||
if (status == "error") return <ExpiredMessage type="audio" />;
|
||||
return (
|
||||
@@ -123,17 +106,10 @@ const VoiceMessage = ({ file_path }: { file_path: string }) => {
|
||||
<IconPlay className="stroke-primary-500" />
|
||||
)}
|
||||
</button>
|
||||
<div ref={containerRef} className={clsx("flex-1 h-8 min-w-[100px]")}>
|
||||
{status == "loading" && <span className="text-xs">Loading voice message...</span>}
|
||||
<div ref={containerRef} className={clsx("flex-1 h-8 min-w-[150px]")}>
|
||||
{status == "loading" && <span className="text-xs leading-8">Loading voice message...</span>}
|
||||
</div>
|
||||
<time className="text-primary-500 text-xs whitespace-nowrap text-left">{duration}</time>
|
||||
{/* {status === "error" && (
|
||||
<IconRefresh
|
||||
role="button"
|
||||
className="absolute -right-6 top-1/2 -translate-y-1/2 w-4 h-4 stroke-primary-600"
|
||||
onClick={handleReload}
|
||||
/>
|
||||
)} */}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user