微信开发之微信jssdk录音功能开发示例


Posted in Javascript onOctober 22, 2018

项目需求简单描述

用户长按录音,松手后直接结束录音,结束录音后,用户可以选择重新录音、播放刚才的录音,上传录音(这里的上传录音指上传到自己服务器,上传步骤是,前端调用wx.uploadVoice,后台再到微信服务器下载音频文件,上传到自己的服务器)。注意,音频文件自上传时间算起在微信服务器的有效期为3天。由于后台从微信服务器下载的音频文件是amr格式的,需要后台先把amr文件转换成MP3,前端用audio播放。我们公司是购买阿里云的媒体处理服务进行文件转码的。

调用到的微信接口

// 开始录音接口
wx.startRecord();

// 停止录音接口
wx.stopRecord({
success: function (res) {
  var localId = res.localId;
 }
});

// 监听录音自动停止接口
wx.onVoiceRecordEnd({
 // 录音时间超过一分钟没有停止的时候会执行 complete 回调
 complete: function (res) {
  var localId = res.localId;
 }
});

// 播放语音接口
wx.playVoice({
 localId: '' // 需要播放的音频的本地ID,由stopRecord接口获得
});

// 暂停播放接口
wx.pauseVoice({
 localId: '' // 需要暂停的音频的本地ID,由stopRecord接口获得
});

// 监听语音播放完毕接口
wx.onVoicePlayEnd({wx.onVoice
 success: function (res) {
  var localId = res.localId; // 返回音频的本地ID
 }
});

// 上传语音接口
wx.uploadVoice({
 localId: '', // 需要上传的音频的本地ID,由stopRecord接口获得
 isShowProgressTips: 1, // 默认为1,显示进度提示
 success: function (res) {
  var serverId = res.serverId; // 返回音频的服务器端ID
 }
});

主要涉及的知识点

//项目用到的框架:vue.js
@touchstart // 手指触碰屏幕,开始长按
@touchend //手指离开屏幕,结束长按
@touchmove //手指在屏幕上滑动

开发流程

说明:项目用到的框架:Vue

1.引入微信jssdk,做好微信配置

2.HTML结构:

<div @touchstart="gtouchstart()" @touchend="gtouchend()" @touchmove="gtouchmove()"></div>

touchstart事件:MDN的定义是:当触点与触控设备表面接触时触发touchstart 事件,换句话来说,就是手指触碰屏幕时触发,所以这里监听开始长按。

@touchend事件:当手指从屏幕上离开的时候触发,这里今天长按结束。

@touchmove事件:当手指在屏幕上滑动的时候连续地触发。在这个长按录音的场景中,当手指在屏幕上移动了,也视为录音结束,所以要监听手指在屏幕上滑动。

3.js代码

methods:{
 gtouchstart(){
  // 当用户长按500ms以上再真正开始录音
  setTimeout(() => {
   this.longPress()
  }, 500)}
 },
 longPress(){
  wx.startRecord() // 微信开始录音接口
 },
 gtouchmove(){
  wx.stopRecord({ // 微信结束录音接口
   success: res => {
    this.localId = res.localId;
    console.log('中断结束录音')
   }
  })
 },
 gtouchend(){
   wx.stopRecord({ // 微信结束录音接口
    success: res => {
     this.localId = res.localId;
     console.log('正常结束录音成功了')
    }
  })
 },
 wxUpload() { // 上传到微信服务器
  wx.uploadVoice({
   localId: this.localId, // 需要上传的音频的本地ID,由stopRecord接口获得
   isShowProgressTips: 1, // 默认为1,显示进度提示
   success: res => {
    this.serverId = res.serverId; // 返回音频的服务器端ID
   }
  });
 },
}

大致过程如上面代码所示:

  • 在某个html元素监听开始长按事件、结束长按事件、在屏幕上移动事件;
  • 长按事件开始,这时调用微信接口wx.startRecord开始录音;
  • 长按事件结束,这时调用微信接口wx.stopRecord结束录音,得到音频的localId;
  • 当用户在长按过程中手指移动了,也调用wx.stopRecord结束录音;
  • 录音结束后,调用微信接口wx.uploadVoice把音频上传到微信服务器。

开发过程遇到的问题

1.调用微信录音超过60秒时,微信会自动结束录音并且返回一个localId,并且这个localId是无效的

解决方案:

在 wx.startRecord() 开始之前添加定时器,如果录音时间到达59秒,执行wx.stopRecord主动停止录音,避免用户录音时间过长导致录音无效。

2.微信录音功能授权引发的交互问题

使用微信jssdk接口录音,在同一个域只需要授权一次,即第一次使用录音的时候,微信自己会弹出对话框询问是否允许录音,用户点击允许后,之后再使用录音时,便不会再咨询用户是否允许。

在第一次按住录音后,由于用户未曾允许录音,微信会提示用户授权允许在本页面使用微信录音功能,这时用户会放开录音按钮转而去点击允许,在用户允许后,才真正会开始录音,而此时用户早已放开录音按钮,那么录音按钮上便不会再有touchend事件,录音便会一直进行。

解决策略:使用localStorage记录用户是否曾授权,并以此来判断是否需要在刚进入页面是自动录一段录音来触发用户授权

if(!localStorage.rainAllowRecord || localStorage.rainAllowRecord !== 'true'){
  wx.startRecord({
    success: function(){
      localStorage.rainAllowRecord = 'true';
      wx.stopRecord();
    },
    cancel: function () {
      alert('用户拒绝授权录音');
    }
  });
}

3.在ios下不能自动播放audio的问题

关于音频的播放,为了页面美观,处理方式是隐藏audio的播放控件,然后给一个按钮添加时间,通过audio.play()来控制音频的播放的。但是在ios下有个问题,audio.play()是不能直接播放音频的,只能显式地通过操作音频的播放控件来。这是因为iOS Safari 不允许自动播放 audio,只能通过用户交互触发。这大概是苹果公司出于用户体验而做的限制。

解决方案:

// 在页面初始化成功后,在wx.ready的回调函数内,收到执行下面的方法,这样ios用户在点击播放按钮时就能正常播放音频
wx.ready(() => {
 this.$nextTick(() => {
  this.$refs.audio.load()
  this.$refs.audio.play()
  this.$refs.audio.pause();
 })
})

4.终极问题:某些手机屏幕不灵敏导致长按录音出现各种各样的问题

描述:在初次完成长按录音的功能后,我在公司多台贴了膜或者屏幕摔烂的手机测试发现,这些手机长按、和取消长按的事件相当不灵敏,误差很大,有时莫名其秒地结束录音,体验非常差。

解决方案:我们和产品经过商量,摆出这个避免不了的问题,最终把长按录音的交互模式改成了点击录音。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Javascript的闭包
Dec 31 Javascript
Jquery ajax不能解析json对象,报Invalid JSON错误的原因和解决方法
Mar 27 Javascript
Ajax搜索结果页面下方的分页按钮的生成
Apr 05 Javascript
node在两个div之间移动,用ztree实现
Mar 06 Javascript
js用正则表达式来验证表单(比较齐全的资源)
Nov 17 Javascript
判断一个对象是否为jquery对象的方法
Mar 12 Javascript
JavaScript+CSS无限极分类效果完整实现方法
Dec 22 Javascript
vue router2.0二级路由的简单使用
Jul 05 Javascript
JavaScript代码判断输入的字符串是否含有特殊字符和表情代码实例
Aug 17 Javascript
Vue中的methods、watch、computed的区别
Nov 26 Javascript
使用layer弹窗,制作编辑User信息页面的方法
Sep 27 Javascript
原生js+css调节音量滑块
Jan 15 Javascript
ztree加载完成后显示勾选节点的实现代码
Oct 22 #Javascript
electron实现qq快捷登录的方法示例
Oct 22 #Javascript
Electron-vue脚手架改造vue项目的方法
Oct 22 #Javascript
angular 服务的单例模式(依赖注入模式下)详解
Oct 22 #Javascript
vue 配置多页面应用的示例代码
Oct 22 #Javascript
微信小程序引用iconfont图标的方法
Oct 22 #Javascript
详解微信小程序与内嵌网页交互实现支付功能
Oct 22 #Javascript
You might like
phpstudy2018升级MySQL5.5为5.7教程(图文)
2018/10/24 PHP
前端开发必须知道的JS之原型和继承
2010/07/06 Javascript
juery框架写的弹窗效果适合新手
2013/11/27 Javascript
javascript中全局对象的parseInt()方法使用介绍
2013/12/19 Javascript
使用纯javascript实现放大镜效果
2015/03/18 Javascript
jQuery实现仿微软首页感应鼠标变化滑动窗口效果
2015/10/08 Javascript
JS+CSS3实现超炫的散列画廊特效
2016/07/16 Javascript
JavaScript实现异步图像上传功能
2018/07/12 Javascript
angularJs使用ng-repeat遍历后选中某一个的方法
2018/09/30 Javascript
一些你可能不熟悉的JS知识点总结
2019/03/15 Javascript
JS中的函数与对象的创建方式
2019/05/12 Javascript
解决VUE mounted 钩子函数执行时 img 未加载导致页面布局的问题
2020/07/27 Javascript
Ant Design Vue table中列超长显示...并加提示语的实例
2020/10/31 Javascript
使用typescript快速开发一个cli的实现示例
2020/12/09 Javascript
mapboxgl实现带箭头轨迹线的代码
2021/01/04 Javascript
Python中的推导式使用详解
2015/06/03 Python
django 外键model的互相读取方法
2018/12/15 Python
Flask核心机制之上下文源码剖析
2018/12/25 Python
django中forms组件的使用与注意
2019/07/08 Python
python字典的setdefault的巧妙用法
2019/08/07 Python
使用Python将字符串转换为格式化的日期时间字符串
2019/09/01 Python
在python中logger setlevel没有生效的解决
2020/02/21 Python
python 代码实现k-means聚类分析的思路(不使用现成聚类库)
2020/06/01 Python
jurlique茱莉蔻英国官网:澳洲天然护肤品
2018/08/03 全球购物
行政助理的职责
2013/11/14 职场文书
大学社团活动策划书
2014/01/26 职场文书
2014迎国庆演讲稿
2014/09/19 职场文书
无犯罪记录证明
2014/09/19 职场文书
任命书怎么写
2015/03/02 职场文书
庆七一活动简报
2015/07/20 职场文书
早恋主题班会
2015/08/14 职场文书
党章党规党纪学习心得体会
2016/01/14 职场文书
子女赡养老人协议书
2016/03/23 职场文书
85句关于理想的名言警句大全
2019/08/22 职场文书
golang 实现Location跳转方式
2021/05/02 Golang
一文搞懂PHP中的抽象类和接口
2022/05/25 PHP