Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
C
CharIP-Electron
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ali
CharIP-Electron
Commits
38df065c
You need to sign in or sign up before continuing.
Commit
38df065c
authored
Dec 27, 2023
by
ali
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: 优化相关异常处理
parent
dff91c47
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
167 additions
and
172 deletions
+167
-172
ShowPhoto.vue
src/renderer/screens/ShowPhoto.vue
+94
-93
ShowVideo.vue
src/renderer/screens/ShowVideo.vue
+73
-79
No files found.
src/renderer/screens/ShowPhoto.vue
View file @
38df065c
...
@@ -50,10 +50,10 @@ onMounted(() => {
...
@@ -50,10 +50,10 @@ onMounted(() => {
})
})
const
errorSnackbar
=
ref
<
boolean
>
(
false
)
const
errorSnackbar
=
ref
<
boolean
>
(
false
)
const
errorMsg
=
ref
<
string
>
(
''
)
;
const
errorMsg
=
ref
<
string
>
(
''
)
const
showError
=
(
msg
:
string
)
=>
{
const
showError
=
(
msg
:
string
)
=>
{
errorSnackbar
.
value
=
true
;
errorSnackbar
.
value
=
true
errorMsg
.
value
=
msg
;
errorMsg
.
value
=
msg
}
}
function
loadImg
():
Promise
<
HTMLImageElement
>
{
function
loadImg
():
Promise
<
HTMLImageElement
>
{
...
@@ -77,17 +77,7 @@ async function init() {
...
@@ -77,17 +77,7 @@ async function init() {
canvasEle
.
height
=
img
.
naturalHeight
canvasEle
.
height
=
img
.
naturalHeight
const
item
=
photo
.
list
.
find
((
i
)
=>
i
.
url
===
url
)
const
item
=
photo
.
list
.
find
((
i
)
=>
i
.
url
===
url
)
photoRole
=
new
PhotoRole
(
settings
.
liveHost
,
`
${
item
?.
liveUrl
}
`, canvasEle)
photoRole
=
new
PhotoRole
(
settings
.
liveHost
,
`
${
item
?.
liveUrl
}
`, canvasEle)
photoRole.on('asyncAnswer', onAsyncAnswer)
photoRole.on('asyncAnswer', async (ans) => {
if (ans.playState === 'playing') {
microphoneState.value = 'reply'
return
}
if (microphoneState.value === 'reply' && ans.playState === 'pause' && (await checkSteps())) {
microphoneState.value = 'input'
}
})
// initPlayer(videoEle);
// initPlayer(videoEle);
...
@@ -112,6 +102,17 @@ async function init() {
...
@@ -112,6 +102,17 @@ async function init() {
requestAnimationFrame(updateFrame)
requestAnimationFrame(updateFrame)
}
}
async function onAsyncAnswer(ans: PhotoAnswer) {
if (ans.playState === 'playing') {
microphoneState.value = 'reply'
return
}
if (microphoneState.value === 'reply' && ans.playState === 'pause' && (await checkSteps())) {
microphoneState.value = 'input'
}
}
function draw(
function draw(
ctx: CanvasRenderingContext2D,
ctx: CanvasRenderingContext2D,
img: HTMLImageElement,
img: HTMLImageElement,
...
@@ -273,7 +274,7 @@ async function startVoskWsAudioInput() {
...
@@ -273,7 +274,7 @@ async function startVoskWsAudioInput() {
if (microphoneState.value === 'loading') return
if (microphoneState.value === 'loading') return
if (microphoneState.value === 'input') {
if (microphoneState.value === 'input') {
endAudioInput()
await
endAudioInput()
return
return
}
}
...
@@ -378,6 +379,9 @@ async function endAudioInput() {
...
@@ -378,6 +379,9 @@ async function endAudioInput() {
}
}
inputContext.asrPartial = ''
inputContext.asrPartial = ''
inputContext.answerArray.length = 0
inputContext.answerArray.length = 0
inputContext.steps.length = 0
// @ts-ignore
photoRole?.off('asyncAnswer', onAsyncAnswer)
await photoRole?.destroy()
await photoRole?.destroy()
}
}
...
@@ -417,13 +421,14 @@ async function onQ(question: string) {
...
@@ -417,13 +421,14 @@ async function onQ(question: string) {
microphoneState.value = 'loading'
microphoneState.value = 'loading'
try {
const ws = await initLLMSocket()
const ws = await initLLMSocket()
const { pose, stepResolve, stepReject } = createStep()
const { pose, stepResolve, stepReject } = createStep()
const messageTimeout = setTimeout(async () => {
const messageTimeout = setTimeout(async () => {
showError('llm:timeout!')
showError('llm:timeout!')
await endAudioInput()
await endAudioInput()
microphoneState.value = 'waitInput'
microphoneState.value = 'waitInput'
}, 5000);
}, 10000)
let sliceAnswer = ''
let sliceAnswer = ''
let answer = ''
let answer = ''
...
@@ -435,6 +440,7 @@ async function onQ(question: string) {
...
@@ -435,6 +440,7 @@ async function onQ(question: string) {
inputContext.steps.length = 0
inputContext.steps.length = 0
inputContext.steps.push(pose)
inputContext.steps.push(pose)
photoRole!.answerArgs = new PhotoAnswer()
photoRole!.answerArgs = new PhotoAnswer()
photoRole!.on('asyncAnswer', onAsyncAnswer)
ws.onmessage = (message) => {
ws.onmessage = (message) => {
try {
try {
...
@@ -459,7 +465,7 @@ async function onQ(question: string) {
...
@@ -459,7 +465,7 @@ async function onQ(question: string) {
photoRole!.answerArgs!._typingAnswer.push(answer)
photoRole!.answerArgs!._typingAnswer.push(answer)
isTime && console.time('sliceAnswer')
isTime && console.time('sliceAnswer')
isTime = false
isTime = false
clearTimeout(messageTimeout);
clearTimeout(messageTimeout)
const textArr = text.split('')
const textArr = text.split('')
for (let i = 0; i < textArr.length; i++) {
for (let i = 0; i < textArr.length; i++) {
...
@@ -475,7 +481,7 @@ async function onQ(question: string) {
...
@@ -475,7 +481,7 @@ async function onQ(question: string) {
}
}
}
}
} catch (error) {
} catch (error) {
showError('llm:'
+ error)
showError('llm:'
+ error)
endAudioInput().then(() => {
endAudioInput().then(() => {
microphoneState.value = 'waitInput'
microphoneState.value = 'waitInput'
})
})
...
@@ -484,6 +490,11 @@ async function onQ(question: string) {
...
@@ -484,6 +490,11 @@ async function onQ(question: string) {
}
}
ws.send(JSON.stringify({ prompt: question, historys_list: [] }))
ws.send(JSON.stringify({ prompt: question, historys_list: [] }))
} catch (error) {
console.error(error)
microphoneState.value = 'input'
showError(`
llm
:
$
{
JSON
.
stringify
(
error
)}
`)
}
}
}
let isTTSRunning = false
let isTTSRunning = false
...
@@ -525,7 +536,7 @@ async function runTTSTask() {
...
@@ -525,7 +536,7 @@ async function runTTSTask() {
}
)
}
)
}
}
} catch (error) {
} catch (error) {
showError('tts:'+ error)
showError('tts:'
+ error)
endAudioInput().then(() => {
endAudioInput().then(() => {
microphoneState.value = 'waitInput'
microphoneState.value = 'waitInput'
})
})
...
@@ -577,7 +588,7 @@ async function down() {
...
@@ -577,7 +588,7 @@ async function down() {
try {
try {
await startVoskWsAudioInput()
await startVoskWsAudioInput()
} catch (error) {
} catch (error) {
showError('start:'+ error)
showError('start:'
+ error)
endAudioInput().then(() => {
endAudioInput().then(() => {
microphoneState.value = 'waitInput'
microphoneState.value = 'waitInput'
})
})
...
@@ -631,21 +642,11 @@ async function down() {
...
@@ -631,21 +642,11 @@ async function down() {
</v-btn>
</v-btn>
</div>
</div>
<v-snackbar
<v-snackbar
v-model=
"errorSnackbar"
multi-line
:timeout=
"3000"
>
v-model=
"errorSnackbar"
multi-line
:timeout=
"3000"
>
{{ errorMsg }}
{{ errorMsg }}
<
template
#
actions
>
<
template
#
actions
>
<v-btn
<v-btn
color=
"red"
variant=
"text"
@
click=
"errorSnackbar = false"
>
Close
</v-btn>
color=
"red"
variant=
"text"
@
click=
"errorSnackbar = false"
>
Close
</v-btn>
</
template
>
</
template
>
</v-snackbar>
</v-snackbar>
</template>
</template>
...
...
src/renderer/screens/ShowVideo.vue
View file @
38df065c
...
@@ -35,8 +35,10 @@ const inputContext: {
...
@@ -35,8 +35,10 @@ const inputContext: {
voskWs
?:
WebSocket
voskWs
?:
WebSocket
asrPartial
:
string
asrPartial
:
string
playingAudio
?:
HTMLAudioElement
playingAudio
?:
HTMLAudioElement
answerArray
:
string
[]
}
=
{
}
=
{
asrPartial
:
''
asrPartial
:
''
,
answerArray
:
[]
}
}
onMounted
(()
=>
{
onMounted
(()
=>
{
...
@@ -48,10 +50,10 @@ router.beforeEach((g) => {
...
@@ -48,10 +50,10 @@ router.beforeEach((g) => {
})
})
const
errorSnackbar
=
ref
<
boolean
>
(
false
)
const
errorSnackbar
=
ref
<
boolean
>
(
false
)
const
errorMsg
=
ref
<
string
>
(
''
)
;
const
errorMsg
=
ref
<
string
>
(
''
)
const
showError
=
(
msg
:
string
)
=>
{
const
showError
=
(
msg
:
string
)
=>
{
errorSnackbar
.
value
=
true
;
errorSnackbar
.
value
=
true
errorMsg
.
value
=
msg
;
errorMsg
.
value
=
msg
}
}
async
function
initVosk
({
async
function
initVosk
({
...
@@ -275,6 +277,7 @@ function endAudioInput() {
...
@@ -275,6 +277,7 @@ function endAudioInput() {
videos
[
1
].
value
?.
pause
()
videos
[
1
].
value
?.
pause
()
videos
[
0
].
value
?.
pause
()
videos
[
0
].
value
?.
pause
()
isPlayRunning
=
false
isPlayRunning
=
false
inputContext
.
answerArray
.
length
=
0
}
}
const
canplay
=
()
=>
{
const
canplay
=
()
=>
{
...
@@ -344,19 +347,18 @@ async function onQ(question: string) {
...
@@ -344,19 +347,18 @@ async function onQ(question: string) {
}
}
// 视频链接匹配不上,直接走大模型
// 视频链接匹配不上,直接走大模型
try
{
const
ws
=
await
initLLMSocket
()
const
ws
=
await
initLLMSocket
()
const
answerArray
:
string
[]
=
[]
const
messageTimeout
=
setTimeout
(()
=>
{
const
messageTimeout
=
setTimeout
(()
=>
{
showError
(
'llm:timeout!'
)
showError
(
'llm:timeout!'
)
endAudioInput
()
endAudioInput
()
microphoneState
.
value
=
'waitInput'
microphoneState
.
value
=
'waitInput'
},
5000
);
},
10000
)
let
sliceAnswer
=
''
let
sliceAnswer
=
''
let
answer
=
''
let
answer
=
''
let
isTime
=
true
let
isTime
=
true
let
sliceAnswerLength
=
10
let
sliceAnswerLength
=
10
inputContext
.
ws
=
ws
inputContext
.
ws
=
ws
ws
.
onmessage
=
(
message
)
=>
{
ws
.
onmessage
=
(
message
)
=>
{
if
(
microphoneState
.
value
===
'input'
)
{
if
(
microphoneState
.
value
===
'input'
)
{
return
return
...
@@ -370,11 +372,11 @@ async function onQ(question: string) {
...
@@ -370,11 +372,11 @@ async function onQ(question: string) {
}
}
if
(
event
===
'stream_end'
)
{
if
(
event
===
'stream_end'
)
{
answerArray
.
push
(
sliceAnswer
)
inputContext
.
answerArray
.
push
(
sliceAnswer
)
runTTSTask
(
answerArray
)
runTTSTask
(
)
sliceAnswer
=
''
sliceAnswer
=
''
answerArray
.
push
(
sliceAnswer
)
inputContext
.
answerArray
.
push
(
sliceAnswer
)
sliceAnswer
=
''
sliceAnswer
=
''
inputContext
.
ws
?.
close
()
inputContext
.
ws
?.
close
()
console
.
log
(
'----------------> answer: '
,
answer
)
console
.
log
(
'----------------> answer: '
,
answer
)
...
@@ -384,7 +386,7 @@ async function onQ(question: string) {
...
@@ -384,7 +386,7 @@ async function onQ(question: string) {
answer
+=
text
answer
+=
text
isTime
&&
console
.
time
(
'sliceAnswer'
)
isTime
&&
console
.
time
(
'sliceAnswer'
)
isTime
=
false
isTime
=
false
clearTimeout
(
messageTimeout
);
clearTimeout
(
messageTimeout
)
const
textArr
=
text
.
split
(
''
)
const
textArr
=
text
.
split
(
''
)
for
(
let
i
=
0
;
i
<
textArr
.
length
;
i
++
)
{
for
(
let
i
=
0
;
i
<
textArr
.
length
;
i
++
)
{
...
@@ -393,32 +395,34 @@ async function onQ(question: string) {
...
@@ -393,32 +395,34 @@ async function onQ(question: string) {
if
(
/
[
。,?!;,.?!;
]
/
.
test
(
t
)
&&
sliceAnswer
.
length
>=
sliceAnswerLength
)
{
if
(
/
[
。,?!;,.?!;
]
/
.
test
(
t
)
&&
sliceAnswer
.
length
>=
sliceAnswerLength
)
{
console
.
timeEnd
(
'sliceAnswer'
)
console
.
timeEnd
(
'sliceAnswer'
)
sliceAnswerLength
=
settings
.
llmToTTSSliceLength
sliceAnswerLength
=
settings
.
llmToTTSSliceLength
answerArray
.
push
(
sliceAnswer
)
inputContext
.
answerArray
.
push
(
sliceAnswer
)
runTTSTask
(
answerArray
)
runTTSTask
(
)
sliceAnswer
=
''
sliceAnswer
=
''
isTime
=
true
isTime
=
true
}
}
}
}
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
error
(
error
);
console
.
error
(
error
)
showError
(
`message:
${
error
}
`
)
showError
(
`message:
${
error
}
`
)
microphoneState
.
value
=
'waitInput'
microphoneState
.
value
=
'waitInput'
}
}
}
}
ws
.
send
(
JSON
.
stringify
({
prompt
:
question
,
historys_list
:
[]
}))
ws
.
send
(
JSON
.
stringify
({
prompt
:
question
,
historys_list
:
[]
}))
}
catch
(
error
)
{
console
.
error
(
error
)
microphoneState
.
value
=
'input'
showError
(
`llm:
${
JSON
.
stringify
(
error
)}
`
)
}
}
}
let
isTTSRunning
=
false
let
isTTSRunning
=
false
async
function
runTTSTask
(
tasks
:
string
[]
)
{
async
function
runTTSTask
()
{
if
(
isTTSRunning
)
return
if
(
isTTSRunning
)
return
isTTSRunning
=
true
isTTSRunning
=
true
microphoneState
.
value
=
'loading'
try
{
try
{
while
(
tasks
.
length
)
{
while
(
inputContext
.
answerArray
.
length
)
{
const
task
=
tasks
.
shift
()
const
task
=
inputContext
.
answerArray
.
shift
()
if
(
!
task
)
break
if
(
!
task
)
break
if
(
task
.
trim
().
length
<
1
)
continue
if
(
task
.
trim
().
length
<
1
)
continue
...
@@ -560,21 +564,11 @@ async function down() {
...
@@ -560,21 +564,11 @@ async function down() {
</v-chip>
</v-chip>
</div>
</div>
<v-snackbar
<v-snackbar
v-model=
"errorSnackbar"
multi-line
:timeout=
"3000"
>
v-model=
"errorSnackbar"
multi-line
:timeout=
"3000"
>
{{ errorMsg }}
{{ errorMsg }}
<
template
#
actions
>
<
template
#
actions
>
<v-btn
<v-btn
color=
"red"
variant=
"text"
@
click=
"errorSnackbar = false"
>
Close
</v-btn>
color=
"red"
variant=
"text"
@
click=
"errorSnackbar = false"
>
Close
</v-btn>
</
template
>
</
template
>
</v-snackbar>
</v-snackbar>
</template>
</template>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment