forked from VOICEVOX/voicevox
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
167 additions
and
137 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
/** | ||
* HTMLAudioElement周りの音声再生・停止などを担当する。 | ||
*/ | ||
import { createPartialStore } from "./vuex"; | ||
import { AudioPlayerStoreState, AudioPlayerStoreTypes } from "./type"; | ||
import { AudioKey } from "@/type/preload"; | ||
|
||
// ユニットテストが落ちるのを回避するための遅延読み込み | ||
const getAudioElement = (() => { | ||
let audioElement: HTMLAudioElement | undefined = undefined; | ||
return () => { | ||
if (audioElement == undefined) { | ||
audioElement = new Audio(); | ||
} | ||
return audioElement; | ||
}; | ||
})(); | ||
|
||
export const audioPlayerStoreState: AudioPlayerStoreState = { | ||
nowPlayingAudioKey: undefined, | ||
}; | ||
|
||
export const audioPlayerStore = createPartialStore<AudioPlayerStoreTypes>({ | ||
ACTIVE_AUDIO_ELEM_CURRENT_TIME: { | ||
getter: (state) => { | ||
return state._activeAudioKey !== undefined | ||
? getAudioElement().currentTime | ||
: undefined; | ||
}, | ||
}, | ||
|
||
NOW_PLAYING: { | ||
getter(state, getters) { | ||
const activeAudioKey = getters.ACTIVE_AUDIO_KEY; | ||
return ( | ||
activeAudioKey != undefined && | ||
activeAudioKey === state.nowPlayingAudioKey | ||
); | ||
}, | ||
}, | ||
|
||
SET_AUDIO_NOW_PLAYING: { | ||
mutation( | ||
state, | ||
{ audioKey, nowPlaying }: { audioKey: AudioKey; nowPlaying: boolean } | ||
) { | ||
state.nowPlayingAudioKey = nowPlaying ? audioKey : undefined; | ||
}, | ||
}, | ||
|
||
SET_AUDIO_SOURCE: { | ||
mutation(_, { audioBlob }: { audioBlob: Blob }) { | ||
getAudioElement().src = URL.createObjectURL(audioBlob); | ||
}, | ||
}, | ||
|
||
PLAY_AUDIO_PLAYER: { | ||
async action( | ||
{ state, commit }, | ||
{ offset, audioKey }: { offset?: number; audioKey?: AudioKey } | ||
) { | ||
const audioElement = getAudioElement(); | ||
|
||
if (offset !== undefined) { | ||
audioElement.currentTime = offset; | ||
} | ||
|
||
// 一部ブラウザではsetSinkIdが実装されていないので、その環境では無視する | ||
if (audioElement.setSinkId) { | ||
audioElement | ||
.setSinkId(state.savingSetting.audioOutputDevice) | ||
.catch((err) => { | ||
const stop = () => { | ||
audioElement.pause(); | ||
audioElement.removeEventListener("canplay", stop); | ||
}; | ||
audioElement.addEventListener("canplay", stop); | ||
window.electron.showMessageDialog({ | ||
type: "error", | ||
title: "エラー", | ||
message: "再生デバイスが見つかりません", | ||
}); | ||
throw new Error(err); | ||
}); | ||
} | ||
|
||
// 再生終了時にresolveされるPromiseを返す | ||
const played = async () => { | ||
if (audioKey) { | ||
commit("SET_AUDIO_NOW_PLAYING", { audioKey, nowPlaying: true }); | ||
} | ||
}; | ||
audioElement.addEventListener("play", played); | ||
|
||
let paused: () => void; | ||
const audioPlayPromise = new Promise<boolean>((resolve) => { | ||
paused = () => { | ||
resolve(audioElement.ended); | ||
}; | ||
audioElement.addEventListener("pause", paused); | ||
}).finally(async () => { | ||
audioElement.removeEventListener("play", played); | ||
audioElement.removeEventListener("pause", paused); | ||
if (audioKey) { | ||
commit("SET_AUDIO_NOW_PLAYING", { audioKey, nowPlaying: false }); | ||
} | ||
}); | ||
|
||
audioElement.play(); | ||
|
||
return audioPlayPromise; | ||
}, | ||
}, | ||
|
||
STOP_AUDIO: { | ||
// 停止中でも呼び出して問題ない | ||
action() { | ||
// PLAY_ でonpause時の処理が設定されているため、pauseするだけで良い | ||
getAudioElement().pause(); | ||
}, | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.