背景

O3H5y5

编写音频播放需求

实现

思路:

音频播放就用 audio标签来处理,音频内容挂载到audio元素(ad)上,把该元素隐藏。自己写下ui,然后通过audio的相关控制api来实现播放功能。

  1. play/pause 来实现音频的播放/暂停
  2. el.currentTime 来获取当前播放时间进度,用来显示实时的播放时间(封装个处理方法)
  3. el.duration 获取整个音频的时长,这样的话就可以显示总时长
  4. 进度条组件根据(el.currentTime/el.duration) 的百分比随着歌曲播放改变。
  5. 同样,改变进度条,根据百分比计算出当前音频的播放时间点 el.currentTime 来调整歌曲进度
  6. 播放的结尾 判断el.currentTime == el.duration,播放按钮置于暂停状态。此时播放的话 需要从头开始播放
  7. 其他比如倍速 音量之类的选项也是通过相关api来控制

vue代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<template>
  <div class='audioCard'>
    <audio  
      ref='audio'      
      id='audio'
      controls
      :src="info.src">
      你的浏览器不支持音频播放        
    </audio>
    <div class="title">
      <span>{{ info.title }}</span>
      <span class="closeIcon" @click="closePanel">
        <van-icon name="cross" />
      </span>
    </div>
    <div>
      <van-slider 
        v-model="currentValue" 
        @change="onChange"        
        class='audioSlider'              
      />
      <div class='timeBar'>
        <span>{{ getCurrentTime(currentTime) }}</span>
        <span>{{ getCurrentTime(duration) }}</span>
      </div>
      <div class="controlBtn">
        <img
          :src="
            isPlay
              ? require('@/assets/audio_pause.png')
              : require('@/assets/audio_play.png')
          "
          alt=""
          @click="playAudio"
        />
      </div>
    </div>
  </div>
</template>
<script>
/* eslint-disable */
import { getCurrentTime } from './util';

export default { 
  props: ['info'],
  data() {
    return {
      currentTime: 0,
      currentValue: 0,
      duration: 0,   
      isPlay: false    
    }
  },
  mounted() {
    const ad = this.$refs.audio
    ad.onloadedmetadata = () => {
      this.duration = parseInt(ad.duration);
    }

    ad.addEventListener('timeupdate', this.audioTimeupdate);
  },
  methods: {
    getCurrentTime,
    audioTimeupdate() {
      const ad = this.$refs.audio;
      this.currentTime = parseInt(ad.currentTime);  
      this.currentValue = ad.currentTime * 100 / this.duration; 
      
      if(parseInt(this.currentTime) == this.duration) {
        this.isPlay = false;      
      }
    },
    onChange(value) {
      this.currentTime = this.duration * value / 100;
      this.$refs.audio.currentTime = this.currentTime;    
    },
    playAudio() {
      if(!this.isPlay) {
        if(this.currentTime === this.duration) {
          this.currentTime = 0;
          this.currentValue = 0;
        }
        this.$refs.audio.play();        
      }else {
        this.$refs.audio.pause();
      }

      this.isPlay = !this.isPlay;
    },
    closePanel() {
      this.$emit('closePanel')
    }
  }
}
</script>
// 样式省略

小结

  1. 熟悉下audio相关api
  2. 了解封装一些常用移动端ui,