用VUE手撸一个音乐播放控件

由于公司业务需要,需要在H5页面中播放音频。根据提供的UX大概是这个样子的


image.png

分析一下主要功能:
1、点击左侧按钮可以控制音频的播放和暂停。
2、时间随着音乐的播放实时变化,同时需要显示总时间。
3、中间进度条,随着音乐播放实时变化,另外用户主动拖动,可以拖动到对应时间位置。

基于以上需求,先进行UI的绘制,由于项目中使用了vant UI框架,所以拖动条直接用vant中的slider滑块即可
image.png

h5代码如下
<div class="player">
    <div class="button-control" @click="playOrPause">
      <van-icon name="play-circle-o" v-if="!status" />
      <van-icon name="pause-circle-o" v-else />
    </div>
    <div class="time-box">{{ currentStringTime }}/{{ totalStringTime }}</div>
    <div class="controler">
      <van-slider
        :max="totalTime"
        bar-height="2"
        button-size="17"
        inactive-color="#666666"
        v-model="timeNow"
        @change="onChange"
      />
    </div>
    <div class="more">
      <van-icon name="ellipsis" />
    </div>
  </div>

由于本项目中不会太频繁的进行开始和暂停的转换,因此使用了v-if来控制两个按钮的切换,如果经常需要暂停和播放的控制,建议使用v-show属性。
在HTML5中,一般使用<audio></audio>书写音频播放,但是本项目中因为没有使用htm中的UI,所以可以直接用js中的代码来生成音频对象:

mounted() {
    this.audioObject = new Audio(this.audioSrc);
    ...
}

audioSrc通过子控件的props对象中定义,这样父元素可以通过该属性将音频的链接出入。

<audio-player audioSrc="https://mp32.9ku.com/upload/128/2020/05/18/1004197.mp3">
</audio-player>

在audio对象中,对应几个媒体的特有事件,本项目中主要用到了:
loadstart ---------------------------------->对应开始加载音频事件
laodeddata ------------------------------->加载完毕相应该事件
timeupdate ------------------------------->事件改变相应该事件
ended -------------------------------------->播放完毕响应该事件
在音频加载完成时,通过audio对象的duration属性,可以获取音频的总时长;
当事件更新时,通过audio对象的currentTime属性,可以获取当前播放的时间参数,用于显示,由于播放控件中的时间是按照秒更新的,因此在取整后秒没有更新可以不用改变数据,来提高效率。

    let that = this;
    this.audioObject.addEventListener("loadstart", function() {
      //that.$toast("loadstart");
    });
    this.audioObject.addEventListener("loadeddata", function() {
      //console.log("loadeddata");
      that.totalTime = parseInt(that.audioObject.duration);
    });
    this.audioObject.addEventListener("timeupdate", function() {
      let tempSecond = parseInt(that.audioObject.currentTime);
      if (that.timeNow != tempSecond) {
        that.timeNow = tempSecond;
      }
    });
    this.audioObject.addEventListener("ended", function() {
      that.status = false;
      that.timeNow = 0;
    });

其他函数:

    onChange(value) {
      this.audioObject.currentTime = value;
    },
    playOrPause() {
      if (this.status) {
        this.audioObject.pause();
        this.status = false;
      } else {
        this.audioObject.play();
        this.status = true;
      }
    },
    getStringTime(time) {
      let minute = parseInt(time / 60);
      if (minute < 10) {
        minute = "0" + minute;
      }
      let second = parseInt(time % 60);
      if (second < 10) {
        second = "0" + second;
      }
      return minute + ":" + second;
    }

当拖动进度条时,响应控件中的onChange(value)方法,通过将audio对象中的currentTime设置为当前的数值,实现时间显示和播放进度及进度条三者位置的统一
用status来标识当前是否播放的状态,通过点击播放/暂停按钮调用playOrPause函数,来控制状态和播放,audio对象中的play()和pause()方法对应音频的播放和暂停功能。
getStringTime方法,用来优化时间的显示,通过分钟和秒数来标识,单位数的前边加0是显示效果更好一些,在页面上的实时时间显示可以通过计算属性来标识。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容