feat(stage-*): experimental realtime transcription powered by Aliyun NLS

This commit is contained in:
Neko Ayaka
2025-11-02 04:20:27 +08:00
parent 7bde379ab3
commit 69b8a56937
16 changed files with 1101 additions and 21 deletions
+1
View File
@@ -93,6 +93,7 @@
"three": "^0.181.0",
"unified": "^11.0.5",
"unspeech": "^0.1.7",
"uuid": "^13.0.0",
"valibot": "1.0.0-beta.9",
"vaul-vue": "^0.4.1",
"vue": "^3.5.22",
@@ -13,7 +13,7 @@ import { useConsciousnessStore } from '@proj-airi/stage-ui/stores/modules/consci
import { useHearingSpeechInputPipeline } from '@proj-airi/stage-ui/stores/modules/hearing'
import { useProvidersStore } from '@proj-airi/stage-ui/stores/providers'
import { useSettingsAudioDevice } from '@proj-airi/stage-ui/stores/settings'
import { debouncedRef, useBroadcastChannel, watchPausable } from '@vueuse/core'
import { refDebounced, useBroadcastChannel } from '@vueuse/core'
import { storeToRefs } from 'pinia'
import { computed, onUnmounted, ref, toRef, watch } from 'vue'
@@ -43,11 +43,11 @@ const shouldFadeOnCursorWithin = ref(false)
const { isOutside: isOutsideWindow } = useElectronMouseInWindow()
const { isOutside } = useElectronMouseInElement(controlsIslandRef)
const isOutsideFor250Ms = debouncedRef(isOutside, 250)
const isOutsideFor250Ms = refDebounced(isOutside, 250)
const { x: relativeMouseX, y: relativeMouseY } = useElectronRelativeMouse()
const isTransparent = useCanvasPixelIsTransparentAtPoint(stageCanvas, relativeMouseX, relativeMouseY)
const { isNearAnyBorder: isAroundWindowBorder } = useElectronMouseAroundWindowBorder({ threshold: 30 })
const isAroundWindowBorderFor250Ms = debouncedRef(isAroundWindowBorder, 250)
const isAroundWindowBorderFor250Ms = refDebounced(isAroundWindowBorder, 250)
const setIgnoreMouseEvents = useElectronEventaInvoke(electron.window.setIgnoreMouseEvents)
@@ -56,7 +56,7 @@ const { live2dLookAtX, live2dLookAtY } = storeToRefs(useWindowStore())
watch(componentStateStage, () => isLoading.value = componentStateStage.value !== 'mounted', { immediate: true })
const { pause, resume } = watchPausable(isTransparent, (transparent) => {
const { pause, resume } = watch(isTransparent, (transparent) => {
shouldFadeOnCursorWithin.value = !transparent
}, { immediate: true })
@@ -36,6 +36,12 @@ const menu = computed(() => [
icon: 'i-solar:sledgehammer-bold-duotone',
to: '/devtools/use-electron-relative-mouse',
},
{
title: 'Aliyun Real-time Transcriber',
description: 'Stream microphone audio to Aliyun NLS and inspect live transcripts',
icon: 'i-solar:sledgehammer-bold-duotone',
to: '/devtools/providers-transcription-realtime-aliyun-nls',
},
])
const { context } = createContext(window.electron.ipcRenderer)
+1
View File
@@ -80,6 +80,7 @@
"three": "^0.181.0",
"unified": "^11.0.5",
"unspeech": "^0.1.7",
"uuid": "^13.0.0",
"valibot": "1.0.0-beta.9",
"vaul-vue": "^0.4.1",
"vue": "^3.5.22",
@@ -62,6 +62,12 @@ const menu = computed(() => [
icon: 'i-solar:sledgehammer-bold-duotone',
to: '/devtools/vibrant',
},
{
title: 'Aliyun Real-time Transcriber',
description: 'Stream microphone audio to Aliyun NLS and inspect live transcripts',
icon: 'i-solar:sledgehammer-bold-duotone',
to: '/devtools/providers-transcription-realtime-aliyun-nls',
},
])
</script>