您好!欢迎来到爱源码

爱源码

热门搜索: 抖音快手短视频下载   

vue+web socket+wavesurfjs实现H5聊天对话交互 [源码分享]

  • 时间:2022-10-25 01:48 编辑: 来源: 阅读:303
  • 扫一扫,手机访问
摘要:vue+web socket+wavesurfjs实现H5聊天对话交互 [源码分享]
当简介与语音合成、语义分析、机器翻译等算法的后台交互时,页面可以设计得更人性化、更友好。 我们采用类似聊天对话的实现,效果如下:智能客服(输入文本,返回引擎求解的文本结果)和智能客服对话语音合成(输入文本,返回文本,合成音频)。语音合成如上图所示。返回文本后,将返回合成的音频。 对话泡泡中嵌入了音频按钮,点击即可播放。 语音识别(在页面上录制和发送语音,并在页面上实时显示识别的文本结果)在页面上录制和发送音频实现了功能和技术要点。1.对话流页面与后台的交互是基于WebSocket的实时交互,所以采用WebSocket协议代替HTTP请求,使得后台推回的消息可以实时显示在页面上。 WebSocket的返回是排队乱序的,后续解决方案中需要注意这一点,后面会讲到。 2.调用设施麦克风进行音频录制、转码和添加头,基于WebAudio、WaveSurferJS等实现音频解算和绘图。3.基于Vue 4实现响应式页面。优化CSS3+Canvas+JS的交互效果。记录音频CSS动画效果聊天记录自动滚动。下面给出了一些实现代码。 集成WebSocket我们的聊天组件是一个el抽屉,在页面的一侧打开。Vue组件在打开时会被创建,在关闭时会被销毁。 在组件中引入WebSocket,管理其打开、关闭、消息接收和发送,使其生命周期与组件保持一致(打开窗口时创建ws连接,关闭窗口时关闭连接,避免与后端连接过多。 )created(){ if(web socket = = ' undefined '){ alert('您的浏览器不支持socket')} else {//实例化socket this . socket = new web socket(this . socket server path)//监听套接字连接this.socket.onopen = this.open //监听套接字错误消息this . socket . on error = this.error//监听套接字消息this . socket . on message = this . on message this . socket = this . close } } destroyed(){ this . socket . close()}如上所述,绑定web 打开浏览器控制台,选择指定的选项卡,便于监控和查看WebSocket连接。 在c中,音频录制和采集,来自浏览器的音频和视频采集是基于Web实时通信的API(简称WebRTC)。 通过WebRTC的getUserMedia实现获取一个MediaStream对象,并将其与AudioContext关联以获取音频。 可以参考RecorderJS的实现:Matt Diamond/Recorder JS/blob/master/examples/examples _ simple _ export wav . html if(navigator . getuser media){ navigator . getuser media({ audio:true },//仅启用音频函数(stream){ var context = new(window . webkitaudiocontext | | window . audio context)()var audio input = context . createmediastreamsource(stream)var Recorder = new Recorder(audio input)}、Function(error){ switch(error . code | | )break case“not _ supported _ error”:case“not supported error”:thrower error(' Browser不支持硬件设施。 )break case“mandatory _ unsatisfied _ error”:case“mandatory yunsatifiederror”:thrower error('找不到指定的硬件设施。 )Break Default: ThrowerError('无法打开麦克风。 异常:“+(error . code | | error . name))break } } } else { thrower error('当前浏览器不支持录音功能。 )}注意:如果navigator.getUserMedia得到未定义,是Chrome浏览器的安全策略导致的,需要通过https请求或配置浏览器。地址:chrome://flags/# unsafe-treat-insert-origin-as-secure。浏览器收集的音频是PCM格式(PCM),所以在页面上播放之前需要给音频添加一个头。 注意采样率、采样频率、通道数等。必须与采样相同,否则添加头后的音频无法解码。 参见matt diamond/recorder js/blob/master/src/recorder . js中的exportWav方法。 服务中对接的语音识别引擎是实时转录引擎,即不是录音后发送,而是边录音边编码发送。 使用onaudioprocess方法监听语音输入:RecorderJS onaudioprocess方法参考这个实现,我们可以从缓冲区获取录制的数据,进行编码压缩,然后通过WebSocket发送。 Vue组件设计和业务实现分析页面的业务逻辑,将代码拆分成两个组件:ChatDialog.vue聊天对话页面,根据输入类型分为文字输入和语音输入。 ChatRecord.vue聊天记录组件,根据发送方(自己或发送方系统)显示左/右气泡,显示文字、音频等。根据内容。 ChatDialog是ChatRecord的父组件。它遍历ChatDialog中的chatList对象(数组),并将chatList中的项目注入到ChatRecord中。 & ltdiv class="chat-list " >& ltdiv v-for="(item,index)in chat list ":key = " index " class = " msg-wrapper " >& ltchat-record ref = " chat record ":data = " item " @ show JSON = " showJsonDialog " & gt;& lt/chat-record & gt;& lt/div & gt;& ltdiv id = " msg _ end " style = " height:0px;溢出:隐藏" & gt& lt/div & gt;& lt/div & gt;& lt/div & gt;至于聊天记录的气泡呈现,和数据类型有很强的相关性。ChatRecord组件只关心数据的求解和呈现,所以我们完全可以忽略收发消息、录音、停止录音、接收音频的逻辑,只要我们想根据数据呈现不同的风格。 这样就充分利用了Vue的响应性:不需要通过代码来控制样式呈现,只需要设计合适的数据格式和样式模板,然后注入不同的数据。 模板:使用v-if控件,可以通过修改聊天列表中对象的内容来改变页面显示。 根据业务需求,ChatRecord可能接收到的数据可以分为以下几类:发送方是本人;文字输入,文字的显示很容易实现,这里就不赘述了。 进入语音加载状态,显示波纹动画和定时。正在使用CSS输入动画,引用地址为https://www . cnblogs . com/lhb 25/p/loading-spinners-animated-with-css3 . html timer使用JS的setInterval方法,录制时长this。record timer = setinterval((){ this。音频持续时间= this。audioduration+0.1},100)停止后清除计时器:clearInterval(this.recordTimer)语音输入完成。根据录制的语音,绘制波纹效果:使用wavesurfer插件绘制真实波形:initwavesurfer () {this。$ next tick(()= >;{ this . wave surfer = wave surfer . create({ container:this。$refs.waveform,height: 20,waveColor: '#3d6fff ',progressColor: 'blue ',backend: 'MediaElement ',mediaControls: false,audioRate: '1 ',fillParent: false,maxCanvasWidth: 500,barWidth: 1,barGap: 2,barHeight: 5,barMinHeight: 3,normalize: true,cursor color:' # 409 eff ' })this . convertaudiotourl(this . wave audio)。然后((RES)= & gt;{ this . wave surfer . load(RES)setTimeout(()= & gt;{ this . audio duration = this . getaudioduration()},100)} })},//将音频转换为url地址ConvertAudioURL(audio){ let blob URL = ' ' if(this . data . send by = = = ' self '){ blo burl = window。URL . createobjecturl(audio)return new Promise((resolve)= & gt;{ resolve(blo burl)})} else { return this . base64 toblob({ b64 data:audio,contentType: 'audio/wav' }) },base64ToBlob({ b64data = ' ',contentType = ' ',slice size = 512 } = { }){ return new Promise((resolve,reject)= & gt;{//使用atob()方法解码数据let byte characters = atob(b 64 data)let byte arrays =[]for(let offset = 0;offset & lt字节字符长度;offset+= slice size){ let slice = byte characters . slice(offset,offset+slice size)let byte numbers =[]for(let I = 0;我& lt切片.长度;++){ byte numbers . push(slice . charcode at(I))}//8位无符号整数值的类型化数组 将内容初始化为0。 //如果无法分配请求的字节数,将引发异常。 byteArrays . push(new uint 8 array(byte numbers))} let result = new Blob(byteArrays,{ type:content type })result = object . assign(result,{//这里一定要解析URL。创建对象URL预览:URL。CreateObject URL (result),Name:` XXX . wav `})resolve(window . URL . CreateObject URL(result)} },发送方为system:only return text:display text only return audio(参考发送方自己的实现)Draw waveform返回text,然后返回text对应的合成音频,显示text和play按钮状态,显示play按钮状态,显示嵌入了audio标签的暂停按钮页面,设置hidden为true使其不显示:< div class="audio-player " >& ltsvg-icon v-if= "!I playing " icon-class = ' play ' @ click = " onclick audio player "/& gt;& ltSVG-icon v-else icon-class = ' pause ' @ click = " onclick audio player "/& gt;& ltaudio:src = " play audio URL " auto start = " true " hidden = " true " ref = " audio player "/& gt;& lt/div & gt;playAudioUrl的生成是指上面生成的wavesurfer的Url。 使用isplay参数记录当前音频的播放状态,使用setTimeout方法自动设置播放按钮在长时间播放音频后播放。 Once音频播放器(){if (this.isplay) {this。$ refs . audio player . pause()this . isplay = false } else {//每次点击时,启动isplay,并将is play设置为false this。$ refs . audio player . current time = 0 this。$ refs . audio player . play()this . isplay = true settimeout(()= >;{//将播放重置为false this.isplay = false},math.ceil (this。$ refs . audio player . duration)* 1000)} },聊天记录自动定位到最后一条:记录id(用scrollIntoView()方法记录每个会话对应的recordId:定义单个会话的Id并在返回的消息中发回,从而建立多个websocket返回的关联关系。 以上都实现了。 主要困难是请求麦克风许可和编码音频。添加wav头时,需要保证采样率和频率与采样一致。


  • 全部评论(0)
资讯详情页最新发布上方横幅
最新发布的资讯信息
【技术支持|常见问题】1556原创ng8文章搜索页面不齐(2024-05-01 14:43)
【技术支持|常见问题】1502企业站群-多域名跳转-多模板切换(2024-04-09 12:19)
【技术支持|常见问题】1126完美滑屏版视频只能显示10个(2024-03-29 13:37)
【技术支持|常见问题】响应式自适应代码(2024-03-24 14:23)
【技术支持|常见问题】1126完美滑屏版百度未授权使用地图api怎么办(2024-03-15 07:21)
【技术支持|常见问题】如何集成阿里通信短信接口(2024-02-19 21:48)
【技术支持|常见问题】算命网微信支付宝产品名称年份在哪修改?风水姻缘合婚配对_公司起名占卜八字算命算财运查吉凶源码(2024-01-07 12:27)
【域名/主机/服务器|】帝国CMS安装(2023-08-20 11:31)
【技术支持|常见问题】通过HTTPs测试Mozilla DNS {免费源码}(2022-11-04 10:37)
【技术支持|常见问题】别告诉我你没看过邰方这两则有思想的创意广告! (2022-11-04 10:37)

联系我们
Q Q:375457086
Q Q:526665408
电话:0755-84666665
微信:15999668636
联系客服
企业客服1 企业客服2 联系客服
86-755-84666665
手机版
手机版
扫一扫进手机版
返回顶部