Skip to content

Commit

Permalink
✨ feat: audio 统一使用 blob url
Browse files Browse the repository at this point in the history
  • Loading branch information
rdmclin2 committed Aug 4, 2024
1 parent 0b1d0a5 commit 7ecc313
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 33 deletions.
8 changes: 4 additions & 4 deletions src/features/DanceList/Item/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const DanceItem = (props: DanceItemProps) => {
const isHovered = useHover(hoverRef);
const { t } = useTranslation('common');

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

Expand All @@ -52,12 +52,12 @@ const DanceItem = (props: DanceItemProps) => {
} else {
setCurrentPlayId(danceItem.danceId);
setIsPlaying(true);
const audioPromise = fetchAudioBuffer(danceItem.danceId, danceItem.audio);
const audioPromise = fetchAudioUrl(danceItem.danceId, danceItem.audio);
const dancePromise = fetchDanceBuffer(danceItem.danceId, danceItem.src);
Promise.all([dancePromise, audioPromise]).then((res) => {
if (!res) return;
const [danceBuffer, audioBuffer] = res;
viewer.model?.dance(danceBuffer, { data: audioBuffer });
const [danceBuffer, audioUrl] = res;
viewer.model?.dance(danceBuffer, audioUrl);
});
}
};
Expand Down
10 changes: 5 additions & 5 deletions src/hooks/useDownloadDance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,25 @@ export const useDownloadDance = () => {
onProgress: (loaded, total) => {
setAudioProgress((loaded / total) * 100);
},
}).then((res) => res.arrayBuffer());
});

const dancePromise = fetchWithProgress(dance.src, {
onProgress: (loaded, total) => {
setDanceProgress(Math.ceil((loaded / total) * 100));
},
}).then((res) => res.arrayBuffer());
});

try {
const [audioArrayBuffer, coverBase64, danceArrayBuffer] = await Promise.all([
const [audioBlob, coverBase64, danceBlob] = await Promise.all([
audioPromise,
coverPromise,
dancePromise,
]);
const danceKey = getDancePathByDanceId(dance.danceId);
await setItem(danceKey, danceArrayBuffer);
await setItem(danceKey, danceBlob);

const audioKey = getAudioPathByDanceId(dance.danceId);
await setItem(audioKey, audioArrayBuffer);
await setItem(audioKey, audioBlob);

addDanceItem({ ...dance, cover: coverBase64 });
message.success(dance.name + t('actions.downloadSuccess'));
Expand Down
22 changes: 12 additions & 10 deletions src/hooks/useLoadAudio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,36 @@ export const useLoadAudio = () => {
const [downloading, setDownloading] = useState(false);
const [percent, setPercent] = useState(0);

const fetchAudioBuffer = async (danceId: string, audioUrl: string) => {
const fetchAudioUrl = async (danceId: string, audioUrl: string) => {
const localAudioPath = getAudioPathByDanceId(danceId);
let audioBuffer = (await storage.getItem(localAudioPath)) as ArrayBuffer;
let audioBlob = await storage.getItem(localAudioPath);
// 存量转换
if (audioBuffer && !isArrayBuffer(audioBuffer)) {
audioBuffer = await (audioBuffer as Blob).arrayBuffer();
if (audioBlob && isArrayBuffer(audioBlob)) {
// 如果存的是 ArrayBuffer,设置为空重新下载;
audioBlob = null;
}

try {
if (!audioBuffer) {
if (!audioBlob) {
setDownloading(true);
setPercent(0);

audioBuffer = await fetchWithProgress(audioUrl, {
audioBlob = await fetchWithProgress(audioUrl, {
onProgress: (loaded, total) => {
setPercent((loaded / total) * 100);
},
}).then((res) => res.arrayBuffer());
await storage.setItem(localAudioPath, audioBuffer);
});
await storage.setItem(localAudioPath, audioBlob);
}
} finally {
setDownloading(false);
}
return audioBuffer;
return URL.createObjectURL(audioBlob);
};

return {
downloading,
percent,
fetchAudioBuffer,
fetchAudioUrl,
};
};
20 changes: 6 additions & 14 deletions src/libs/vrmViewer/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export class Model {
private _audioPlayer?: AudioPlayer;
private _action: AnimationAction | undefined;
private _clip: AnimationClip | undefined;
private _audio: ArrayBuffer | undefined;
private _audio: string | undefined;

constructor(lookAtTargetParent: THREE.Object3D) {
this._lookAtTargetParent = lookAtTargetParent;
Expand Down Expand Up @@ -155,29 +155,21 @@ export class Model {

/**
* 播放舞蹈,以音乐文件的播放作为结束标志。
* @param audio
* @param dance
*/
public async dance(
dance: ArrayBuffer,
audio?: {
data: ArrayBuffer;
onEnd?: () => void;
},
) {
public async dance(dance: ArrayBuffer, audioUrl: string, onEnd?: () => void) {
const { vrm, mixer } = this;
if (vrm && mixer) {
this.disposeAll();
const animation = convert(dance, toOffset(vrm));
const clip = bindToVRM(animation, vrm);
const action = mixer.clipAction(clip);
action.setLoop(LoopOnce, 1).play(); // play animation
if (audio) {
this._audioPlayer?.playFromArrayBuffer(audio.data, () => {
if (audioUrl) {
this._audioPlayer?.playFromURL(audioUrl, () => {
this.resetToIdle();
audio.onEnd?.();
onEnd?.();
});
this._audio = audio.data;
this._audio = audioUrl;
}

this._action = action;
Expand Down

0 comments on commit 7ecc313

Please sign in to comment.