HTML5-Audio实战总结

最近闲暇时在使用Electron做桌面端应用(仿网易云桌面客户端)于是有接触到audio。由于很久没有写过这标签了 特来此详细做个笔记,方便自己以后查阅。

先放一个auido标签 让他动起来

   <audio 
   		:src="https://music.163.com/song/media/outer/url?id=65847.mp3"
		controls
    ></audio>

一、Audio 对象

Audio 对象属性

属性描述博主提示
audioTracks返回表示可用音频轨道的 AudioTrackList 对象。任何主流浏览器都不支持 audioTracks 属性。
autoplay设置或返回是否在就绪(加载完成)后随即播放音频。如果设置了该属性,音频(加载完成)将自动播放。
buffered返回表示音频已缓冲部分的 TimeRanges 对象。
controller返回表示音频当前媒体控制器的 MediaController 对象。目前没有主流浏览器支持 controller 属性。
controls设置或返回音频是否应该显示控件(比如播放/暂停等)。设置就可以显示控件,但是每个浏览器都有自己显示auido的样式
crossOrigin设置或返回音频的 CORS 设置。这个确实没太懂哈 按常理,跨域在头部设置或者config配置 或者后端配置
currentSrc返回当前音频的 URL。只读
currentTime设置或返回音频中的当前播放位置(以秒计)。可写可读
defaultMuted设置或返回音频默认是否静音。可写可读
defaultPlaybackRate设置或返回音频的默认播放速度。可写可读
duration返回音频的长度(以秒计)。只读
ended返回音频的播放是否已结束。只读
error返回表示音频错误状态的 MediaError 对象。
loop设置或返回音频是否应在结束时再次播放。可写可读
mediaGroup设置或返回音频所属媒介组合的名称。可写可读
muted设置或返回是否关闭声音。可写可读
networkState返回音频的当前网络状态。0 - 音频尚未初始化;1 - 音频是活动的且已选取资源,但并未使用网络2 - 浏览器正在下载数据;3 - 未找到音频来源
paused设置或返回音频是否暂停。只读
playbackRate设置或返回音频播放的速度。可写可读,例值:1.0 正常速度;0.5 半速(更慢);2.0 倍速(更快);-1.0 向后;正常速度-0.5 向后半速 等
played返回表示音频已播放部分的 TimeRanges 对象。
preload设置或返回音频的 preload 属性的值。可写可读,是否在页面加载后载入音频。
readyState返回音频当前的就绪状态。可写可读
seekable返回表示音频可寻址部分的 TimeRanges 对象。
seeking返回用户当前是否正在音频中进行查找。
src设置或返回音频的 src 属性的值。可写可读
textTracks返回表示可用文本轨道的 TextTrackList 对象。
volume设置或返回音频的音量。规定音频/视频的当前音量。必须是介于 0.0 与 1.0 之间的数字。可写可读

Audio 对象方法

方法描述
addTextTrack()向音频添加新的文本轨道。
canPlayType()检查浏览器是否能够播放指定的音频类型。
fastSeek()在音频播放器中指定播放时间。
getStartDate()返回新的 Date 对象,表示当前时间线偏移量。
load()重新加载音频元素。
play()开始播放音频。
pause()暂停当前播放的音频。

二、播放器代码

template

    <div class="audio">
      <audio @ended="next(currentSongUnit.afterId)" ref="audio" @timeupdate="timeupdate"
             preload="auto" :src="audioSrc" />
      <div class="audio-btn fac">
      	<!-- 上一首 -->
        <i @click="next(currentSongUnit.beforeId)"class="iconfont icon-lastSong"/>
        <!-- 播放 -->
        <i @click="play()" v-show="isPause" class="iconfont icon-play" />
        <!-- 暂停 -->
        <i @click="stop()" v-show="!isPause" class="iconfont icon-paused" />
        <!-- 下一首 -->
        <i @click="next(currentSongUnit.afterId)" class="iconfont icon-nextSong"/>
      </div>
      <div class="audio-progressBar fbc">
      	<!-- 歌曲当前播放时间 -->
        <p class="start-tiem audio-tiem">{{ staratTime }}</p>
        <!-- 进度条 -->
        <div>
          <el-slider v-model="progressBarValue" :show-tooltip="false" @change="sliderChange"/>
        </div>
        <!-- 歌曲总时长 -->
        <p class="end-tiem audio-tiem">{{ allTime }}</p>
      </div>
    </div>

script

#部分代码涉及接口 接口我并没有写出来 不好意思
<script>
import { search, getSongDetail } from '@/api/find';
export default {
  name: 'myFooter',

  components: {},

  data() {
    return {
      audio: '',//audio的ref
      hotList: [],//歌曲完整列表
      staratTime: '00:00', //当前播放时间
      progressBarValue: 0,//进度条显示长度 默认为0 范围为0-100 使用前转换
      allTime: '00:00', //歌曲总时间
      isPause: true, //是否暂停 默认暂停
      songsIdList: [], //所有歌曲简化信息
      currentSongUnit: {}, //当前歌曲部分信息
    };
  },

  computed: {
    //歌曲的url
    audioSrc() {
      return `https://music.163.com/song/media/outer/url?id=${this.currentSongUnit.id}.mp3`;
    },
  },
  
  watch: {
  	//当歌曲audioSrc 发生变化时 重新执行load加载歌曲及 getSongDetail获取歌曲相信信息
    audioSrc() {
      this.audio.load();
      this.getSongDetail();
    },
  },

  mounted() {
    this.audio = this.$refs.audio; //获取audio的ref
    this.searchMusic();
  },

  methods: {
    //search接口获取陈奕迅的歌单数据 重写数组 只保留id 名字 上/下首歌曲id 
    async searchMusic() {
      const params = { keywords: '陈奕迅' };
      const { result } = await search(params);
      const hotList = result.songs;
      //获取上一曲下一曲id 当前歌曲id,name 重置id数组
      const songsIdList = hotList.map((item, index) => {
        const afterId = hotList[index + 1] ? hotList[index + 1].id : null;
        const beforeId = hotList[index - 1] ? hotList[index - 1].id : null;
        const arr = { id: item.id, name: item.name, afterId, beforeId };
        return arr;
      });
      this.hotList = hotList;//获取到的歌单信息
      this.songsIdList = songsIdList;//重写的数组
      this.currentSongUnit = songsIdList[0];//默认当前播放为第一条
      this.getSongDetail();//执行getSongDetail
    },
    //getSongDetail接口获取当前播放歌曲的详细信息 歌单信息内歌曲list信息不够完善
    async getSongDetail() {
      const { songs } = await getSongDetail(this.currentSongUnit.id);
      const song = songs[0];
      //处理song.ar对象内歌手大于一位时 拼接/ 例: 陈奕迅/薛之谦
      const singer =  song.ar.length > 1
          ? song.ar.map((it) => it.name).join(' / ')
          : song.ar[0].name;
      this.currentSongUnit = {
        ...this.currentSongUnit,
		songName: song.name,
		songAvatar: song.al.picUrl,
        singer,
      };
      this.play();//执行play方法 播放
    },
    //下一首 上一首  播放完毕也回执行该方法
    next(id) {
      if (!id) {  return false; }
      const nextList = this.songsIdList.find((it) => it.id === id);
      this.currentSongUnit = nextList;
    },
    //暂停
    stop() {
      this.audio.pause();
      this.isPause = true;
    },
    //播放 获取完整时间
    play() {
      this.allTime = this.filterDuration(this.audio.duration);
      this.audio.play();
      this.isPause = false;
    },
    //当歌曲实时播放时 获取当前播放时间 设置滚动条位置
    timeupdate() {
      this.staratTime = this.filterDuration(this.audio.currentTime);
      this.progressBarValue =
        (this.audio.currentTime / this.audio.duration) * 100;
      // console.log(this.audio.currentTime / this.audio.duration);
    },
    //拉动滚动条时候出发 松手触发
    sliderChange(e) {
      this.audio.currentTime = (e / 100) * this.audio.duration;
    },
    // 静音/禁止静音
    muted() {
      this.audio.muted = !this.audio.muted;
    },
    //转化时长显示
    filterDuration(s) {
      if (typeof s !== 'number') {
        throw new Error('传入时长需为数字类型');
      }
      let hour = Math.floor(s / 3600);
      let min = Math.floor((s % 3600) / 60);
      let sec = Math.floor(s % 60);

      hour = hour < 10 ? `0${hour}` : hour;
      min = min < 10 ? `0${min}` : min;
      sec = sec < 10 ? `0${sec}` : sec;

      return `${min}:${sec}`;
    },
  },
};
</script>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hhua.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值