小程序: wx.createInnerAudioContext以及用data绑定固定动态class

1.wx.createInnerAudioContext

小程序虽说不维护audio组件,但在1.6.6版本后就不再支持audio了,尤其在ios不能播放audio了,强制改用wx.createInnerAudioContext来播放audio。

譬如页面原先是使用audio播放音频,只要在wxml页面写下如下代码就可以执行:

<audio class="img" poster="/common/icons/audio.png" name="" author="" src="https://www.xxx.com/01.mp3"controls></audio>

在微信开发工具上是可以呈现的,但要是用真机是点击音频播放按钮是无效的。

所以下面要在js文件中使用wx.createInnerAudioContext来呈现音频的播放功能

(1).首先在wxml写下view或button或block,推荐用view

wxml文件代码
<view class="img" bindtap="audioPlay"></view>
js文件代码
Page({

  /**
   * 页面的初始数据
   */
  data: {
    isplay: false
  },
  audioPlay: function() {
    const innerAudioContext = wx.createInnerAudioContext()
    innerAudioContext.autoplay = true
    innerAudioContext.src = 'https://www.xxx.com/001.mp3'
  // 监听音频播放事件
    innerAudioContext.onPlay(() => {
      console.log('onPlay');
      this.setData({
        isplay: true
      });
    });
    // 监听音频自然播放至结束的事件
    innerAudioContext.onEnded(()=> {
      console.log('onEnded');
      this.setData({
        isplay: false
      });
      innerAudioContext.seek(0);
    });
  },

原理:在wxml文件中,需要有bindtap,主要是点击这个位置时候会响应js文件中audioPlay操作,所以在js文件中audioPlay来定义wx.createInnerAudioContext,如果你不需要监听音频事件,三行代码就可以了,但是一般都没有这么简单的操作逻辑。下面就介绍多个音频文件的class监听。

2.利用data绑定wxml中的固定class

如上图,如果你的页面有多个相同的class,如何利用js绑定音频文件和class?

<view class="{{((!isplay)?'play':'pause')}}" bindtap="audioPlay" id="0001.mp3"></view>

在class中添加一个三目运算符,譬如上面的{{((!isplay)?’play’:’pause’)}},意思是if not play,class=”play”; else class=”pause”.

$a = (1 > 0)?'true':'false' // 三目运算符等同于下面if语句

if(1 > 0) {
  $a = 'true';
} else {
  $a = 'false';
}
js文件
Page({
  /**
   * 页面的初始数据
   */
  data: {
    isplay: false
  },
    audioPlay: function(event) {
    console.log(event)
    const innerAudioContext = wx.createInnerAudioContext()
    innerAudioContext.autoplay = true
    innerAudioContext.src = 'https://www.xxx.com/' + event.currentTarget.id

    // 监听音频播放事件
    innerAudioContext.onPlay(() => {
      console.log('onPlay');
      this.setData({
        isplay: true
      });
    });
    // 监听音频自然播放至结束的事件
    innerAudioContext.onEnded(()=> {
      console.log('onEnded');
      this.setData({
        isplay: false
      });
      innerAudioContext.seek(0);
    });
  },

通过wxml中bindtap传递id=id=”0001.mp3″到js文件中audioPlay,利用innerAudioContext.src = ‘https://www.xxx.com/’ + event.currentTarget.id 来绑定音频文件,这样点击bindtap就可以播放这个固定id的音频了。

重点来了:因为使用wx.createInnerAudioContext在xml view中是不显示音频的,所以你就需要在view 的class=play或pause来background-image不同的音频按钮。

wxss文件
.play {
  width: 130rpx;
  height: 130rpx;
  background-position: center;
  background-repeat: no-repeat;
  background-image: url(https://www.xxx.com/miniapp/play.png);
}
.pause {
  width: 130rpx;
  height: 130rpx;
  background-position: center;
  background-repeat: no-repeat;
  background-image: url(https://www.xxx.com/miniapp/pause.png);
}

通过js文件中onPlay和onEended来监听音频的播放和停止,然后通过setData中isplay为true或false来传递给wxml中view class=”{{((!isplay)?’play’:’pause’)}}”。

但是wxml中<view class….是相同的,所以当data传递isPlay时候,点击一个音频,所有音频按钮都会改变,所以这个时候就需要绑定每个层的class,点击这个层bingtap其他层的class不变,通过引入num=id,然后setData num: event.currentTarget.id,如果wxml class={{(num==id) then执行isplay。完全代码如下:

wxml:
<view class="{{(num=='0001.mp3')?((!isplay)?'play':'pause'):'play'}}" bindtap="audioPlay" id="0001.mp3"></view>
js:
data: {
    num: null,
    isplay: false
  },
    audioPlay: function(event) {
    console.log(event)
    const innerAudioContext = wx.createInnerAudioContext()
    innerAudioContext.autoplay = true
    innerAudioContext.src = 'https://www.xxx.com/' + event.currentTarget.id

    // 监听音频播放事件
    innerAudioContext.onPlay(() => {
      console.log('onPlay');
      this.setData({
        isplay: true,
        num: event.currentTarget.id
      });
    });
    // 监听音频自然播放至结束的事件
    innerAudioContext.onEnded(()=> {
      console.log('onEnded');
      this.setData({
        isplay: false
      });
      innerAudioContext.seek(0);
    });
wxss:
wxss文件
.play {
  width: 130rpx;
  height: 130rpx;
  background-position: center;
  background-repeat: no-repeat;
  background-image: url(https://www.xxx.com/miniapp/play.png);
}
.pause {
  width: 130rpx;
  height: 130rpx;
  background-position: center;
  background-repeat: no-repeat;
  background-image: url(https://www.xxx.com/miniapp/pause.png);
}

Referrence:

  1. AudioContext wx.createAudioContext(string id, Object this):https://developers.weixin.qq.com/miniprogram/dev/api/media/audio/wx.createAudioContext.html
  2. InnerAudioContext播放音频失败,但是模拟器可以正常播放,怎么处理?:https://developers.weixin.qq.com/community/develop/doc/0000c40ae602304d527961a235b400
  3. 如何在小程序中实现音频播放:https://cloud.tencent.com/developer/article/1362479
  4. 微信小程序的innerAudioContext 与AudioContext有什么区别:https://zhmzjl.com/show-11-193-1.html
  5. 微信小程序–解决wx.createInnerAudioContext()无法停止播放问题:https://blog.csdn.net/qq_41226029/article/details/95346514
  6. 微信小程序:wx.createInnerAudioContext的使用:https://blog.csdn.net/HUSHILIN001/article/details/79740459
  7. 三目运算符:https://baike.baidu.com/item/%E4%B8%89%E7%9B%AE%E8%BF%90%E7%AE%97%E7%AC%A6
  8. 微信小程序学习–传递参数的3种方式:http://www.wxapp-union.com/portal.php?mod=view&aid=2708
  9. 微信小程序 点击切换样式的功能实现:https://zhuanlan.zhihu.com/p/35625925