Eric小屋

  • 一、播放/暂停
  • 二、上一曲/下一曲
  • 三、列表循环/随机循环/单曲循环
  • 四、自动播放
  • 五、自适应方案
  • 首页
  • 学习笔记
    • JAVA
    • Spring
    • Node.js
    • Vue
  • 学习文档
  • 案例项目
  • 课程笔记
  • 问题解决
登录

音频播放器组件 — 开发文档

  • Eric
  • 2024-05-16
  • 0

首先,要使用ref将<video>标签进行绑定

const audioCtr = ref(null)
<video src="#" ref="audioCtr" autoplay></video>

一、播放/暂停

要实现播放暂停功能,需要添加两个方法,一个是播放方法,一个是暂停方法,使用的是video标签自带的方法,来实现播放器内部的暂停和播放。

然后添加一个暂停播放的icon图标,绑定一个方法,可以控制播放器的暂停和播放

const isPlay = ref(false)
<video src="#" ref="audioCtr" autoplay @play="playFn"@pause="pauseFn"></video>
<div class="status" @click="changePlayStatus">
// 改变播放状态
function changePlayStatus() {
    if (!audioCtr.value) return
    if (isPlay.value) {
        audioCtr.value.pause()
    } else {
        audioCtr.value.play()
    }
}
// 监听开始事件
function playFn(e) {
    console.log('开启播放状态');
    isPlay.value = true
    emit('play', e)
}
// 监听暂停事件
function pauseFn(e) {
    console.log('暂停播放状态');
    isPlay.value = false
    emit('pause', e)
}

二、上一曲/下一曲

首先,添加两个icon图标,绑定两个方法,然后改变当前播放歌曲的下标,然后做一个watch监听,下标改变时就会自动切歌,播放器内部会变化播放的歌曲,例如下标 + + 就是下一曲,下标 - - 就是下一曲。

<i class="iconfont icon-shangyiqu" @click="preSong"></i>

<i class="iconfont icon-xiayiqu" @click="nextSong"></i>
// 下标发生改变 自动切歌
watch(playingIndex, (newVal, oldVal) => {
    setPlayingInfoByIndex(newVal)
    emit('change', newVal)
})

// 上一曲
function preSong() {
    if (loopType.value != 2) {
        if (playingIndex.value <= 0) {
            playingIndex.value = prop.srcList.length - 1
            return
        }
        playingIndex.value--
    } else {
        loopDict[loopType.value].fn()
    }
}
// 下一曲
function nextSong() {
    if (loopType.value != 2) {
        if (playingIndex.value >= prop.srcList.length - 1) {
            playingIndex.value = 0
            return
        }
        playingIndex.value++
    } else {
        loopDict[loopType.value].fn()
    }
}

三、列表循环/随机循环/单曲循环

首先有一个,对象数组,里面包含了,三种状态的类型下标、css图表样式、对应播放模式的方法。

const loopDict = [
    {
        type: 0,
        css: 'iconfont icon-liebiaoxunhuan',
        fn: () => {
            nextSong()
        }
    },
    {
        type: 1,
        css: 'iconfont icon-danquxunhuan',
        fn: () => {
            audioCtr.value.src = '#'
            setPlayingInfoByIndex(playingIndex.value)
        }
    },
    {
        type: 2,
        css: 'iconfont icon-suijibofang',
        fn: () => {
            while (true) {
                const newIndex = Math.floor(prop.srcList.length * Math.random())
                if (playingIndex.value != newIndex) {
                    playingIndex.value = newIndex;
                    break;
                }
            }
        }
    }
]

之后将他们绑定在一个div里面,使他可以点击更换不同的样式和方法。

<div class="loop" @click="changeLoop">
  <i :class="loopDis"></i>
</div>
// 更新循环方案
function changeLoop() {
    let index = loopDict.findIndex(i => i.type == loopType.value)
    if (index == loopDict.length - 1) {
        loopType.value = 0
    } else {
        loopType.value++
    }
    emit('uploop', loopType.value)
}

四、自动播放

使一首歌播放结束以后,可以自动播放下一首歌。

首先要做一个播放结束以后触发的方法,之后还要给video标签添加autoplay

<video src="#" ref="audioCtr" autoplay @play="playFn" @timeupdate="timeupdateFn" @canplay="canplayFn" @pause="pauseFn" @ended="endedFn"></video>
// 播放完成的回调事件
function endedFn() {
    loopDict[loopType.value].fn()
}

五、自适应方案

使用VW适配方案,需要下载postcss-px-to-viewport插件

然后添加配置代码:

// postcss.config.js
export default {
    plugins: {
        'postcss-px-to-viewport': {
            viewportWidth: 375,
        },
    },
};

之后,我们在css中输入px,会自动帮我们转换为vw。
联系作者:2572976830@qq.com
© 2025 Eric小屋
Theme by Wing
京ICP备2023032157号 京公网安备11011402053616号
  • {{ item.name }}
  • {{ item.name }}