Skip to content

Commit 84893cb

Browse files
yinhewYulin Li
andauthored
[TTS Avatar][JS, Python] Trigger reconnection for websockets disconnection (#2782)
* [TalkingAvatar] Add sample code for TTS talking avatar real-time API * sample codes for batch avatar synthesis * Address repository check failure * update * [Avatar] Update real time avatar sample code to support multi-lingual * [avatar] update real time avatar chat sample to receive GPT response streamingly * [Live Avatar] update chat sample to make some refinements * [TTS Avatar] Update real-time sample to support 1. non-continuous recognition mode 2. a button to stop speaking 3. user can type query without speech * [TTS Avatar] Update real time avatar sample to support auto-reconnect * Don't reset message history when re-connecting * [talking avatar] update real time sample to support using cached local video for idle status, to help save customer cost * Update chat.html and README.md * Update batch avatar sample to use mp4 as default format, to avoid defaultly showing slow speed with vp9 * A minor refinement * Some refinement * Some bug fixing * Refine the reponse receiving logic for AOAI streaming mode, to make it more robust * [Talking Avatar] update real-time sample code to log result id (turn id) for ease of debugging * [Talking Avatar] Update avatar live chat sample, to upgrade AOAI API version from 2023-03-15-preview to 2023-12-01-preview * [Talking Avatar][Live Chat] Update AOAI API to be long term support version 2023-06-01-preview * [Talking Avatar] Add real time avatar sample code for server/client hybrid web app, with server code written in python * Some refinements * Add README.md * Fix repo check failure: files that are neither marked as binary nor text, please extend .gitattributes * [Python][TTS Avatar] Add chat sample * [Python][TTS Avatar] Add chat sample - continue * Support multiple clients management * Update README.md * [Python][TTS Avatar] Support customized ICE server * [Talking Avatar][Python] Support stop speaking * Tolerat speech sdk to unsupport sending message with connection * [Python][TTS Avatar] Send local SDP as post body instead of header, to avoid header size over limit * [python][avatar] update requirements.txt to add the missing dependencies * [python][avatar] update real-time sample to make auto-connection more smoothy * [Python][Avatar] Fix some small bugs * [python][avatar] Support AAD authorization on private endpoint * [Java][Android][Avatar] Add Android sample code for real time avatar * Code refinement * More refinement * More refinement * Update README.md * [Java][Android][Avatar] Remove AddStream method, which is not available with Unified Plan SDP semantics, and use AddTrack per suggestion * [Python][Avatar][Live] Get speaking status from WebRTC event, and remove the checkSpeakingStatus API from backend code * [Java][Android][Live Avatar] Update the sample to demonstrate switching audio output device to loud speaker * [Python][Avatar][Live] Switch from REST API to SDK for calling AOAI * [Python][Avatar][Live] Trigger barging at first recognizing event which is earlier * [Python][Avatar][Live] Enable continuous conversation by default * [Python][Avatar][Live] Disable multi-lingual by default for better latency * [Python][Avatar][Live] Configure shorter segmentation silence timeout for quicker SR * [Live Avatar][Python, CSharp] Add logging for latency * [TTS Avatar][Live][Python, CSharp, JS] Fix a bug to correctly clean up audio player * [TTS Avatar][Live][JavaScript] Output display text with a slower rate, to follow the avatar speaking progress * Make the display text / speech alignment able for on/off * [TTS Avatar][Live][CSharp] Output display text with a slower rate, to follow the avatar speaking progress * Create an auto-deploy file * Unlink the containerApp yinhew-avatar-app from this repo * Delete unnecessary file * [talking avatar][python] Update real time sample to add option to connect with server through WebSocket, and do STT on server side * [TTS Avatar][Live][js] update sample code for support of setting of background image and remote TURN server URL * [talking avatar][live][python] make sure host can still start up without AOAI resource * [Talking Avatar][Live] update sample code to close WS connection in-time, when user closes/refreshes web page, or auto-reconnection is applied * Some refinement to connection object * Update csharp sample as well * [Talking Avatar][Live][Python] Check ICE token fetching success * [Talking Avatar][Live][Python] Add VAD for interruption with lower delay * [TTS Avatar][JS] Continue speaking unfinished sentences after reconnection * [TTS Avatar][Python] Continue speaking unfinished sentences after reconnection * [TTS Avatar][Python] Trigger reconnection for websockets disconnection * [TTS Avatar][JS] Trigger reconnection for websockets disconnection --------- Co-authored-by: Yulin Li <yulili@microsoft.com>
1 parent 11333dd commit 84893cb

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

samples/js/browser/avatar/js/chat.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ var enableQuickReply = false
1414
var quickReplies = [ 'Let me take a look.', 'Let me check.', 'One moment, please.' ]
1515
var byodDocRegex = new RegExp(/\[doc(\d+)\]/g)
1616
var isSpeaking = false
17+
var isReconnecting = false
1718
var speakingText = ""
1819
var spokenTextQueue = []
1920
var repeatSpeakingSentenceAfterReconnection = true
2021
var sessionActive = false
22+
var userClosedSession = false
2123
var lastSpeakTime
2224
var imgUrl = ""
2325

@@ -207,6 +209,7 @@ function setupWebRTC(iceServerUrl, iceServerUsername, iceServerCredential) {
207209
}
208210
}
209211

212+
isReconnecting = false
210213
setTimeout(() => { sessionActive = true }, 5000) // Set session active after 5 seconds
211214
}
212215
}
@@ -223,7 +226,23 @@ function setupWebRTC(iceServerUrl, iceServerUsername, iceServerCredential) {
223226
subtitles.innerHTML = speakingText
224227
} else if (webRTCEvent.event.eventType === 'EVENT_TYPE_SESSION_END' || webRTCEvent.event.eventType === 'EVENT_TYPE_SWITCH_TO_IDLE') {
225228
subtitles.hidden = true
229+
if (webRTCEvent.event.eventType === 'EVENT_TYPE_SESSION_END') {
230+
if (document.getElementById('autoReconnectAvatar').checked && !userClosedSession && !isReconnecting) {
231+
// Session disconnected unexpectedly, need reconnect
232+
console.log(`[${(new Date()).toISOString()}] The WebSockets got disconnected, need reconnect.`)
233+
isReconnecting = true
234+
235+
// Release the existing avatar connection
236+
if (avatarSynthesizer !== undefined) {
237+
avatarSynthesizer.close()
238+
}
239+
240+
// Setup a new avatar connection
241+
connectAvatar()
242+
}
243+
}
226244
}
245+
227246
console.log("[" + (new Date()).toISOString() + "] WebRTC event received: " + e.data)
228247
}
229248
})
@@ -620,6 +639,7 @@ function checkHung() {
620639
sessionActive = false
621640
if (document.getElementById('autoReconnectAvatar').checked) {
622641
console.log(`[${(new Date()).toISOString()}] The video stream got disconnected, need reconnect.`)
642+
isReconnecting = true
623643
// Release the existing avatar connection
624644
if (avatarSynthesizer !== undefined) {
625645
avatarSynthesizer.close()
@@ -670,6 +690,7 @@ window.startSession = () => {
670690
return
671691
}
672692

693+
userClosedSession = false
673694
connectAvatar()
674695
}
675696

@@ -687,6 +708,7 @@ window.stopSession = () => {
687708
document.getElementById('localVideo').hidden = true
688709
}
689710

711+
userClosedSession = true
690712
disconnectAvatar()
691713
}
692714

samples/python/web/avatar/static/js/chat.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ var peerConnection
1212
var isSpeaking = false
1313
var isReconnecting = false
1414
var sessionActive = false
15+
var userClosedSession = false
1516
var recognitionStartedTime
1617
var chatRequestSentTime
1718
var chatResponseReceivedTime
@@ -249,6 +250,14 @@ function setupWebRTC(iceServerUrl, iceServerUsername, iceServerCredential) {
249250
isSpeaking = false
250251
lastSpeakTime = new Date()
251252
document.getElementById('stopSpeaking').disabled = true
253+
} else if (e.data.includes("EVENT_TYPE_SESSION_END")) {
254+
if (document.getElementById('autoReconnectAvatar').checked && !userClosedSession && !isReconnecting) {
255+
// Session disconnected unexpectedly, need reconnect
256+
console.log(`[${(new Date()).toISOString()}] The WebSockets got disconnected, need reconnect.`)
257+
isReconnecting = true
258+
connectAvatar()
259+
createSpeechRecognizer()
260+
}
252261
}
253262
}
254263
})
@@ -477,6 +486,8 @@ window.startSession = () => {
477486
setupWebSocket()
478487
}
479488

489+
userClosedSession = false
490+
480491
createSpeechRecognizer()
481492
if (document.getElementById('useLocalVideoForIdle').checked) {
482493
document.getElementById('startSession').disabled = true
@@ -532,6 +543,7 @@ window.stopSession = () => {
532543
document.getElementById('localVideo').hidden = true
533544
}
534545

546+
userClosedSession = true // Indicating the session was closed by user on purpose, not due to network issue
535547
disconnectAvatar(true)
536548
}
537549

0 commit comments

Comments
 (0)