|
|
@@ -10,6 +10,7 @@ import { getS3SimpleSign } from "@/services/upload";
|
|
|
interface AudioUploadProps {
|
|
|
value?: string | string[];
|
|
|
onChange?: (value: string | string[]) => void;
|
|
|
+ onDurationChange?: (duration: number | undefined) => void;
|
|
|
maxCount?: number;
|
|
|
disabled?: boolean;
|
|
|
dir?: string;
|
|
|
@@ -42,9 +43,23 @@ const getFileNameFromUrl = (url: string): string => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+const getAudioDuration = (url: string): Promise<number> => {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ const audio = new Audio();
|
|
|
+ audio.addEventListener("loadedmetadata", () => {
|
|
|
+ resolve(Math.round(audio.duration));
|
|
|
+ });
|
|
|
+ audio.addEventListener("error", () => {
|
|
|
+ reject(new Error("Failed to load audio metadata"));
|
|
|
+ });
|
|
|
+ audio.src = url;
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
const AudioUpload: React.FC<AudioUploadProps> = ({
|
|
|
value,
|
|
|
onChange,
|
|
|
+ onDurationChange,
|
|
|
maxCount = 1,
|
|
|
disabled = false,
|
|
|
dir,
|
|
|
@@ -234,6 +249,16 @@ const AudioUpload: React.FC<AudioUploadProps> = ({
|
|
|
onChange(successUrls);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ if (onDurationChange && successUrls.length > 0) {
|
|
|
+ const targetUrl =
|
|
|
+ maxCount === 1 ? successUrls[0] : successUrls[successUrls.length - 1];
|
|
|
+ if (targetUrl) {
|
|
|
+ getAudioDuration(targetUrl)
|
|
|
+ .then((duration) => onDurationChange(duration))
|
|
|
+ .catch(() => onDurationChange(undefined));
|
|
|
+ }
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
// Handle file removal
|
|
|
@@ -253,6 +278,17 @@ const AudioUpload: React.FC<AudioUploadProps> = ({
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ if (onDurationChange) {
|
|
|
+ if (urls.length === 0) {
|
|
|
+ onDurationChange(undefined);
|
|
|
+ } else {
|
|
|
+ const targetUrl = urls[urls.length - 1];
|
|
|
+ getAudioDuration(targetUrl)
|
|
|
+ .then((duration) => onDurationChange(duration))
|
|
|
+ .catch(() => onDurationChange(undefined));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
return true;
|
|
|
};
|
|
|
|