微信小程序 音频播放

记录一下原生微信小程序的音频实现

只有简单的拖拽进度条,上一首,下一首,开始/暂停功能

直接上代码,先实现基本页面,这是基本功,没什么好说的

<view class='tc'>
    <!-- 这个是封面 -->
    <image src='' class='audio_img'></image>	
    <view class='text-black f32'>这里是标题</view>
</view>

<!-- 这个是进度条 -->
<slider class='slider pt10 pb10 pl10 pr10' bindchange="changeValue" value='{{currentNum/durationNum}}' backgroundColor='#D8D8D8' selected-color="#FBB000" block-size="20"></slider>

<!-- 这个是时间 -->
<view class='time flex-bc'>
    <view class='time_left'>{{current}}</view>
    <view class='time_right'>{{duration}}</view>
</view>

<!-- 这个是操作按钮 -->
<view class='flex-bc audio_btn pl50 pr50'>
    <image class='small' src='/assets/last.png' bindtap='back' wx:if='{{active > 0}}'></image>
    <image class='small' src='/assets/lastno.png' wx:else></image>

    <image class='' src='/assets/audio.png' bindtap='play' wx:if='{{tridPlay}}'></image>
    <image class='' src='/assets/audio.png' bindtap='play' wx:else></image>

    <image class='small' src='/assets/next.png' wx:if='{{active < list.length - 1}}' bindtap='go'></image>
    <image class='small' src='/assets/nextno.png' wx:else></image>
</view>

接下来就是js部分,先创建一个音频实例
这里已废弃,看尾部

// 创建一个播放对象
const audio = wx.createInnerAudioContext();

初始化音频, 封装成一个方法,方便调用

initAudio(url) {
     // 音频链接
    audio.src = url 
    // 进来自动播放
    audio.autoplay = true

    audio.onTimeUpdate( () => {
        // 这里获取到音频的总时长
        let durationnum = parseInt(audio.duration)
        //  this.formatSeconds 为转换时间格式(04:37 可自行百度)
        let time = this.formatSeconds(audio.duration)
        // 更新值方便计算进度条和查看时间
        this.setData({
            duration: time,
            durationNum: durationnum,
        })
    
        this.changeCurrent(audio.currentTime)
    })
},
// 当前播放格式化
changeCurrent(step) {
    let currentnum = parseInt(step)
    let currentt = this.formatSeconds(currentnum)
    this.setData({
        current: currentt,
        currentNum: currentnum * 100,
    })
},
// 左侧补零
addZero(val) {
    if (val < 10) {
	return 0 + '' + val
    } else {
	return val
    }
},
// 时间格式化
formatSeconds(value) {
    var secondTime = parseInt(value); // 秒
    var minuteTime = 0; // 分
    var hourTime = 0; // 小时
        if (secondTime > 60) {
    	      minuteTime = parseInt(secondTime / 60);
              secondTime = parseInt(secondTime % 60);
              if (minuteTime > 60) {
        	hourTime = parseInt(minuteTime / 60);
        	minuteTime = parseInt(minuteTime % 60);
             }
        }
	var result = "" + this.addZero(parseInt(secondTime)) + "";
	if (minuteTime > 0) {
		result = "" + this.addZero(parseInt(minuteTime)) + ":" + result;
	} else {
	      result = "" + this.addZero(parseInt(minuteTime)) + ":" + result;
	}
	if (hourTime > 0) {
		result = "" + parseInt(hourTime) + ":" + result;
	}
	return result;
},

然后就是使用了,因为一般都会跳到详情播放音频,会带上当前id,所以我在 onLoad 生命周期里执行

async onLoad(options) {
    // 获取链接上的参数
    const params = JSON.parse(options.params)

    // 传参请求后台接口,返回链接
    const res = await app.globalData.post('/Book/play', params)

    // 初始化音频
    this.initAudio(res.url)

    // 播放完毕回调
    audio.onEnded(res => {
          // 这里是个回调,可以执行一些操作,比如自动播放下一条
        cosnt url = ''

        this.initAudio(url)
    })
},

然后实现一个拖拽进度条,因为slider 自带有bindchange,那么直接监听即可

// 滑块拖动快进,快退
changeValue(e) {
    let val = e.detail.value
    let step = (val / 100) * this.data.durationNum
    audio.seek(parseInt(step))
    this.changeCurrent(step)
},

最后就是上一首,下一首,暂停和开始了

// 上一首
go() {
  // 获取链接然后直接开始
  const url = ''

  // 播放
  this.initAudio(url)
},
  // 下一首
back() {
  // 获取链接然后直接开始
  const url = ''

  // 播放
  this.initAudio(url)
},

// 播放暂停
play() {
  if (this.data.tridPlay) {
    audio.play();
    this.setData({ tridPlay: false })
  } else {
    audio.pause()
    this.setData({ tridPlay: true })
  }
},

这时候就会有一个bug了,你会发现每次退出页面的时候,音频竟然还在播放,正常的逻辑应该是退出播放就音频不播放,简单讲就是销毁音频实例,所以我这样做:

onHide(){
      //页面隐藏时停止播放
	this.dataaudio.stop()
},

onUnload() {
      //页面卸载时销毁音频实例
      this.data.audio.destroy();
},

这里的音频实例为什么变成 this.data.audio了呢,而不是 page外面定义的audio,是因为你销毁了实例,确实不会播放了,但是再次进来页面的时候,onTimeUpdate不执行了,导致我没法监听进度条时间等,网上很多说加个setTimeout,onCanplay、onWaiting加个play(),pasue()等等,我觉得都不好使。不如简单点,我每次进来就重新创建一个实例,关闭页面就销毁这个实例。所以 所有audio实例调用改为this.data.audio

Page({
  data: {
     audio: null
  },
  onLoad{
    this.setData({
      audio: wx.createInnerAudioContext()
    })
  }
})

下一篇,微信小程序 背景音频播放

完。

posted @ 2022-05-07 17:59  Z、yx  阅读(583)  评论(0编辑  收藏  举报