zoukankan      html  css  js  c++  java
  • layim手机版嵌入app

    感觉记忆力不行了,才做了就有点忘了.先简单做下记录...

    遇到的问题

    • 需要类似微信的语音发送功能
    • 前端发送给后端,在mogodb中用二进制存储.后端取到数据发送给我的也是blob.前端拿到数据就变了.
    • layim列表和聊天面板改写



    解决方法

    ** 以微信语音发送的方式处理语音发送**

    在layim手机版本中没有语音发送的具体接口,但是存在一个扩展tool(),layim的pc端发送语音是直接发送一个线上url.但是这里需要使用手机录音.
    接下来是使用手机录音

    在layim的聊天模板中新增一个隐藏按钮,用于自定义手机的touch事件.

    监听layim的一个扩展

    layim.on('tool(audio)', function(insert, send) {
                $("#recordBtn").toggleClass('on'); // 点击显示隐藏录音按钮
              });
    

    layim-mobile.js内部自定义了一个监听,以便在外部获取到录音按钮

    // 自定义一个监听
        var wch_listener = function() {
          wch_event = new CustomEvent('wch_listener', {
            detail:{
              name: 'wch',
              audioBtn: othis.parents('.layui-m-layer').siblings('.layui-m-layer').find('#recordBtn'),
              sendAudio: sendAudio // 发送消息的函数
            }
          });
           window.dispatchEvent(wch_event); // 显式触发
        }
    

    监听录音

    //监听自定义工具栏--录音的点击
        window.addEventListener('wch_listener', function(event) {
    // 如果是CustomEvent,传入的数据在event.detail中
                if (navigator.mediaDevices.getUserMedia) {
                  console.log('getUserMedia supported.');
                  var constraints = {
                    audio: true
                  };
                  var chunks = [];
                  var onSuccess = function(stream) {
                    var mediaRecorder = new MediaRecorder(stream),
                      to = '',
                      recordStartTime = '',
                      recordendTime = '',
                      startY, endY,
                      recordedTime = 0,
                      interval;
    
                    event.detail.audioBtn.on({
                      touchstart: function(e) {
                        var othis = this;
                        to = JSON.parse(decodeURIComponent($(this).parents('.layim-chat-send').siblings('.layim-chat-tool').data('json')));
                        mediaRecorder.start();
                        startY = e.touches[0].pageY;
                        $(othis).html('0S, '+i18n.t('m.chat_0042')) // 松开发送
                        interval = setInterval(function() {
                            recordedTime++;
                            $(othis).html(recordedTime + 'S, '+i18n.t('m.chat_0042')) // 松开发送
                            if(recordedTime >= 20) {
                              clearInterval(interval);
                              mediaRecorder.stop();
                              $(this).html(i18n.t('m.chat_0041')) // 按住录音
                              console.log("recorder stopped");
                            }
                          }, 1000)
                        recordStartTime = new Date().getTime();
                        console.log("recorder started");
                      },
                      touchmove: function(e) {
                        if(e.changedTouches[0].pageY- startY  >= 100 || e.changedTouches[0].pageY - startY <= -100){
                          endY = e.changedTouches[0].pageY;
                          clearInterval(interval);
                          if(mediaRecorder.state === 'recording') {
                            mediaRecorder.stop();
                          }
                          $(this).html(i18n.t('m.chat_0041')) // 按住录音
                          recordendTime = new Date().getTime();
                          console.log("recorder stopped");
                        }
                      },
                      touchend: function(e) {
                        if(mediaRecorder.state === 'recording') {
                          endY = e.changedTouches[0].pageY;
                          mediaRecorder.stop();
                          $(this).html(i18n.t('m.chat_0041')) // 按住录音
                          recordendTime = new Date().getTime();
                          console.log("recorder stopped");
                        }
                      }
                    })
                    mediaRecorder.onstop = function(e) {
                      recordedTime = 0;
                      clearInterval(interval);
                      if (endY - startY >= 100 || endY - startY <= -100) { // 取消发送
                        // 重置录音数据
                        chunks = [];
                      } else {
                        // 保存录音
                        var blob = new Blob(chunks, {
                            'type': 'audio/mp3'
                          }),
                          center_info = JSON.parse(localStorage.getItem('account_info')),
                          project_info = JSON.parse(localStorage.getItem('project_basic'));
                        // 发送录音
                        let audioPara = {
                          touserid: to.id , // to.gid ,
                          username: center_info.user_name,
                          avatar: layui.cache.dir + 'images/face/' + (Math.random() * 72 | 0) + '.gif',
                          type: 'friend',
                          content: blob,
                          cid: '',
                          mine: false,
                          userid: project_info.db + center_info.user_guid,
                          project_id:project_info.db
                        };
                        var fr = new FileReader ()
                        fr.readAsDataURL(blob, {type: 'audio/mp3'})
                        fr.onload = function(e) {
                          var audioEle  =  document.createElement('audio')
                          audioEle.src = e.target.result;
                          event.detail.audioBtn.after(audioEle)
                        }
                          
                        console.log(audioPara)
                        event.detail.sendAudio(socket, audioPara)
    //                     socket.emit('sendAudioMessage', audioPara)
                        // that.displayAudio(blob, true, event.detail.audioBtn)
                        // 重置录音数据
                        chunks = [];
                      }
                    }
    
                    // 录音逻辑
                    mediaRecorder.ondataavailable = function(e) {
                      chunks.push(e.data);
                    }
                  }
        })
    

    // 监听录音发送

     //发送语音
      var sendAudio = function(socket, audioPara){
        var data = {
          username: cache.mine ? cache.mine.username : i18n.t('m.chat_0022')
          ,avatar: cache.mine ? cache.mine.avatar : (layui.cache.dir+'css/pc/layim/skin/logo.jpg')
          ,id: cache.mine ? cache.mine.id : null
          ,mine: true
        };
        var thatChat = thisChat(), ul = thatChat.elem.find('.layim-chat-main ul');
        var To = thatChat.data, maxLength = cache.base.maxLength || 3000;
        var time =  new Date().getTime(), textarea = thatChat.textarea;
        // 使用objectURL做src,失败->416错误
    //     let blob = new Blob([new Int8Array(audioPara.content)], {type: 'audio/mp3'});
    //     let src = URL.createObjectURL(blob);
        // 使用base64作src
        var fr = new FileReader();
        fr.readAsDataURL(audioPara.content);
        fr.onload = function(e) {
          data.content = e.target.result;
          if(data.content === '') return;
          if(time - (sendMessage.time||0) > 60*1000){
            ul.append('<li class="layim-chat-system"><span>'+ layui.data.date() +'</span></li>');
            sendMessage.time = time;
          }
          console.log(data)
          ul.append(laytpl(elemChatAudio).render(data));
          
          var param = {
            mine: data
            ,to: To
          }, message = {
            username: param.mine.username
            ,avatar: param.mine.avatar
            ,id: To.id
            ,type: To.type
            ,content: param.mine.content
            ,timestamp: time
            ,mine: true,
            dataType: 'audio'
          };
          pushChatlog(message);
          console.log(audioPara)
          socket.emit('sendAudioMessage', audioPara)
          To.content = data.content;
          To.dataType = 'audio';
          setHistory(To);
          chatListMore();
          textarea.val('');
          
          textarea.next().addClass('layui-disabled');
        }
      };
    

    layim-mobile.js中新增一个展示语音聊天的模块

      var elemChatAudio = ['<li class="layim-chat-li{{ d.mine ? " layim-chat-mine" : "" }}">'
        ,'<div class="layim-chat-user"><img src="{{ d.avatar }}"><cite>'
          ,'{{ d.username|| i18n.t("m.chat_0008") }}'
        ,'</cite></div>'
        ,'<div class="layim-chat-text"><div class="layui-unselect layui-layim-audio" layim-event="playAudio" data-src="'
        ,'{{ d.content }}'
        ,'"><i class="layui-icon">&#58962;</i><p>音频文件</p></div></div>'
      ,'</li>'].join('');
    

    至于后端传给我是blob结果拿到却不是的问题

    这个应该是在websocket传输的过程中转码了,不是太清楚.刚开始没有弄明白自己拿到的是什么格式(类型)的数据,后面看了下自己转成base64的文件,有点像诶.好吧试着转一下

    var bString = atob(item.content); // 结果证明,从数据库中拿到的的确是没有编码头的base64的数据,或者叫(ASCII码数据)
              var len = bString.length;
              var arr = new Uint8Array(len);
              while(len--){
                arr[len] = bString.charCodeAt(len);
              }
              var blob = new Blob([new Int8Array(arr)], {type: 'audio/mp3'});
              var src = URL.createObjectURL(blob);
              item.content = src
              ul.append(laytpl(elemChatAudio).render(item));
    

    看着这些代码,脑袋晕,还是自己太撇火药了,哪天想起了看看能不能再来整理下吧

  • 相关阅读:
    iOS 数据持久化--CoreData
    iOS 数据持久化-- FMDB
    iOS数据持久化--数据库
    iOS数据持久化--归档
    iOS数据持久化--用户属性
    python爬坑记录
    Flutter 爬坑记录
    Web开发爬坑记录
    博客 新址: http://zhoushaoting.com/
    微信小程序开发技巧及填坑记录
  • 原文地址:https://www.cnblogs.com/whitewen/p/10622841.html
Copyright © 2011-2022 走看看