first commit
This commit is contained in:
		
						commit
						3ebdf2931b
					
				
							
								
								
									
										20132
									
								
								duix/duix.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20132
									
								
								duix/duix.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										379
									
								
								simple.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										379
									
								
								simple.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,379 @@ | |||||||
|  | <!DOCTYPE html> | ||||||
|  | <html lang="zh"> | ||||||
|  | 
 | ||||||
|  | <head> | ||||||
|  |   <meta charset="UTF-8" /> | ||||||
|  |   <meta http-equiv="X-UA-Compatible" content="IE=edge" /> | ||||||
|  |   <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" /> | ||||||
|  |   <meta http-equiv="Pragma" content="no-cache" /> | ||||||
|  |   <meta http-equiv="expires" content="0" /> | ||||||
|  |   <meta name="viewport" content="width=device-width,initial-scale=1.0,maximu-scale=1.0,user-scalable=no" /> | ||||||
|  |   <title>Duix Sdk Simple Example</title> | ||||||
|  |   <style> | ||||||
|  |     :root { | ||||||
|  |       --primary-100: #FF7F50; | ||||||
|  |       --primary-200: #dd6236; | ||||||
|  |       --primary-300: #8f1e00; | ||||||
|  |       --accent-100: #8B4513; | ||||||
|  |       --accent-200: #ffd299; | ||||||
|  |       --text-100: #000000; | ||||||
|  |       --text-200: #2c2c2c; | ||||||
|  |       --bg-100: #F7EEDD; | ||||||
|  |       --bg-200: #ede4d3; | ||||||
|  |       --bg-300: #c4bcab; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     html, | ||||||
|  |     body { | ||||||
|  |       margin: 0; | ||||||
|  |       padding: 0; | ||||||
|  |       font-family: 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; | ||||||
|  |       background: var(--bg-100); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     .modal { | ||||||
|  |       position: fixed; | ||||||
|  |       left: 0; | ||||||
|  |       top: 0; | ||||||
|  |       width: 100vw; | ||||||
|  |       height: 100vh; | ||||||
|  |       overflow: auto; | ||||||
|  |       background: rgba(247, 238, 221, 0.95); | ||||||
|  |       display: flex; | ||||||
|  |       align-items: center; | ||||||
|  |       justify-content: center; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     .modal-content { | ||||||
|  |       background-color: transparent; | ||||||
|  |       padding: 20px; | ||||||
|  |       width: auto; | ||||||
|  |       border-radius: 0; | ||||||
|  |       box-shadow: none; | ||||||
|  |       animation: fadeIn 0.3s ease-out; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @keyframes fadeIn { | ||||||
|  |       from { opacity: 0; transform: translateY(-20px); } | ||||||
|  |       to { opacity: 1; transform: translateY(0); } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     .container { | ||||||
|  |       width: 100vw; | ||||||
|  |       height: 100vh; | ||||||
|  |       background: var(--bg-200); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     .item { | ||||||
|  |       margin-bottom: 20px; | ||||||
|  |       display: flex; | ||||||
|  |       flex-direction: column; | ||||||
|  |       align-items: center; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     .item>span { | ||||||
|  |       font-size: 24px; | ||||||
|  |       font-weight: 600; | ||||||
|  |       margin-bottom: 20px; | ||||||
|  |       color: var(--text-200); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     .input { | ||||||
|  |       background: var(--bg-100); | ||||||
|  |       height: 48px; | ||||||
|  |       border: 1px solid var(--accent-100); | ||||||
|  |       outline: none; | ||||||
|  |       border-radius: 8px; | ||||||
|  |       padding: 0 16px; | ||||||
|  |       width: 100%; | ||||||
|  |       box-sizing: border-box; | ||||||
|  |       font-size: 16px; | ||||||
|  |       transition: all 0.3s ease; | ||||||
|  |       color: var(--text-200); | ||||||
|  |       margin-bottom: 10px; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     .input:focus { | ||||||
|  |       border-color: var(--primary-100); | ||||||
|  |       box-shadow: 0 0 0 3px var(--accent-200); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     .btn { | ||||||
|  |       border: none; | ||||||
|  |       border-radius: 8px; | ||||||
|  |       height: 48px; | ||||||
|  |       background: var(--primary-100); | ||||||
|  |       color: white; | ||||||
|  |       cursor: pointer; | ||||||
|  |       font-size: 16px; | ||||||
|  |       font-weight: 600; | ||||||
|  |       transition: all 0.3s ease; | ||||||
|  |       padding: 0 24px; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     .btn:hover { | ||||||
|  |       transform: translateY(-2px); | ||||||
|  |       box-shadow: 0 6px 8px rgba(0,0,0,0.15); | ||||||
|  |       background: var(--primary-200); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     .btn-config { | ||||||
|  |       position: absolute; | ||||||
|  |       top: 20px; | ||||||
|  |       right: 20px; | ||||||
|  |       background: var(--accent-100); | ||||||
|  |       color: white; | ||||||
|  |       border: none; | ||||||
|  |       border-radius: 50%; | ||||||
|  |       width: 40px; | ||||||
|  |       height: 40px; | ||||||
|  |       font-size: 20px; | ||||||
|  |       cursor: pointer; | ||||||
|  |       transition: all 0.3s ease; | ||||||
|  |       transform: rotate(0deg); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     .btn-config:hover { | ||||||
|  |       transform: rotate(90deg); | ||||||
|  |       background: var(--primary-200); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     .btn:active { | ||||||
|  |       transform: translateY(0); | ||||||
|  |     } | ||||||
|  |   </style> | ||||||
|  |   <script src="https://cdn.bootcss.com/eruda/1.3.2/eruda.min.js"></script> | ||||||
|  |   <script>eruda.init()</script> | ||||||
|  |   <script src="./duix/duix.js"></script> | ||||||
|  | </head> | ||||||
|  | 
 | ||||||
|  | <body> | ||||||
|  |   <!-- 数字人容器 --> | ||||||
|  |   <div class="container"></div> | ||||||
|  | 
 | ||||||
|  |   <div id="modal" class="modal"> | ||||||
|  |     <div class="modal-content" style="text-align: center; padding: 20px; position: relative;"> | ||||||
|  |       <button id="configBtn" class="btn-config" onclick="toggleConfig()">⚙️</button> | ||||||
|  |       <div id="configSection" style="display: none;"> | ||||||
|  |         <!-- <div style="margin-bottom: 8px; width: 100%; text-align: left; color: var(--text-200);">签名密钥</div> --> | ||||||
|  |         <input class="input" style="display: none;" id="sign" placeholder="请输入您的签名密钥" value="" /> | ||||||
|  |         <input class="input" style="display: none;" id="audio" placeholder="音色" value="" /> | ||||||
|  |         <div style="margin-bottom: 8px; width: 100%; text-align: left; color: var(--text-200);">性别</div> | ||||||
|  |         <select class="input" id="gender" style="margin-bottom: 16px;"> | ||||||
|  |           <option value="male" selected>男</option> | ||||||
|  |           <option value="female" >女</option> | ||||||
|  |         </select> | ||||||
|  |         <div style="margin-bottom: 8px; width: 100%; text-align: left; color: var(--text-200);">会话ID</div> | ||||||
|  |         <input class="input" id="conversationId" placeholder="请输入会话ID" value="1920410565458886658" title="请输入会话ID" /> | ||||||
|  |       </div> | ||||||
|  |       <button id="start" onclick="init()" class="btn" style="width: 200px; margin: 20px auto 0;"> | ||||||
|  |         <span>开始智能会话</span> | ||||||
|  |       </button> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  |   <script> | ||||||
|  |     const duix = new DUIX() | ||||||
|  | 
 | ||||||
|  |     const sex = { | ||||||
|  |       "male": "1920410565458886658", | ||||||
|  |       "female": "1933000305591988225" | ||||||
|  |     } | ||||||
|  |     let conversationL = "" | ||||||
|  |     const sex_audio = { | ||||||
|  |       "male": "gongzheng-v2", | ||||||
|  |       "female": "presenter_female" | ||||||
|  |     } | ||||||
|  |     const audio = document.getElementById('audio') | ||||||
|  |     // Add event listener for gender selection | ||||||
|  |     document.getElementById('gender').addEventListener('change', function(e) { | ||||||
|  |       const selectedGender = e.target.value; | ||||||
|  |       const conversationIdInput = document.getElementById('conversationId'); | ||||||
|  |        | ||||||
|  |       conversationIdInput.value = sex[selectedGender]; | ||||||
|  |       audio.value = sex_audio[selectedGender] | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     // Set initial conversation ID based on default gender | ||||||
|  |     document.addEventListener('DOMContentLoaded', function() { | ||||||
|  |       const genderSelect = document.getElementById('gender'); | ||||||
|  |       const conversationIdInput = document.getElementById('conversationId'); | ||||||
|  |       conversationIdInput.value = sex[genderSelect.value]; | ||||||
|  |       audio.value = sex_audio[genderSelect.value] | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     async function getToken() { | ||||||
|  |       try { | ||||||
|  |         const response = await fetch('http://192.168.2.183:8080/token', { | ||||||
|  |           method: 'POST', | ||||||
|  |           headers: { | ||||||
|  |             'Content-Type': 'application/json', | ||||||
|  |           } | ||||||
|  |         }); | ||||||
|  |         const data = await response.json(); | ||||||
|  |         return data.token; | ||||||
|  |       } catch (error) { | ||||||
|  |         console.error('Error getting token:', error); | ||||||
|  |         throw error; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function toggleConfig() { | ||||||
|  |       const configSection = document.getElementById('configSection'); | ||||||
|  |       if (configSection.style.display === 'none') { | ||||||
|  |         configSection.style.display = 'block'; | ||||||
|  |       } else { | ||||||
|  |         configSection.style.display = 'none'; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     async function init() { | ||||||
|  |       let sign = document.querySelector('#sign').value; | ||||||
|  |       const conversationId = document.querySelector('#conversationId').value; | ||||||
|  | 
 | ||||||
|  |       if (!sign) { | ||||||
|  |         try { | ||||||
|  |           sign = await getToken(); | ||||||
|  |           document.querySelector('#sign').value = sign; | ||||||
|  |         } catch (error) { | ||||||
|  |           alert('获取token失败,请重试'); | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if (!conversationId) { | ||||||
|  |         return alert('会话ID不能为空'); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       duix.on('error', data => { | ||||||
|  |         console.error(data) | ||||||
|  |       }) | ||||||
|  |       duix.on('intialSucccess', () => { | ||||||
|  |         console.info('intialSucccess') | ||||||
|  |         // 此时初始化成功,可调用start | ||||||
|  |         duix.start({ conversationId, openAsr: true, useActSection: true }).then(res => { | ||||||
|  |           console.info('start', res) | ||||||
|  |         }) | ||||||
|  |       }) | ||||||
|  |       duix.on('bye', (data) => { | ||||||
|  |         console.info('bye', data) | ||||||
|  |       }) | ||||||
|  | 
 | ||||||
|  |       duix.on('progress', progress => { | ||||||
|  |         console.info('progress', progress) | ||||||
|  |       }) | ||||||
|  |       duix.on('show', () => { | ||||||
|  |         console.info('show') | ||||||
|  |         // 此时可确认视频已 | ||||||
|  |         document.querySelector('#modal').style.display = "none" | ||||||
|  |       }) | ||||||
|  |       duix.on('openAsrSuccess', () => { | ||||||
|  |         console.info('openAsrSuccess') | ||||||
|  |       }) | ||||||
|  |       duix.on('asrClose', () => { | ||||||
|  |         console.info('asrClose') | ||||||
|  |       }) | ||||||
|  |       // duix.on('speakStart', (data) => { | ||||||
|  |       //   console.info('speakStart', data) | ||||||
|  |       // }) | ||||||
|  |       // duix.on('speakEnd', (data) => { | ||||||
|  |       //   console.info('speakEnd', data) | ||||||
|  |       // }) | ||||||
|  |       duix.on('speakSection', (data) => { | ||||||
|  |         console.info('speakSection', data) | ||||||
|  |       }) | ||||||
|  |       duix.on('speakError', (data) => { | ||||||
|  |         console.info('speakError', data) | ||||||
|  |       }) | ||||||
|  |       duix.on('asrResult', async (data) => { | ||||||
|  |         console.info('asrResult', data); | ||||||
|  |         duix.break() | ||||||
|  |         // if (data == "你好") { | ||||||
|  |           try { | ||||||
|  |             const response = await fetch('http://192.168.2.183:8080/chat', { | ||||||
|  |               method: 'POST', | ||||||
|  |               headers: { | ||||||
|  |                 'Content-Type': 'application/json', | ||||||
|  |               }, | ||||||
|  |               body: JSON.stringify({ | ||||||
|  |                 query: data, | ||||||
|  |                 response_mode: 'streaming', | ||||||
|  |                 user: 'SYS002', | ||||||
|  |                 conversation_id: conversationL, | ||||||
|  |                 audio: audio.value | ||||||
|  |               }) | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|  |             const reader = response.body.getReader(); | ||||||
|  |             const decoder = new TextDecoder(); | ||||||
|  |             let fullAnswer = ''; | ||||||
|  |             let triggered = false; | ||||||
|  | 
 | ||||||
|  |             while (true) { | ||||||
|  |               const { value, done } = await reader.read(); | ||||||
|  |               if (done) break; | ||||||
|  | 
 | ||||||
|  |               const chunk = decoder.decode(value); | ||||||
|  |               const lines = chunk.split('\n'); | ||||||
|  | 
 | ||||||
|  |               for (const line of lines) { | ||||||
|  |                 if (line.startsWith('data:')) { | ||||||
|  |                   const responseData = JSON.parse(line.slice(5).trim()); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |                   if (responseData.audio_data) { | ||||||
|  |                     conversationL = responseData.conversation_id | ||||||
|  |                     duix.speak({ | ||||||
|  |                       content: responseData.answer, | ||||||
|  |                       audio: responseData.audio_data | ||||||
|  |                     }) | ||||||
|  |                      | ||||||
|  |                   } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |                   // Handle end of stream | ||||||
|  |                   if (responseData.isEnd) { | ||||||
|  |                     break; | ||||||
|  |                   } | ||||||
|  |                 } | ||||||
|  |               } | ||||||
|  |             } | ||||||
|  |           } catch (error) { | ||||||
|  |             console.error('Error in chat API:', error); | ||||||
|  |           } | ||||||
|  |         // } | ||||||
|  | 
 | ||||||
|  |         // test = [ | ||||||
|  |         //   'https://p3-bot-sign.byteimg.com/tos-cn-i-v4nquku3lp/0f1be92489b849f3b7568e9b17334e42.wav~tplv-v4nquku3lp-image.image?rk3s=68e6b6b5&x-expires=1752754758&x-signature=rXa5LFcZttKGZpHMVIP6SgZTsRI%3D','https://p6-bot-sign.byteimg.com/tos-cn-i-v4nquku3lp/9898244b02be4765a964cf4b3d4afcd0.wav~tplv-v4nquku3lp-image.image?rk3s=68e6b6b5&x-expires=1752754726&x-signature=%2BbIrCv%2B5yAUxZvNqBURCnSRVqWo%3D','https://p9-bot-sign.byteimg.com/tos-cn-i-v4nquku3lp/4bffded0446648a2aef1d2d7e59ddd0c.wav~tplv-v4nquku3lp-image.image?rk3s=68e6b6b5&x-expires=1752754642&x-signature=E5Dr2R%2Fhd%2Ft7K593ka393OlCPNg%3D'] | ||||||
|  |         // for (let index = 0; index < test.length; index++) { | ||||||
|  |         //   const element = test[index]; | ||||||
|  |         //   duix.speak({content: "我会尽量帮助您", audio: element}) | ||||||
|  |            | ||||||
|  |         // } | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       duix.on('report', data => { | ||||||
|  |         // console.info('report', data) | ||||||
|  |       }) | ||||||
|  |       duix.on('speakEnd', async(data) => { | ||||||
|  |         console.info('公证speakEnd: ', data) | ||||||
|  | 
 | ||||||
|  |       }) | ||||||
|  |       duix.init({ | ||||||
|  |         sign, | ||||||
|  |         containerLable: '.container' | ||||||
|  |       }).then(data => { | ||||||
|  |         console.info('init', data) | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     window.addEventListener('beforeunload', function(event) { | ||||||
|  |       if (duix) { | ||||||
|  |         duix.destroy() | ||||||
|  |         duix.stop() | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |   </script> | ||||||
|  | </body> | ||||||
|  | 
 | ||||||
|  | </html> | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Song367
						Song367