vue2使用audio标签实现播放外部音频

在audio标签中存在如下属性:

autoplay:是否音频在就绪后马上播放。

controls:是否向用户显示控件,比如播放按钮。

loop:是否音频结束时重新开始播放。

preload:是否音频在页面加载时进行加载,并预备播放。如果使用 “autoplay”,则忽略该属性。

src:要播放的音频的 URL。

HTML5 audio支持的音频格式有wav,mp3和ogg格式。

ogg:一种新的音频压缩格式,是完全免费、开放和没有专利限制的。

mp3:是一种音频压缩技术。它被设计用来大幅度地降低音频数据量。

wav:为微软公司开发的一种声音文件格式,声音文件质量和CD相差无几。

以下为组件代码:

//VueAudio.vue
<template>
  <div class="di main-wrap" v-loading="audio.waiting">
    <!-- 这里设置了ref属性后,在vue组件中,就可以用this.$refs.audio来访问该dom元素 -->
    <audio ref="audio" class="dn" 
        :src="url" :preload="audio.preload"
        @play="onPlay" 
        @error="onError"
        @waiting="onWaiting"
        @pause="onPause" 
        @timeupdate="onTimeupdate" 
        @loadedmetadata="onLoadedmetadata"
        ></audio>
    <div>
    //音量条
    <div class="volume" v-show="volumeShow">
        <el-slider v-show="!controlList.noVolume" v-model="volume"  @change="changeVolume" class="sliderMute" vertical height="80px"></el-slider>
    </div>
    //播放显示
    <div class="progress">
        <el-tag type="info">{{ audio.currentTime | formatSecond}}</el-tag>
        <div class="progressBar">
            <el-slider v-show="!controlList.noProcess" v-model="sliderTime" :format-tooltip="formatProcessToolTip" @change="changeCurrentTime" class="slider" ></el-slider>
        </div>
        <el-tag type="info">{{ audio.maxTime | formatSecond }}</el-tag>
        <div class="mute" @click.stop="onVolume">
            <img class="muteImg" src="../../../../assets/image/yl02.png" alt="" v-if="80<=volume">
            <img class="muteImg" src="../../../../assets/image/yl04.png" alt="" v-else-if="volume > 40 && volume < 80">
            <img class="muteImg" src="../../../../assets/image/yl03.png" alt="" v-else-if="volume > 0 && volume <= 40">            
            <img class="muteImg" src="../../../../assets/image/yl01.png" alt="" v-else>
        </div>
    </div>
      
    //静音
    <el-button v-show="!controlList.noMuted" type="text" @click="startMutedOrNot">{{audio.muted | transMutedOrNot}}</el-button>
    //播放/暂停
    <div class="playButton">
        <el-button type="theme" @click="startPlayOrPause" size="small">{{audio.playing | transPlayPause}}</el-button>
        <el-button v-show="!controlList.noSpeed" type="theme" size="small" @click="changeSpeed">{{audio.speed | transSpeed}}</el-button>
    </div>      
      //下载
    <a :href="url" v-show="!controlList.noDownload" target="_blank" class="download" download>下载</a>
    </div>
  </div>
</template>

<script>
  function realFormatSecond(second) {
    var secondType = typeof second

    if (secondType === 'number' || secondType === 'string') {
      second = parseInt(second)

      var hours = Math.floor(second / 3600)
      second = second - hours * 3600
      var mimute = Math.floor(second / 60)
      second = second - mimute * 60

      return hours + ':' + ('0' + mimute).slice(-2) + ':' + ('0' + second).slice(-2)
    } else {
      return '0:00:00'
    }
  }

  export default {
    props: {
      theUrl: {
        type: String,
        required: true,
      },
      theSpeeds: {
        type: Array,
        default () {
          return [1, 1.5, 2]
        }
      },
    },
    name: 'VueAudio',
    data() {
      return {
        url: this.theUrl || 'http://devtest.qiniudn.com/secret base~.mp3',
        audio: {
          currentTime: 0,
          maxTime: 0,
          playing: false,
          muted: false,
          speed: 1,
          waiting: true,
          preload: 'auto'
        },

        sliderTime: 0,
        volume: 100,
        speeds: this.theSpeeds,

        controlList: {
          // 不显示下载
          noDownload: false,
          // 不显示静音
          noMuted: false,
          // 不显示音量条
          noVolume: false,
          // 不显示进度条
          noProcess: false,
          // 只能播放一个
          onlyOnePlaying: false,
          // 不要快进按钮
          noSpeed: false
        },
        volumeShow: false,
      }
    },
    methods: {
        //音量条的显示与隐藏
        onVolume(event){
            if(this.volumeShow){
                this.volumeShow = false
            }else{
                this.volumeShow = true
            }
        },
        //快进
        changeSpeed() {
            let index = this.speeds.indexOf(this.audio.speed) + 1
            this.audio.speed = this.speeds[index % this.speeds.length]
            this.$refs.audio.playbackRate = this.audio.speed
        },
        //静音
        startMutedOrNot() {
            this.$refs.audio.muted = !this.$refs.audio.muted
            this.audio.muted = this.$refs.audio.muted
        },
        // 音量条toolTip
        formatVolumeToolTip(index) {
            return '音量条: ' + index
        },
        // 进度条toolTip
        formatProcessToolTip(index = 0) {
            index = parseInt(this.audio.maxTime / 100 * index)
            return '进度条: ' + realFormatSecond(index)
        },
        // 音量改变
        changeVolume(index = 0) {
            this.$refs.audio.volume = index / 100
            this.volume = index
        },
        // 播放跳转
        changeCurrentTime(index) {
            this.$refs.audio.currentTime = parseInt(index / 100 * this.audio.maxTime)
        },
        //播放/暂停
        startPlayOrPause() {
            return this.audio.playing ? this.pausePlay() : this.startPlay()
        },
        // 开始播放
        startPlay() {
            this.$refs.audio.play()
        },
        // 暂停
        pausePlay() {
            this.$refs.audio.pause()
        },
        // 当音频暂停
        onPause () {
            this.audio.playing = false
        },
        // 当发生错误, 就出现loading状态
        onError () {
            this.audio.waiting = true
        },
        // 当音频开始等待
        onWaiting (res) {
            console.log(res)
        },
        // 当音频开始播放
        onPlay (res) {
            console.log(res)
            this.audio.playing = true
            this.audio.loading = false

            if(!this.controlList.onlyOnePlaying){
            return 
            }

            let target = res.target

            let audios = document.getElementsByTagName('audio');

            [...audios].forEach((item) => {
            if(item !== target){
                item.pause()
            }
            })
        },
        // 当timeupdate事件大概每秒一次,用来更新音频流的当前播放时间
        onTimeupdate(res) {
            // console.log('timeupdate')
            // console.log(res)
            this.audio.currentTime = res.target.currentTime
            this.sliderTime = parseInt(this.audio.currentTime / this.audio.maxTime * 100)
        },
        // 当加载语音流元数据完成后,会触发该事件的回调函数
        // 语音元数据主要是语音的长度之类的数据
        onLoadedmetadata(res) {
            console.log('loadedmetadata')
            console.log(res)
            this.audio.waiting = false
            this.audio.maxTime = parseInt(res.target.duration)
        }
    },
    filters: {
      formatSecond(second = 0) {
        return realFormatSecond(second)
      },
      transPlayPause(value) {
        return value ? '暂停' : '播放'
      },
      transMutedOrNot(value) {
        return value ? '放音' : '静音'
      },
      transSpeed(value) {
        return '快进: x' + value
      }
    },
  }

</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  .main-wrap{
    padding: 10px 15px;
  }
  .progress{
    height: 40px;
    width: 400px;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-around;
    border-radius: 14px;
    box-shadow: rgba(0, 0, 0, 0.2) 1px 2px 10px;

  }
  .volume{
    position: absolute;
    top: 53px;
    left: 445px;
    border-radius: 10px;
    padding: 5px 0px;
    box-shadow: rgba(0, 0, 0, 0.2) 1px 2px 10px;
  }
.progressBar{
    height: 25px;
    width: 160px;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    
  }
  .mute{
    height: 20px;
    width: 20px;
    cursor: pointer;
  }
  .muteImg{
    height: 20px;
    width: 20px;
  }
  .slider {
    display: inline-block;
    width: 150px;
    position: relative;
    /* top: 14px;
    margin-left: 15px; */
  }
  .sliderMute{
    display: inline-block;
    position: relative;
  }
  /deep/ .el-slider__button{
    width: 0px !important;
    height: 0px !important;
  }
  .di {
    display: inline-block;
  }

  .download {
    color: #409EFF;
    margin-left: 15px;
  }

  .dn{
    display: none;
  }
.playButton{
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    margin-top: 30px;
}
</style>

在父组件中使用:

<template>
    <div>
        <div class="custm-form-item" v-for="(item,index) in audioList" :key="index">
            <el-button @click="aclick(item.url)">{{item.name}}</el-button>
        </div>
        <el-dialog title="录音"  :visible.sync="audioLoging" width="580px!important" style="margin-top: 130px;" :close-on-click-modal="false" :destroy-on-close="true" :modal="false">
            <div style="height: 278px;display: flex;flex-direction: column;align-items: center;justify-content: center;" @click.stop="handleChangeAudioVolume" >
                 <VueAudio ref="audio" :theUrl="music_path" :theControlList="'onlyOnePlaying'"/>
            </div>
        </el-dialog>
    </div>
</template>

<script>
import VueAudio from './VueAudio.vue'

export default {
    data() {
        return {
            music_path: '',
            audioList: [
                {
                    name: '录音1',
                    url: require('../../../../assets/record/recorder.wav'),
                    controlList: 'onlyOnePlaying'
                },
                {
                    name: '录音2',
                    url: require('../../../../assets/record/falling-star.mp3'),
                    controlList: 'onlyOnePlaying'
                },
            ],
            audioLoging: false,
        }
    },
    methods: {
        handleChangeAudioVolume() {//点击空白关闭音量显示
            if (this.$refs.audio) this.$refs.audio.volumeShow = false
        },
        aclick(src) { //打开弹框
            this.audioLoging = true
            this.music_path = src
		},
    }
}
</script>

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用 Vue.js 控制 HTML5 音频按顺序播放的示例代码: ```html <template> <div> <audio ref="audio" controls @ended="playNext"> <source v-for="(src, index) in sources" :key="index" :src="src" type="audio/mpeg"> Your browser does not support the audio tag. </audio> </div> </template> <script> export default { data() { return { sources: ['audio1.mp3', 'audio2.mp3', 'audio3.mp3'], index: 0 }; }, methods: { playNext() { this.index++; // 播放索引加 1 if (this.index < this.sources.length) { this.$refs.audio.src = this.sources[this.index]; // 切换到下一个音频文件 this.$refs.audio.play(); // 播放音频 } } }, mounted() { this.$refs.audio.src = this.sources[this.index]; // 设置第一个音频文件的路径 this.$refs.audio.play(); // 播放第一个音频文件 } }; </script> ``` 这个代码示例中,我们使用Vue.js 的 `ref` 属性来获取 `audio` 元素的引用,并使用 `v-for` 指令动态生成多个 `source` 元素以设置多个音频文件的路径。在 `data` 中定义了一个 `sources` 数组来存储所有音频文件的路径,以及一个 `index` 变量来记录当前播放的是哪个音频文件。在 `methods` 中定义了一个 `playNext` 方法,用于在监听到音频播放结束事件时切换到下一个音频文件并播放。在 `mounted` 生命周期钩子中,我们设置了第一个音频文件的路径,并调用 `play()` 方法开始播放。 这个示例代码中,只需要将所有音频文件的路径添加到 `sources` 数组中即可,Vue.js 代码会自动按顺序播放这些音频文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值