开发微信公众号网页调用微信js-sdk(扫一扫,语音)

在微信公众号里打开的网页,想要调用手机扫一扫,语音功能,这需要用到微信JS-SDK。因为是在微信里打开,受微信控制,所以只能用官方提供的sdk了。

注意-_-  坑:多个页面用到接口,必须都配一次config,url要是当前网页完整路径(现在是单页面,即www.abc.com/log,www.abc.com/list),不包括#后面的。

准备工作:

1. 认真读官方文档,可以减少不少坑。 (文档也有坑,字多,有的过时了,没更新。)

2.在公众号后台,配置JS接口安全域名,并把文件(下图第3点)下载到自己服务器。

3.  后端提供了接口,获取微信的签名等信息,用来配置config ( 前端直接调接口就行,生成签名这些只能有后台去调微信接口,官方文档也有写到)

正式开发:

【扫一扫】

1.在每个用到微信接口的页面,都需要单独调用一次后台接口,配置一次config。 因为每次签名所需要的url,必须是页面完整的url。

我用到的是vue,所以在created生命周期去请求配置config。

       const pageUrl = window.location.href; // 当前页面的url const vx_url="/wx/auth"; // 这是后台提供的接口。 const data={ url:pageUrl } this.$api.get(vx_url, data).then((result) => { if (result.success) { this.$wx.config({ debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: 'wx222222', // 必填,公众号的唯一标识 timestamp:result.data.timestamp , // 必填,生成签名的时间戳 nonceStr: result.data.noncestr, // 必填,生成签名的随机串 signature: result.data.signature,// 必填,签名 jsApiList: ['scanQRCode'] // 必填,需要使用的JS接口列表 }); } });

2. 在点击按钮后去调用微信接口,这种方式可以直接调用,不用写在ready里。

this.$wx.scanQRCode({
                          needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
                          scanType: ["qrCode"],
                          success: (res)=> {// console.log('扫描结果',res);
                          }
               });

【语音】

1.配置config

created() {
            const pageUrl = window.location.href;
            const vx_url = "/wx/auth";
            const data = {
                url: pageUrl
            }

            this.$api.get(vx_url,  data).then((result) => {
                if (result.success) {
                    this.$wx.config({
                        debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                        appId: 'wx2222', // 必填,公众号的唯一标识
                        timestamp: result.data.timestamp, // 必填,生成签名的时间戳
                        nonceStr: result.data.noncestr, // 必填,生成签名的随机串
                        signature: result.data.signature, // 必填,签名
                        jsApiList: ['startRecord', 'stopRecord', 'uploadVoice', 'onVoiceRecordEnd' ] // 必填,需要使用的JS接口列表
                    });
                }
            });
        }

2.开始录音

sendVoice(event) {
                event.preventDefault();            if (util.judgeEquipment().isWeixin) {
                        this.$wx.startRecord({
                            success: () => {
                                this.isSend = true;
                                this.isReord = true;
                                const touch = event.touches[0], //获取第一个触点
                                    x = Number(touch.pageX), //页面触点X坐标
                                    y = Number(touch.pageY); //页面触点Y坐标
                                // 记录触点初始位置
                                this.startX = x;
                                this.startY = y;
                                this.startTime = new Date().getTime();
                                this.voiceTxt = '松开 发送';
                                this.$wx.onVoiceRecordEnd({
                                    // 录音时间超过一分钟没有停止的时候会执行 complete 回调
                                    complete: function(res) {
                                        this.resetVoiceOption();
                                        this.uploadVoice(res.localId);
                                    }
                                });
                            }
                        });
                    }
            },

3.手指移动

    touchmove(event) {
                const touch = event.touches[0], //获取第一个触点
                    x = Number(touch.pageX), //页面触点X坐标
                    y = Number(touch.pageY); //页面触点Y坐标
                // 记录移动位置
                this.endX = x;
                this.endY = y;
                if (this.startY - this.endY < 0) {
                    // 向上滑
                    this.recordStatusTxt = recordingTxt;
                    this.isSend = true;
                } else {
                    // 向下滑
                    this.recordStatusTxt = cancelRecordTxt;
                    this.isSend = false;
                }
            },

4.结束录音

    touchend(e) {
                e.preventDefault();
                this.resetVoiceOption();
                this.endTime = new Date().getTime();
                const diffTime = this.endTime - this.startTime;
                if (this.startTime === 0 || diffTime < 500) {
                    this.$toast("录音时间太短", "none", 1500);
                    return
                }
                const recordTime = Math.ceil(diffTime / 1000); // 录音多少秒
this.$wx.stopRecord({ success: (res) => { if (this.isSend) { this.uploadVoice(res.localId); } } }); },

5.上传语音 

由于微信服务器只会保留语音文件3天,所以需要后台去微信服务器下载到自己服务器。后端从微信下载语音接口文档 https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/Get_temporary_materials.html

        uploadVoice(_localId) {
                this.$wx.uploadVoice({
                    localId: _localId, // 需要上传的音频的本地ID,由stopRecord接口获得
                    isShowProgressTips: 0, // 1显示进度提示,0不显示
                    success: (resp) => {
                        const url = '/wx/downloadVoice' // 后台提供的接口。先把语音上传到微信服务器,然后把serverId发给后台,后台通过这id去微信服务器下载语音到自己服务器,再返回url给前端
                        const data = {
                            mediaId:resp.serverId
                        }
                        this.$api.get(url, data).then((result) => {
                            if (result.success) {
                                // 返回是 .amr
                                console.log(result.data)   
                            }
                        });
                    }
                });
            },

6.重置

    resetVoiceOption(){
                this.isReord = false;
                this.voiceTxt = '按住 说话';
                this.recordStatusTxt = recordingTxt;
                this.startX = 0;
                this.startY = 0;
                this.endX = 0;
                this.endY = 0;
            },

7.播放

由于微信录音文件是.amr格式,h5音频标签无法播放的。

方案1:后台从微信服务器下载回来语音文件时,直接转换成MP3格式

方案2:前端使用‘benz-amr-recorder’这个库,可以播放

const BenzAMRRecorder = require('benz-amr-recorder');    
const amr = new BenzAMRRecorder();
                // url是后台返回的 https://www.abc.com/7A1BAEEB.amr
                amr.initWithUrl(src).then(() => {
                    amr.play(); // 播放
                    // const amrDuration = Math.ceil(amr.getDuration());
                    // console.log('音频时长', amrDuration); // 获取音频时长
                });

                amr.onEnded(() => {// console.log(播放结束)
                })

附:官网事例demo

补上HTML和data部分的代码:

用的是uni-app 
<view class="input">
      <input
              v-if="featuresType == 0"
              class="txt"
              placeholder="请输入文字"
              v-model="commentText"
              confirm-type="send"
              @confirm="sendTxt"
        />
        <input
              disabled
              :placeholder="voiceTxt"
              v-else
              class="btn-voice"
              @longpress="sendVoice"
              @touchend="touchend"
              @touchmove="touchmove"
            />
</view>

data(){
  return{
    voiceTxt: "按住 说话",
      startX: 0,
      startY: 0,
      endX: 0,
      endY: 0,
      startTime: 0,
      endTime: 0,
      recordStatusTxt: recordingTxt,
      isSend: false,
    isReord: false,
  }
}
原文地址:https://www.cnblogs.com/lucas27/p/13671800.html