From e0d38695ff541b1ff803eaf5ad06147eb31da3f5 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 29 Nov 2024 03:10:16 +0900 Subject: [PATCH] =?UTF-8?q?=E9=81=B8=E6=8A=9E=E3=81=97=E3=81=9F=E5=86=8D?= =?UTF-8?q?=E7=94=9F=E3=83=87=E3=83=90=E3=82=A4=E3=82=B9=E3=81=8C=E3=82=BD?= =?UTF-8?q?=E3=83=B3=E3=82=B0=E3=81=A7=E3=82=82=E9=81=A9=E7=94=A8=E3=81=95?= =?UTF-8?q?=E3=82=8C=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E3=81=99=E3=82=8B?= =?UTF-8?q?=20(#2375)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Hiroshiba --- src/components/App.vue | 7 +++++++ src/store/singing.ts | 18 ++++++++++++++++++ src/store/type.ts | 4 ++++ src/type/globals.d.ts | 4 ++++ 4 files changed, 33 insertions(+) diff --git a/src/components/App.vue b/src/components/App.vue index e1cc5c9a42..68cb92c3a7 100644 --- a/src/components/App.vue +++ b/src/components/App.vue @@ -97,6 +97,13 @@ watchEffect(() => { setThemeToCss(theme); }); +// ソングの再生デバイスを同期 +watchEffect(() => { + void store.actions.APPLY_DEVICE_ID_TO_AUDIO_CONTEXT({ + device: store.state.savingSetting.audioOutputDevice, + }); +}); + // ソフトウェアを初期化 const { hotkeyManager } = useHotkeyManager(); const isEnginesReady = ref(false); diff --git a/src/store/singing.ts b/src/store/singing.ts index 611fe2ce22..d343bfe912 100644 --- a/src/store/singing.ts +++ b/src/store/singing.ts @@ -106,6 +106,7 @@ import { uuid4 } from "@/helpers/random"; import { convertToWavFileData } from "@/sing/convertToWavFileData"; import { generateWriteErrorMessage } from "@/helpers/fileHelper"; import path from "@/helpers/path"; +import { showAlertDialog } from "@/components/Dialog/Dialog"; const logger = createLogger("store/singing"); @@ -1682,6 +1683,23 @@ export const singingStore = createPartialStore({ }, }, + APPLY_DEVICE_ID_TO_AUDIO_CONTEXT: { + action(_, { device }) { + if (!audioContext) { + throw new Error("audioContext is undefined."); + } + const sinkId = device === "default" ? "" : device; + audioContext.setSinkId(sinkId).catch((err: unknown) => { + void showAlertDialog({ + type: "error", + title: "エラー", + message: "再生デバイスが見つかりません", + }); + throw err; + }); + }, + }, + /** * レンダリングを行う。レンダリング中だった場合は停止して再レンダリングする。 */ diff --git a/src/store/type.ts b/src/store/type.ts index fae93613da..50c523d22a 100644 --- a/src/store/type.ts +++ b/src/store/type.ts @@ -1326,6 +1326,10 @@ export type SingingStoreTypes = { SYNC_TRACKS_AND_TRACK_CHANNEL_STRIPS: { action(): void; }; + + APPLY_DEVICE_ID_TO_AUDIO_CONTEXT: { + action(payload: { device: string }): void; + }; }; export type SingingCommandStoreState = { diff --git a/src/type/globals.d.ts b/src/type/globals.d.ts index 6c761fa17f..9708bb15e5 100644 --- a/src/type/globals.d.ts +++ b/src/type/globals.d.ts @@ -9,6 +9,10 @@ declare global { setSinkId(deviceID: string): Promise; // setSinkIdを認識してくれないため } + interface AudioContext { + setSinkId: (sinkId: string) => Promise; + } + interface Window { readonly [SandboxKey]: import("./preload").Sandbox; }