Spaces:
Running
Running
| window.HELP_IMPROVE_VIDEOJS = false; | |
| // var INTERP_BASE = "./static/interpolation/stacked"; | |
| var NUM_INTERP_FRAMES = 240; | |
| var interp_images = []; | |
| // function preloadInterpolationImages() { | |
| // for (var i = 0; i < NUM_INTERP_FRAMES; i++) { | |
| // var path = INTERP_BASE + '/' + String(i).padStart(6, '0') + '.jpg'; | |
| // interp_images[i] = new Image(); | |
| // interp_images[i].src = path; | |
| // } | |
| // } | |
| // function setInterpolationImage(i) { | |
| // var image = interp_images[i]; | |
| // image.ondragstart = function() { return false; }; | |
| // image.oncontextmenu = function() { return false; }; | |
| // $('#interpolation-image-wrapper').empty().append(image); | |
| // } | |
| $(document).ready(function() { | |
| // Check for click events on the navbar burger icon | |
| $(".navbar-burger").click(function() { | |
| // Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu" | |
| $(".navbar-burger").toggleClass("is-active"); | |
| $(".navbar-menu").toggleClass("is-active"); | |
| }); | |
| var options = { | |
| slidesToScroll: 1, | |
| slidesToShow: 3, | |
| loop: true, | |
| infinite: true, | |
| autoplay: false, | |
| autoplaySpeed: 3000, | |
| } | |
| // Initialize all div with carousel class | |
| var carousels = bulmaCarousel.attach('.carousel', options); | |
| // Loop on each carousel initialized | |
| for(var i = 0; i < carousels.length; i++) { | |
| // Add listener to event | |
| carousels[i].on('before:show', state => { | |
| console.log(state); | |
| }); | |
| } | |
| // Access to bulmaCarousel instance of an element | |
| var element = document.querySelector('#my-element'); | |
| if (element && element.bulmaCarousel) { | |
| // bulmaCarousel instance is available as element.bulmaCarousel | |
| element.bulmaCarousel.on('before-show', function(state) { | |
| console.log(state); | |
| }); | |
| } | |
| /*var player = document.getElementById('interpolation-video'); | |
| player.addEventListener('loadedmetadata', function() { | |
| $('#interpolation-slider').on('input', function(event) { | |
| console.log(this.value, player.duration); | |
| player.currentTime = player.duration / 100 * this.value; | |
| }) | |
| }, false);*/ | |
| // preloadInterpolationImages(); | |
| // $('#interpolation-slider').on('input', function(event) { | |
| // setInterpolationImage(this.value); | |
| // }); | |
| // setInterpolationImage(0); | |
| // $('#interpolation-slider').prop('max', NUM_INTERP_FRAMES - 1); | |
| bulmaSlider.attach(); | |
| }) | |
| // 全局初始化 | |
| // connect ws | |
| var ws = null; | |
| var recorder = null; | |
| var isRecording = false; | |
| var vc_enabled = location.search.split('vc=')[1] == '1' ? true : false; | |
| var text = '' | |
| var audio_base64 = null; | |
| Recorder.CLog = function(){} //update | |
| var wave = Recorder.WaveView({elem:"#waveform"}); //创建wave对象,写这里面浏览器妥妥的; | |
| const audioPlayer = document.getElementById('audioPlayer'); | |
| const waveformDiv = document.getElementById('waveform'); | |
| const resultsDiv = document.getElementById('results'); | |
| const llasaLoading = document.getElementById('llasaLoading'); | |
| const container = document.getElementById('llasa'); | |
| // sent text element | |
| function createSentMessageElement(message) { | |
| const sentDiv = document.createElement('div'); | |
| sentDiv.id = 'sent'; | |
| sentDiv.setAttribute('class', 'd-flex flex-row justify-content-end mb-2 pt-1 text-start'); | |
| const sentMessageP = document.createElement('p'); | |
| sentMessageP.setAttribute('class', 'sent-message small p-2 me-2 mb-1 text-white rounded-3 bg-primary'); | |
| sentMessageP.textContent = message['value']; | |
| sentMessageP.id = message['cid'] | |
| const imageDiv = document.createElement('div'); | |
| const senderImage = document.createElement('img'); | |
| senderImage.setAttribute('src', './images/user.png'); | |
| senderImage.setAttribute('class', 'rounded-4'); | |
| senderImage.setAttribute('alt', 'avatar 1'); | |
| senderImage.setAttribute('height', '30'); | |
| senderImage.setAttribute('width', '30'); | |
| imageDiv.appendChild(senderImage); | |
| sentDiv.appendChild(sentMessageP); | |
| sentDiv.appendChild(imageDiv); | |
| return sentDiv; | |
| } | |
| // Function to add a new sent message to the DOM | |
| function addSentMessageToDOM(message) { | |
| const sentDiv = createSentMessageElement(message); | |
| resultsDiv.appendChild(sentDiv); | |
| } | |
| function createRecieveMessageElement(message) { | |
| const responseDiv = document.createElement("div"); | |
| responseDiv.id = "response"; | |
| responseDiv.classList.add("d-flex", "flex-row", "justify-content-start", "pt-2", "mb-2"); | |
| const imageDiv = document.createElement('div') | |
| const avatarImg = document.createElement("img"); | |
| avatarImg.src = "../../images/gpt.png"; | |
| avatarImg.classList.add("rounded-4"); | |
| avatarImg.alt = "avatar 1"; | |
| avatarImg.height = 30; | |
| avatarImg.width = 30; | |
| imageDiv.appendChild(avatarImg) | |
| responseDiv.appendChild(imageDiv); | |
| const responseMessageP = document.createElement("p"); | |
| responseMessageP.id = message['cid']; | |
| responseMessageP.classList.add("small", "p-2", "ms-2", "mb-1", "rounded-3"); | |
| responseMessageP.style.backgroundColor = "#f5f6f7"; | |
| responseMessageP.innerText = message['value']; | |
| responseDiv.appendChild(responseMessageP); | |
| return responseDiv; | |
| } | |
| // Function to add a new recieve message to the DOM | |
| function addRecieveMessageToDOM(message) { | |
| const reciDiv = createRecieveMessageElement(message); | |
| resultsDiv.appendChild(reciDiv); | |
| resultsDiv.scrollTo(0, resultsDiv.scrollHeight); | |
| } | |
| function createSentAudioMessageElement(message) { | |
| const sentDiv = document.createElement('div'); | |
| sentDiv.id = 'sent'; | |
| sentDiv.className = 'd-flex flex-row justify-content-end mb-2 pt-1 text-start'; | |
| const audio = document.createElement('audio'); | |
| audio.controls = true; | |
| audio.id = message['cid']; | |
| audio.className = 'sent-message p-2 me-2 bg-primagry'; | |
| // audio.style.width = '200px'; | |
| const sourceElement = document.createElement('source'); | |
| sourceElement.src = message['value']; | |
| // sourceElement.type = 'audio/ogg'; | |
| const unsupportedText = document.createTextNode('Your browser does not support the audio element.'); | |
| audio.appendChild(sourceElement); | |
| audio.appendChild(unsupportedText); | |
| const imageDiv = document.createElement('div') | |
| const image = document.createElement('img'); | |
| image.src = '../../images/user.png'; | |
| image.id = 'sender-image'; | |
| image.className = 'rounded-4'; | |
| image.alt = 'avatar 1'; | |
| image.height = 30; | |
| image.width = 30; | |
| imageDiv.appendChild(image); | |
| sentDiv.appendChild(audio); | |
| sentDiv.appendChild(imageDiv); | |
| return sentDiv; | |
| } | |
| // Function to add a new audio sent message to the DOM | |
| function addAudioSentMessageToDOM(message) { | |
| const sentDiv = createSentAudioMessageElement(message); | |
| resultsDiv.appendChild(sentDiv); | |
| resultsDiv.scrollTo(0, resultsDiv.scrollHeight); | |
| } | |
| // stream update response | |
| function updateResponse(cID, answer) { | |
| const responseP = document.getElementById("a_text_" + cID); | |
| responseP.innerText = answer; | |
| } | |
| // connect ws | |
| window.onload = async () => { | |
| await connect(); | |
| } | |
| async function connect() { | |
| // url = ((window.location.protocol === "https:") ? "wss://" : "ws://") + window.location.host + "/api"; | |
| url = "wss://demo.linksoul.ai/alm/api"; | |
| ws = new WebSocket(url); | |
| ws.onopen = function (e) { | |
| console.log('握手成功'); | |
| if (ws.readyState == 1) { //ws进入连接状态,则每隔500毫秒发送一包数据 | |
| console.log('连接状态成功'); | |
| // resultsDiv.style.display = ''; | |
| // llasaLoading.style.display = 'none'; | |
| container.style.opacity = 1; | |
| llasaLoading.style.display = 'none'; | |
| } | |
| }; | |
| ws.onmessage = function (e) { | |
| console.log(e['data']) | |
| var response = JSON.parse(e['data']); | |
| if(response["action"] == "qa"){ | |
| // nothing to do | |
| if(response['msg'] == 'ok') { | |
| console.log(response["data"]) | |
| updateResponse(response['data']['cid'], response['data']['answer']) | |
| }else{ | |
| console.log(response['msg']); | |
| } | |
| } | |
| } | |
| ws.onerror = function (err) { | |
| console.info('ws error: '+err) | |
| } | |
| ws.onclose=function(e){ | |
| console.info('ws close: '+e); | |
| }; | |
| } | |
| const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay)) | |
| const submitTextButton = document.getElementById('send_button'); | |
| submitTextButton.onclick = async () => { | |
| await sendMessage(); | |
| } | |
| async function sendMessage() { | |
| if(ws == null || ws.readyState != 1) { | |
| // alert('服务未连接,请刷新页面'); | |
| // return; | |
| await connect(); | |
| await sleep(800); | |
| } | |
| var userTextDiv = document.getElementById('user-text'); | |
| text = userTextDiv.value | |
| userTextDiv.value = '' | |
| console.log('user input text', text); | |
| console.log('user input audio', audio_base64); | |
| if (text.length == 0 && audio_base64 == null) return; | |
| var cid = crypto.randomUUID(); | |
| if (text.length > 0) { | |
| addSentMessageToDOM({ | |
| 'cid': "q_text_" + cid, | |
| 'from': 'human', | |
| 'value': text, | |
| 'type': 'text' | |
| }); | |
| } | |
| if (audio_base64 != null) { | |
| addAudioSentMessageToDOM({ | |
| 'cid': "q_audio_" + cid, | |
| 'from': 'human', | |
| 'value': audio_base64, | |
| 'type': 'audio' | |
| }); | |
| } | |
| ws.send(JSON.stringify({"action": "qa", "data":{"cid": cid, "text": text, "audio": audio_base64, "vc_enabled": vc_enabled}})); | |
| addRecieveMessageToDOM({ | |
| 'cid': "a_text_" + cid, | |
| 'from': 'gpt', | |
| 'value': '', | |
| 'type': 'text' | |
| }) | |
| if (text != '') { | |
| text = ''; | |
| } | |
| if (audio_base64 != null) { | |
| audio_base64 = null; | |
| // 清空缓存区 | |
| audioPlayer.src = ''; | |
| audioPlayer.style.display = 'none'; | |
| } | |
| } | |
| function blobToDataURI(blob, callback) { | |
| var reader = new FileReader(); | |
| reader.onload = function (e) { | |
| callback(e.target.result); | |
| } | |
| reader.readAsDataURL(blob); | |
| } | |
| const resetButton = document.getElementById('delete_button'); | |
| resetButton.onclick = () => { | |
| clear(); | |
| resultsDiv.innerHTML = ''; | |
| audioPlayer.src = ''; | |
| audioPlayer.style.display = 'none'; | |
| waveformDiv.style.display = 'none'; | |
| } | |
| function clear() {//update | |
| ws.send(JSON.stringify({"action": "clear"})); | |
| } | |
| const recordButton = document.getElementById('start_button'); | |
| recordButton.onclick = () => { | |
| record_audio(); | |
| } | |
| function record_audio() {//update | |
| if (!isRecording) { | |
| recorder = Recorder({type:"mp3", sampleRate:44100, bitRate:128, onProcess:function(buffers,powerLevel,bufferDuration,bufferSampleRate,newBufferIdx,asyncEnd){ | |
| wave&&wave.input(buffers[buffers.length-1],powerLevel,bufferSampleRate); | |
| }}); | |
| recorder.open(function(){ | |
| isRecording = true; | |
| recorder.start(); | |
| audioPlayer.style.display = 'none'; | |
| waveformDiv.style.display = ''; | |
| recordButton.style.filter = "invert(18%) sepia(66%) saturate(5808%) hue-rotate(338deg) brightness(91%) contrast(125%)"; | |
| },function(msg,isUserNotAllow){ | |
| alert("请允许浏览器获取麦克风录音权限"); | |
| console.log((isUserNotAllow?"UserNotAllow, ":"")+"无法录音:"+msg); | |
| }); | |
| }else { | |
| isRecording = false; | |
| recorder.stop(function(blob, duration){ | |
| audioPlayer.style.display = ''; | |
| waveformDiv.style.display = 'none'; | |
| blobToDataURI(blob, function(audio_base64_data){ | |
| audio_base64 = audio_base64_data; | |
| // document.getElementById('audioPlayer').src = URL.createObjectURL(blob); | |
| recorder.close(); | |
| recorder=null; | |
| // 移动 audio 到暂存区 | |
| audioPlayer.src = audio_base64; | |
| // sendMessage(); | |
| }); | |
| },function(msg){ | |
| alert("录音失败"); | |
| console.log("录音失败:"+msg); | |
| recorder.close(); | |
| recorder=null; | |
| }); | |
| recordButton.style.filter = null; | |
| } | |
| } | |