Skip to content

Commit 7ecc313

Browse files
committed
✨ feat: audio 统一使用 blob url
1 parent 0b1d0a5 commit 7ecc313

File tree

4 files changed

+27
-33
lines changed

4 files changed

+27
-33
lines changed

src/features/DanceList/Item/index.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ const DanceItem = (props: DanceItemProps) => {
4141
const isHovered = useHover(hoverRef);
4242
const { t } = useTranslation('common');
4343

44-
const { downloading: audioDownloading, percent: audioPercent, fetchAudioBuffer } = useLoadAudio();
44+
const { downloading: audioDownloading, percent: audioPercent, fetchAudioUrl } = useLoadAudio();
4545
const { downloading: danceDownloading, percent: dancePercent, fetchDanceBuffer } = useLoadDance();
4646
const viewer = useGlobalStore((s) => s.viewer);
4747

@@ -52,12 +52,12 @@ const DanceItem = (props: DanceItemProps) => {
5252
} else {
5353
setCurrentPlayId(danceItem.danceId);
5454
setIsPlaying(true);
55-
const audioPromise = fetchAudioBuffer(danceItem.danceId, danceItem.audio);
55+
const audioPromise = fetchAudioUrl(danceItem.danceId, danceItem.audio);
5656
const dancePromise = fetchDanceBuffer(danceItem.danceId, danceItem.src);
5757
Promise.all([dancePromise, audioPromise]).then((res) => {
5858
if (!res) return;
59-
const [danceBuffer, audioBuffer] = res;
60-
viewer.model?.dance(danceBuffer, { data: audioBuffer });
59+
const [danceBuffer, audioUrl] = res;
60+
viewer.model?.dance(danceBuffer, audioUrl);
6161
});
6262
}
6363
};

src/hooks/useDownloadDance.tsx

+5-5
Original file line numberDiff line numberDiff line change
@@ -33,25 +33,25 @@ export const useDownloadDance = () => {
3333
onProgress: (loaded, total) => {
3434
setAudioProgress((loaded / total) * 100);
3535
},
36-
}).then((res) => res.arrayBuffer());
36+
});
3737

3838
const dancePromise = fetchWithProgress(dance.src, {
3939
onProgress: (loaded, total) => {
4040
setDanceProgress(Math.ceil((loaded / total) * 100));
4141
},
42-
}).then((res) => res.arrayBuffer());
42+
});
4343

4444
try {
45-
const [audioArrayBuffer, coverBase64, danceArrayBuffer] = await Promise.all([
45+
const [audioBlob, coverBase64, danceBlob] = await Promise.all([
4646
audioPromise,
4747
coverPromise,
4848
dancePromise,
4949
]);
5050
const danceKey = getDancePathByDanceId(dance.danceId);
51-
await setItem(danceKey, danceArrayBuffer);
51+
await setItem(danceKey, danceBlob);
5252

5353
const audioKey = getAudioPathByDanceId(dance.danceId);
54-
await setItem(audioKey, audioArrayBuffer);
54+
await setItem(audioKey, audioBlob);
5555

5656
addDanceItem({ ...dance, cover: coverBase64 });
5757
message.success(dance.name + t('actions.downloadSuccess'));

src/hooks/useLoadAudio.tsx

+12-10
Original file line numberDiff line numberDiff line change
@@ -9,34 +9,36 @@ export const useLoadAudio = () => {
99
const [downloading, setDownloading] = useState(false);
1010
const [percent, setPercent] = useState(0);
1111

12-
const fetchAudioBuffer = async (danceId: string, audioUrl: string) => {
12+
const fetchAudioUrl = async (danceId: string, audioUrl: string) => {
1313
const localAudioPath = getAudioPathByDanceId(danceId);
14-
let audioBuffer = (await storage.getItem(localAudioPath)) as ArrayBuffer;
14+
let audioBlob = await storage.getItem(localAudioPath);
1515
// 存量转换
16-
if (audioBuffer && !isArrayBuffer(audioBuffer)) {
17-
audioBuffer = await (audioBuffer as Blob).arrayBuffer();
16+
if (audioBlob && isArrayBuffer(audioBlob)) {
17+
// 如果存的是 ArrayBuffer,设置为空重新下载;
18+
audioBlob = null;
1819
}
20+
1921
try {
20-
if (!audioBuffer) {
22+
if (!audioBlob) {
2123
setDownloading(true);
2224
setPercent(0);
2325

24-
audioBuffer = await fetchWithProgress(audioUrl, {
26+
audioBlob = await fetchWithProgress(audioUrl, {
2527
onProgress: (loaded, total) => {
2628
setPercent((loaded / total) * 100);
2729
},
28-
}).then((res) => res.arrayBuffer());
29-
await storage.setItem(localAudioPath, audioBuffer);
30+
});
31+
await storage.setItem(localAudioPath, audioBlob);
3032
}
3133
} finally {
3234
setDownloading(false);
3335
}
34-
return audioBuffer;
36+
return URL.createObjectURL(audioBlob);
3537
};
3638

3739
return {
3840
downloading,
3941
percent,
40-
fetchAudioBuffer,
42+
fetchAudioUrl,
4143
};
4244
};

src/libs/vrmViewer/model.ts

+6-14
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export class Model {
3131
private _audioPlayer?: AudioPlayer;
3232
private _action: AnimationAction | undefined;
3333
private _clip: AnimationClip | undefined;
34-
private _audio: ArrayBuffer | undefined;
34+
private _audio: string | undefined;
3535

3636
constructor(lookAtTargetParent: THREE.Object3D) {
3737
this._lookAtTargetParent = lookAtTargetParent;
@@ -155,29 +155,21 @@ export class Model {
155155

156156
/**
157157
* 播放舞蹈,以音乐文件的播放作为结束标志。
158-
* @param audio
159-
* @param dance
160158
*/
161-
public async dance(
162-
dance: ArrayBuffer,
163-
audio?: {
164-
data: ArrayBuffer;
165-
onEnd?: () => void;
166-
},
167-
) {
159+
public async dance(dance: ArrayBuffer, audioUrl: string, onEnd?: () => void) {
168160
const { vrm, mixer } = this;
169161
if (vrm && mixer) {
170162
this.disposeAll();
171163
const animation = convert(dance, toOffset(vrm));
172164
const clip = bindToVRM(animation, vrm);
173165
const action = mixer.clipAction(clip);
174166
action.setLoop(LoopOnce, 1).play(); // play animation
175-
if (audio) {
176-
this._audioPlayer?.playFromArrayBuffer(audio.data, () => {
167+
if (audioUrl) {
168+
this._audioPlayer?.playFromURL(audioUrl, () => {
177169
this.resetToIdle();
178-
audio.onEnd?.();
170+
onEnd?.();
179171
});
180-
this._audio = audio.data;
172+
this._audio = audioUrl;
181173
}
182174

183175
this._action = action;

0 commit comments

Comments
 (0)