diff --git a/CHANGELOG.md b/CHANGELOG.md
index 900d042eaf..7feb89b546 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,6 +20,7 @@
 
 ### Client
 - fix: 「設定のバックアップ」で一部の項目がバックアップに含まれていなかった問題を修正
+- Fix: ウィジェットのジョブキューにて音声の発音方法変更に追従できていなかったのを修正 #12367
 
 ### Server
 - Fix: 時間経過により無効化されたアンテナを再有効化したとき、サーバ再起動までその状況が反映されないのを修正 #12303
diff --git a/packages/frontend/src/scripts/sound.ts b/packages/frontend/src/scripts/sound.ts
index 4b0cd0bb39..2b604bd98a 100644
--- a/packages/frontend/src/scripts/sound.ts
+++ b/packages/frontend/src/scripts/sound.ts
@@ -61,7 +61,7 @@ export const soundsTypes = [
 	'noizenecio/kick_gaba7',
 ] as const;
 
-export async function getAudio(file: string, useCache = true) {
+export async function loadAudio(file: string, useCache = true) {
 	if (useCache && cache.has(file)) {
 		return cache.get(file)!;
 	}
@@ -77,12 +77,6 @@ export async function getAudio(file: string, useCache = true) {
 	return audioBuffer;
 }
 
-export function setVolume(audio: HTMLAudioElement, volume: number): HTMLAudioElement {
-	const masterVolume = defaultStore.state.sound_masterVolume;
-	audio.volume = masterVolume - ((1 - volume) * masterVolume);
-	return audio;
-}
-
 export function play(type: 'noteMy' | 'note' | 'antenna' | 'channel' | 'notification') {
 	const sound = defaultStore.state[`sound_${type}`];
 	if (_DEV_) console.log('play', type, sound);
@@ -91,16 +85,22 @@ export function play(type: 'noteMy' | 'note' | 'antenna' | 'channel' | 'notifica
 }
 
 export async function playFile(file: string, volume: number) {
+	const buffer = await loadAudio(file);
+	createSourceNode(buffer, volume)?.start();
+}
+
+export function createSourceNode(buffer: AudioBuffer, volume: number) : AudioBufferSourceNode | null {
 	const masterVolume = defaultStore.state.sound_masterVolume;
 	if (masterVolume === 0 || volume === 0) {
-		return;
+		return null;
 	}
 
 	const gainNode = ctx.createGain();
 	gainNode.gain.value = masterVolume * volume;
 
 	const soundSource = ctx.createBufferSource();
-	soundSource.buffer = await getAudio(file);
+	soundSource.buffer = buffer;
 	soundSource.connect(gainNode).connect(ctx.destination);
-	soundSource.start();
+
+	return soundSource;
 }
diff --git a/packages/frontend/src/widgets/WidgetJobQueue.vue b/packages/frontend/src/widgets/WidgetJobQueue.vue
index 89770b2216..fa82997570 100644
--- a/packages/frontend/src/widgets/WidgetJobQueue.vue
+++ b/packages/frontend/src/widgets/WidgetJobQueue.vue
@@ -99,7 +99,10 @@ const current = reactive({
 	},
 });
 const prev = reactive({} as typeof current);
-const jammedSound = sound.setVolume(sound.getAudio('syuilo/queue-jammed'), 1);
+let jammedAudioBuffer: AudioBuffer | null = $ref(null);
+let jammedSoundNodePlaying: boolean = $ref(false);
+
+sound.loadAudio('syuilo/queue-jammed').then(buf => jammedAudioBuffer = buf);
 
 for (const domain of ['inbox', 'deliver']) {
 	prev[domain] = deepClone(current[domain]);
@@ -113,8 +116,13 @@ const onStats = (stats) => {
 		current[domain].waiting = stats[domain].waiting;
 		current[domain].delayed = stats[domain].delayed;
 
-		if (current[domain].waiting > 0 && widgetProps.sound && jammedSound.paused) {
-			jammedSound.play();
+		if (current[domain].waiting > 0 && widgetProps.sound && jammedAudioBuffer && !jammedSoundNodePlaying) {
+			const soundNode = sound.createSourceNode(jammedAudioBuffer, 1);
+			if (soundNode) {
+				jammedSoundNodePlaying = true;
+				soundNode.onended = () => jammedSoundNodePlaying = false;
+				soundNode.start();
+			}
 		}
 	}
 };