Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor: audioElementsをRecordから単体にする #1525

Merged
merged 9 commits into from
Aug 28, 2023
2 changes: 1 addition & 1 deletion src/components/AudioDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ const play = async () => {
};

const stop = () => {
store.dispatch("STOP_AUDIO", { audioKey: props.activeAudioKey });
store.dispatch("STOP_AUDIO");
};

const nowPlaying = computed(
Expand Down
7 changes: 2 additions & 5 deletions src/components/DictionaryManageDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -432,9 +432,6 @@ const changeAccent = async (_: number, accent: number) => {
}
};

const audioElem = new Audio();
audioElem.pause();

const play = async () => {
if (!accentPhrase.value) return;

Expand Down Expand Up @@ -471,11 +468,11 @@ const play = async () => {
}
nowGenerating.value = false;
nowPlaying.value = true;
await store.dispatch("PLAY_AUDIO_BLOB", { audioElem, audioBlob: blob });
await store.dispatch("PLAY_AUDIO_BLOB", { audioBlob: blob });
nowPlaying.value = false;
};
const stop = () => {
audioElem.pause();
store.dispatch("STOP_AUDIO");
};

// accent phraseにあるaccentと実際に登録するアクセントには差が生まれる
Expand Down
59 changes: 30 additions & 29 deletions src/store/audio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,16 @@ export function applyAudioPresetToAudioItem(
}

const audioBlobCache: Record<string, Blob> = {};
const audioElements: Record<AudioKey, HTMLAudioElement> = {};
// ユニットテストが落ちるのを回避するための遅延読み込み
const getAudioElement = (() => {
let audioElement: HTMLAudioElement | undefined = undefined;
return () => {
if (audioElement == undefined) {
audioElement = new Audio();
}
return audioElement;
};
})();

export const audioStoreState: AudioStoreState = {
characterInfos: {},
Expand Down Expand Up @@ -276,7 +285,7 @@ export const audioStore = createPartialStore<AudioStoreTypes>({
ACTIVE_AUDIO_ELEM_CURRENT_TIME: {
getter: (state) => {
return state._activeAudioKey !== undefined
? audioElements[state._activeAudioKey]?.currentTime
? getAudioElement().currentTime
: undefined;
},
},
Expand Down Expand Up @@ -461,7 +470,6 @@ export const audioStore = createPartialStore<AudioStoreTypes>({
GENERATE_AUDIO_KEY: {
action() {
const audioKey = AudioKey(uuidv4());
audioElements[audioKey] = new Audio();
return audioKey;
},
},
Expand Down Expand Up @@ -1713,8 +1721,7 @@ export const audioStore = createPartialStore<AudioStoreTypes>({
PLAY_AUDIO: {
action: createUILockAction(
async ({ commit, dispatch }, { audioKey }: { audioKey: AudioKey }) => {
const audioElem = audioElements[audioKey];
audioElem.pause();
getAudioElement().pause();

// 音声用意
let blob = await dispatch("GET_AUDIO_CACHE", { audioKey });
Expand All @@ -1738,7 +1745,6 @@ export const audioStore = createPartialStore<AudioStoreTypes>({

return dispatch("PLAY_AUDIO_BLOB", {
audioBlob: blob,
audioElem,
audioKey,
});
}
Expand All @@ -1749,40 +1755,36 @@ export const audioStore = createPartialStore<AudioStoreTypes>({
action: createUILockAction(
async (
{ state, commit, dispatch },
{
audioBlob,
audioElem,
audioKey,
}: { audioBlob: Blob; audioElem: HTMLAudioElement; audioKey?: AudioKey }
{ audioBlob, audioKey }: { audioBlob: Blob; audioKey?: AudioKey }
) => {
audioElem.src = URL.createObjectURL(audioBlob);
getAudioElement().src = URL.createObjectURL(audioBlob);
// 途中再生用の処理
if (audioKey) {
const accentPhraseOffsets = await dispatch("GET_AUDIO_PLAY_OFFSETS", {
audioKey,
});
if (accentPhraseOffsets.length === 0) {
audioElem.currentTime = 0;
getAudioElement().currentTime = 0;
} else {
const startTime =
accentPhraseOffsets[state.audioPlayStartPoint ?? 0];
if (startTime === undefined) throw Error("startTime === undefined");
// 小さい値が切り捨てられることでフォーカスされるアクセントフレーズが一瞬元に戻るので、
// 再生に影響のない程度かつ切り捨てられない値を加算する
audioElem.currentTime = startTime + 10e-6;
getAudioElement().currentTime = startTime + 10e-6;
}
}

// 一部ブラウザではsetSinkIdが実装されていないので、その環境では無視する
if (audioElem.setSinkId) {
audioElem
if (getAudioElement().setSinkId) {
getAudioElement()
.setSinkId(state.savingSetting.audioOutputDevice)
.catch((err) => {
const stop = () => {
audioElem.pause();
audioElem.removeEventListener("canplay", stop);
getAudioElement().pause();
getAudioElement().removeEventListener("canplay", stop);
};
audioElem.addEventListener("canplay", stop);
getAudioElement().addEventListener("canplay", stop);
window.electron.showMessageDialog({
type: "error",
title: "エラー",
Expand All @@ -1798,33 +1800,32 @@ export const audioStore = createPartialStore<AudioStoreTypes>({
commit("SET_AUDIO_NOW_PLAYING", { audioKey, nowPlaying: true });
}
};
audioElem.addEventListener("play", played);
getAudioElement().addEventListener("play", played);

let paused: () => void;
const audioPlayPromise = new Promise<boolean>((resolve) => {
paused = () => {
resolve(audioElem.ended);
resolve(getAudioElement().ended);
};
audioElem.addEventListener("pause", paused);
getAudioElement().addEventListener("pause", paused);
}).finally(async () => {
audioElem.removeEventListener("play", played);
audioElem.removeEventListener("pause", paused);
getAudioElement().removeEventListener("play", played);
getAudioElement().removeEventListener("pause", paused);
if (audioKey) {
commit("SET_AUDIO_NOW_PLAYING", { audioKey, nowPlaying: false });
}
});

audioElem.play();
getAudioElement().play();

return audioPlayPromise;
}
),
},

STOP_AUDIO: {
action(_, { audioKey }: { audioKey: AudioKey }) {
const audioElem = audioElements[audioKey];
audioElem.pause();
action() {
getAudioElement().pause();
},
},

Expand Down Expand Up @@ -1878,7 +1879,7 @@ export const audioStore = createPartialStore<AudioStoreTypes>({
action({ state, dispatch }) {
for (const audioKey of state.audioKeys) {
if (state.audioStates[audioKey].nowPlaying) {
dispatch("STOP_AUDIO", { audioKey });
dispatch("STOP_AUDIO");
}
}
},
Expand Down
8 changes: 2 additions & 6 deletions src/store/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -448,15 +448,11 @@ export type AudioStoreTypes = {
};

PLAY_AUDIO_BLOB: {
action(payload: {
audioBlob: Blob;
audioElem: HTMLAudioElement;
audioKey?: AudioKey;
}): boolean;
action(payload: { audioBlob: Blob; audioKey?: AudioKey }): boolean;
};

STOP_AUDIO: {
action(payload: { audioKey: AudioKey }): void;
action(): void;
};

SET_AUDIO_PRESET_KEY: {
Expand Down