微信小程序中音频播放

简介: 微信小程序中音频播放

如何在小程序中实现音频播放

需要注意几点

由于现在官方不再维护 audio 组件 ,所以音频播放尽可能采取 wx.createInnerAudioContext() 接口 ( 若需要在后台播放,则采用 wx.getBackgroundAudioManager() )


音频播放,只有在播放时才可以获取到音频长度(参考了多个带音频的小程序 qq音乐,百度网盘等,都是采取自动播放的方式,以获取总时长)


由于 wx.createInnerAudioContext()和wx.getBackgroundAudioManager()接口都差不多,(简单来说,前者只会在当前页面播放,后者可在离开播放页面甚至返回微信界面(需要配置下),继续播放音乐),这里以 背景音乐为例子


wx.getBackgroundAudioManager()这个api返回的是一个对象(BackgroundAudioManager),同时需要注意 背景音频播放是获取的 全局唯一的背景音频管理器,也就是说,你不销毁或者停止,他会一直播放(离开微信和配置了后台播放除外)


BackgroundAudioManager在这个对象上有一些方法,比如:暂停,设置地址,监听播放状态(播放,停止,暂停,错误。。。。等)

  1. 获取全局唯一的背景音频管理器
const InnerAudioContext = uni.getBackgroundAudioManager();

       具体代码如下(此处是封装为播放组件,可直接复制)

<template>
  <view class="">
    <view class="audio-wrapper">
      <view class="audio-number">{{forNowTime}}</view>
      <slider class="audio-slider" :activeColor="color" block-size="16" :value="current" :max="duration" @changing="seek=true,current=$event.detail.value"
       @change="change"></slider>
       <!-- 时长 -->
      <view class="audio-number">{{forAllTime}}</view>
    </view>
    <view class="audio-control-wrapper" :style="{color:color}">
      <!-- 随机播放 -->
      <view class="audio-control audio-more iconfont music_icon_random" hover-class="btn-bg-m"></view>
      <!-- 上一首 -->
      <view class="audio-control  iconfont music_icon_previous" hover-class="btn-bg-m" v-if="control"  @click="prev"></view>
      <!-- 播放 -->
      <view class="audio-control audio-control-switch iconfont" hover-class="btn-bg"  :class="{'music_icon_play':paused,'music_icon_pause':!paused}"  @click="operation">
      </view>
      <!-- 下一首 -->
      <view class="audio-control  iconfont music_icon_next" v-if="control" hover-class="btn-bg-m"  @click="next"></view>
      <!-- 列表 -->
      <view class="audio-control audio-more  iconfont music_icon_list" hover-class="btn-bg-m" ></view>
    </view>
  </view>
</template>
<script>
  const InnerAudioContext = uni.getBackgroundAudioManager(); //createInnerAudioContext
  export default {
    data() {
      return {
        forNowTime:'00:00', //当前播放时间 4:30 格式
        forAllTime:'', //总时长 格式化
        duration:0,//总时间 秒
        current:0, //slider当前进度
        seek: false, //是否处于拖动状态
        paused: true, //是否处于暂停状态
      }
    },
    props: {
      audioSrc: {         //音频链接
        type:String,
        default:''
      },
      audioName:{     //歌曲名称
        type:String,
        default:''
      },
      control: {        //是否需要上一曲/下一曲按钮
        type:Boolean,
        default:true
      }, 
      nextAudio:{   //播放完成后是否继续播放下一首,需定义@next事件
        type:Boolean,
        default:false,
      },
      color: {    //主色调
        type:String,
        default:'#5189FF'
      } 
    },
    created() {
      // 是否遵循系统静音开关
      InnerAudioContext.obeyMuteSwitch = false
      // 监听播放
      InnerAudioContext.onPlay(()=>{
        this.paused=false
        console.log('播放中。。。')
      })
      // 监听暂停
      InnerAudioContext.onPause(()=>{
        this.paused=true
      })
      // 监听播放结束
      InnerAudioContext.onEnded(()=>{
        // 是否需要 自动播放下一首
        if(this.nextAudio) {
          this.next()
        }else{
          // 暂停
          this.paused=true
        }
      })
      // 监听 进度更新
      InnerAudioContext.onTimeUpdate(()=>{
        // 获取总进度
        this.duration = InnerAudioContext.duration
        // 当前进度 非拖动时
        if (!this.seek) {
          this.current= InnerAudioContext.currentTime
        }
      })
      //监听 进度更改完成
      InnerAudioContext.onSeeked(() => {
        this.seek = false
      })
      // 音频播放失败
      this.errMsg()
    },
    mounted(){
    },
    beforeDestroy(){
      // InnerAudioContext.pause()
    },
    computed:{
    },
    watch: {
      // 音频地址
      audioSrc(value){
        if(InnerAudioContext.src==value)return
        InnerAudioContext.src= value
        this.current=0
        // 设置自动播放 以获取总时长
        InnerAudioContext.autoplay=true
      },
      // 音频名字
      audioName(value,o){
        InnerAudioContext.title =value
      },
      // 音频总时长--格式化
      duration(value){
        this.forAllTime = this.format(value)
      },
      // 当前播放位置
      current(now){
        this.forNowTime = this.format(now)
        if(!InnerAudioContext.paused){
          this.paused=false
        }
      }
    },
    methods: {
      //返回prev事件
      prev() {
        this.$emit('prev')
      },
      //返回next事件
      next() {
        this.$emit('next')
      },
      //时间格式化
      format(num) {
        return '0'.repeat(2 - String(Math.floor(num / 60)).length) + Math.floor(num / 60) + ':' + '0'.repeat(2 - String(
          Math.floor(num % 60)).length) + Math.floor(num % 60)
      },
      //播放/暂停操作
      operation() {
        // 停止播放状态
        InnerAudioContext.paused?InnerAudioContext.play():InnerAudioContext.pause()
      },
      //快进
      change(e) {
        InnerAudioContext.seek(e.detail.value)
      },
      // 播放失败
      errMsg(){
        InnerAudioContext.onError((res)=>{
          let ErrMsg=res.errMsg
          wx.showModal({
            title: '播放失败',
            content:ErrMsg,
            showCancel:false,
            success: function(res) {
            }
          })
        })
      }
    },
  }
</script>
<style>
  .audio-wrapper {
    display: flex;
    align-items: center;
    padding-bottom: 90rpx;
  }
  .audio-number {
    font-size: 24upx;
    line-height: 1;
    color: #333;
  }
  .audio-slider {
    flex: 1;
    margin: 0 30upx;
  }
  .audio-control-wrapper {
    margin-top: 20upx;
    display: flex;
    align-items: center;
    justify-content: space-around;
  }
  .audio-control {
    font-size: 32rpx;
    width:80rpx;
    height:80rpx;
    border:1rpx solid rgba(168,196,255,1);
    border-radius:50%;
    text-align: center;
    line-height: 80rpx;
  }
  .audio-more{
    border:none;
    font-size: 32rpx;
    border-radius: 50%;
  }
  .audio-control-switch {
    color: #FFFFFF;
    font-size: 42rpx;
    margin: 0 60rpx;
    width:120rpx;
    height:120rpx;
    line-height: 120rpx;
    background:rgba(81,137,255,1);
    border-radius:50%;
    border: none;
  }
  .audioLoading {
    animation: loading 2s;
    animation-iteration-count: infinite;
    animation-timing-function: linear;
  }
  @keyframes loading {
    to {
      transform: rotate(360deg);
    }
  }
</style>


目录
相关文章
|
6月前
|
小程序 JavaScript
微信小程序【视频、音频】
微信小程序【视频、音频】
62 1
|
小程序
微信小程序wx.createInnerAudioContext播放play报错errMsg: “operateAudio:fail jsapi has no permission, event=ope
微信小程序wx.createInnerAudioContext播放play报错errMsg: “operateAudio:fail jsapi has no permission, event=ope
|
5月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的电影播放平台附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的电影播放平台附带文章和源代码部署视频讲解等
29 0
|
6月前
|
小程序 JavaScript 前端开发
微信小程序的音频视屏播放
微信小程序的音频视屏播放
105 0
|
6月前
|
小程序
微信小程序音频后台播放功能
微信小程序音频后台播放功能
559 0
|
6月前
|
小程序 JavaScript 前端开发
微信小程序音频,视频播放
微信小程序音频,视频播放
89 0
|
18天前
|
JSON 小程序 JavaScript
uni-app开发微信小程序的报错[渲染层错误]排查及解决
uni-app开发微信小程序的报错[渲染层错误]排查及解决
266 7
|
18天前
|
小程序 JavaScript 前端开发
uni-app开发微信小程序:四大解决方案,轻松应对主包与vendor.js过大打包难题
uni-app开发微信小程序:四大解决方案,轻松应对主包与vendor.js过大打包难题
369 1
|
1月前
|
小程序 前端开发 测试技术
微信小程序的开发完整流程是什么?
微信小程序的开发完整流程是什么?
92 7
ly~
|
2月前
|
存储 供应链 小程序
除了微信小程序,PHP 还可以用于开发哪些类型的小程序?
除了微信小程序,PHP 还可用于开发多种类型的小程序,包括支付宝小程序、百度智能小程序、抖音小程序、企业内部小程序及行业特定小程序。在电商、生活服务、资讯、工具、娱乐、营销等领域,PHP 能有效管理商品信息、订单处理、支付接口、内容抓取、复杂计算、游戏数据、活动规则等多种业务。同时,在企业内部,PHP 可提升工作效率,实现审批流程、文件共享、生产计划等功能;在医疗和教育等行业,PHP 能管理患者信息、在线问诊、课程资源、成绩查询等重要数据。
ly~
74 6

热门文章

最新文章