vue中可以用的音频播放demo,可以作为组件引入
vue中可以用的音频播放demo,可以作为组件引入
参考文章:
https://segmentfault.com/a/1190000012453975
https://blog.csdn.net/xzwwjl1314/article/details/107204842/
其中主要参考第二篇,但在进度条拖动上,获取鼠标当前位置遇到问题。
clickProgress这个方法
const position = e.clientX - e.currentTarget.offsetLeft
这个地方获取的e.clientX值为900多,是变化的,但是e.currentTarget.offsetLeft的值一直是41,导致一拖动按照百分比计算的播放时间直接因为分子太大直接到底
后面发下在0的位置,是917, e.clientX为变化,923,957,依次变化,变化的值就是点击后的当前鼠标位置
所以用 (e.clientX-917)/ 进度条总宽度 * 总时长,获得跳转时长
4/20 update:
clickProgress方法这里的固定距离,写死的917遇到不同情况会失效,因为917不可以写死。
后续根据屏幕估算,用了document.body.clientWidth * 0.74代替写死的数值
const fixedSpace = document.body.clientWidth * 0.74; // 这是根据屏幕估算的
clickProgress(event) { console.log(event); // 点击进度条时 更新音频时间和进度条 const e = event || window.event; const position = e.clientX - e.currentTarget.offsetLeft; // 当前点击的位置 const progressWidth = this.$refs.progress.offsetWidth; // 进度条总宽度 // 第一步确认固定距离 878 减去固定距离就是剩余距离 const fixedSpace = document.body.clientWidth * 0.74; // 这是根据屏幕估算的 const space = position - fixedSpace; this.$refs.audio.currentTime = (space / progressWidth) * this.duration; this.updateProgress( (position / progressWidth) * this.duration, this.duration ); },
<template> <div> <div class="ckplayer"> <div class="bottom-progress"> <div class="curTime">{{ curTime ? curTime : "00:00" }}</div> <div class="progress" @click="clickProgress($event)" ref="progress"> <div class="line" :style="{ width: `${precent}` }"></div> <div class="dot" :style="{ left: `${precent}` }" @touchstart="dotStart" @touchmove="dotMove" @touchend="dotEnd" ></div> </div> <div class="allTime">{{ allTime }}</div> </div> <div class="bottom-controls"> <div class="prev" @click="prevSong"> <!-- <i class="pre"></i> --> </div> <div class="pause" v-show="isPlaying" @click="pauseSong"> <!-- <i class="fa fa-pause">暂停</i> --> </div> <div class="play" v-show="!isPlaying" @click="playSong"> <!-- <i class="fa fa-play">播放</i> --> </div> <div class="next" @click="nextSong"></div> </div> <!-- autio标签 --> <audio @timeupdate="updateTime" @canplay="getDuration" @ended="ended" :src="musicUrl" id="audio" ref="audio" class="testAudio" ></audio> </div> </div> </template> <script> import { boardListDetail } from "@/utils/api"; export default { data() { return { list: [], tvUrl: "", player: null, playingSong: {}, // 正在播放的歌曲信息 show: true, // 控制cd和lyrics的显示 默认显示cd isPlaying: false, // 播放和暂停状态 musicUrl: "", // 音乐地址 curTime: "00:00", // 当前播放时间,格式化之后的 allTime: "00:00", // 当前音频总时长,格式化之后的 duration: 0, // 音频总时长,单位秒 currentTime: 0, // 音频当前播放时间, 单位秒 precent: "0%", // 当前播放进度百分比 touchInfo: {}, // 原点滑动时的位置信息 lyrics: {}, // 歌词 中英文 lyricsObjArr: [], // 处理之后的歌词 包含时间和歌词 curMsTime: "", // 当前音频播放的时分毫秒 like: false, // 是否喜欢当前歌曲 默认为不喜欢 lyricIndex: "0", // 当前显示的歌词 isMuted: false, // 是否经验 默认不静音 volume: 100, // 音频音量 likeList: [], playType: 0, // 播放类型 0代表播放单曲 1代表播放歌曲列表 audios: [], index: 0, }; }, components: {}, created() { this.getAudio(); this.loadMusic(this.index); this.playType = this.audios.length === 1 ? 0 : 1; }, mounted() {}, methods: { async getAudio() { const res = await boardListDetail({ page: this.page, pagesize: this.pagesize, }); this.audios = res.data.items[0].audio_path; this.loadMusic(this.index); }, clickProgress(event) { console.log(event); // 点击进度条时 更新音频时间和进度条 const e = event || window.event; const position = e.clientX - e.currentTarget.offsetLeft; // 当前点击的位置 const progressWidth = this.$refs.progress.offsetWidth; // 进度条总宽度 // 第一步确认固定距离 878 减去固定距离就是剩余距离 const fixedSpace = document.body.clientWidth * 0.74; // 这是根据屏幕估算的 const space = position - fixedSpace; this.$refs.audio.currentTime = (space / progressWidth) * this.duration; this.updateProgress( (position / progressWidth) * this.duration, this.duration ); }, updateProgress(currentTime, duration) { // 更新进度条 const precent = `${((currentTime / duration) * 100).toFixed(5)}%`; this.precent = precent; }, dotEnd(e) { this.playSong(); this.isPlaying = true; }, dotMove(e) { console.log(e); // 移动的距离 let moveX = e.touches[0].pageX - 83; // console.log(moveX, "kk"); // 进度条的宽度 const progressWidth = this.$refs.progress.offsetWidth; if (moveX >= progressWidth) moveX = progressWidth; this.$refs.audio.currentTime = (moveX / progressWidth) * this.duration; this.updateProgress( (moveX / progressWidth) * this.duration, this.duration ); }, dotStart(e) { // 点击的初始位置 this.touchInfo.startX = e.touches[0].pageX - 83; }, formatTime(time) { if (time === 0) { this.curTime = "00:00"; return; } const mins = Math.floor(time / 60) < 10 ? `0${Math.floor(time / 60)}` : Math.floor(time / 60); const sec = Math.floor(time % 60) < 10 ? `0${Math.floor(time % 60)}` : Math.floor(time % 60); return `${mins}:${sec}`; }, ended() { this.$refs.audio.currentTime = 0; this.isPlaying = false; // if (this.playType === 0) { // this.$message.warning("歌曲列表只有这一首 请返回上一级!"); // this.curTime = "00:00"; // return; // } // if (this.index >= this.audios.length - 1) { // } this.nextSong(); console.log("播放完毕"); this.curTime = "00:00"; }, updateTime(e) { // timeupdate时获取当前播放时间 const { currentTime } = e.target; // console.log(e.target.currentTime, "看看"); this.currentTime = currentTime; this.curTime = this.formatTime(currentTime) === "undefined" ? "00:00" : this.formatTime(currentTime); this.updateProgress(currentTime, this.duration); // console.log(this.formatTime(currentTime), "k"); }, loadMusic(index) { // 加载播放地址 this.musicUrl = this.audios[index]; console.log(this.musicUrl, this.audios[index]); }, playSong() { console.log("5"); // 手动点击播放歌曲 const audio = this.$refs.audio; this.isPlaying = !this.isPlaying; audio.play(); }, autoPlaySong() { // 自动播放歌曲 const audio = this.$refs.audio; audio.autoplay = true; this.isPlaying = true; }, nextSong() { console.log("进下一首"); this.$refs.audio.currentTime = 0; // this.isPlaying = false; this.curTime = "00:00"; // 播放下一首歌曲 this.index++; if (this.index > this.audios.length - 1) { this.index = 0; } console.log(this.index); this.loadMusic(this.index); this.autoPlaySong(); }, prevSong() { console.log("上一首"); this.$refs.audio.currentTime = 0; // this.isPlaying = false; this.curTime = "00:00"; // 播放上一首歌曲 this.index--; if (this.index < 0) { this.index = this.audios.length - 1; } console.log(this.index, this.curTime); this.loadMusic(this.index); this.autoPlaySong(); }, pauseSong() { console.log("6"); // 暂停歌曲 this.isPlaying = !this.isPlaying; this.$refs.audio.pause(); }, getDuration() { // canplay时获取音频总时长 this.duration = this.$refs.audio.duration; this.allTime = this.formatTime(this.$refs.audio.duration); }, }, }; </script> <style scoped lang="scss"> .ckplayer { width: 100%; height: 25vh; position: absolute; top: 7%; left: 5.5%; width: 89%; height: 82%; .testAudio { width: 100%; height: 100%; background: red; } } .bottom { height: 20%; color: #fff; &-line1 { font-size: 0.8vw; display: flex; align-items: center; justify-content: space-around; } &-progress { padding: 0 5%; // margin: 5% 0; display: flex; align-items: center; justify-content: space-between; .progress { height: 0.2vh; background-color: #fff; width: 70%; position: relative; .line { position: absolute; left: 0; top: 0; height: 0.1vh; background-color: skyblue; transition: width 0.1s; } .dot { width: 0.5vw; height: 1vh; border-radius: 50%; position: absolute; top: -0.4vh; background-color: #ccc; transition: left 0.1s; } } } &-controls { padding: 0 5%; display: flex; align-items: center; justify-content: space-around; font-size: 30px; padding: 0 3vw; .prev { width: 1.3vw; height: 2.5vh; background: url("../assets/pre.png") no-repeat; background-size: 100% 100%; cursor: pointer; } .next { width: 1.3vw; height: 2.5vh; background: url("../assets/next.png") no-repeat; background-size: 100% 100%; cursor: pointer; } .pause { width: 4vw; height: 8vh; background: url("../assets/pause.png") no-repeat; background-size: 100% 100%; cursor: pointer; } .play { width: 4vw; height: 8vh; background: url("../assets/play.png") no-repeat; background-size: 100% 100%; cursor: pointer; } } } </style>
你好,我是Jane,如果万幸对您有用,请帮忙点下推荐,谢谢啦~另外,咱们闪存见哦~