本文参考 /weixin_40404336/article/details/84570070
感谢上面博主分享,为了方便前端开发人员查阅,提供新的连接。~_~.
下面代码有个细节,slider滑块这里采用的vant,原理同上。
定义vue 文件 :,代码内容如下:(引用代码后,在其他页面导入该组件即可,不懂的可以看上面博主分享)
<template>
<div class="di main-wrap">
<!-- 这里设置了ref属性后,在vue组件中,就可以用this.$来访问该dom元素 -->
<template>
<div class="di main-wrap">
<!-- 这里设置了ref属性后,在vue组件中,就可以用this.$来访问该dom元素 -->
<audio
ref="audio"
class="dn"
:src="url"
:preload=""
@play="onPlay"
@error="onError"
@waiting="onWaiting"
@pause="onPause"
@timeupdate="onTimeupdate"
@loadedmetadata="onLoadedmetadata"
></audio>
<div>
<!-- 倍率播放速度 -->
<!-- <el-button v-show="!" type="text" @click="changeSpeed">{{ | transSpeed}}</el-button> -->
<div class="boxs">
<div class="track">
<!-- <el-tag type="info">{{ | formatSecond}}</el-tag> -->
<div class="times startT" @click="startPlayOrPause">播放</div>
<div class="sliders-box">
<!-- <el-slider
v-show="!"
v-model="sliderTime"
:format-tooltip="formatProcessToolTip"
@change="changeCurrentTime"
class="slider"
></el-slider>-->
<vanSlider
v-model="sliderTime"
:inactive-color="'#EBEBEB'"
:bar-height="'2vw'"
:active-color="'#0096F0'"
@change="changeCurrentTime"
>
<!-- <div slot="button" class="custom-button">a</div> -->
</vanSlider>
</div>
<div class="times endT">{{ | formatSecond }}</div>
<!-- <el-tag type="info">{{ | formatSecond }}</el-tag> -->
</div>
</div>
<div class="operation">
<div class="back-box" @click="minus">
<div style="width:20px;height:20px;background:red"></div>
</div>
<div class="play-bt" @click="startPlayOrPause">
<img :src=" | transPlayPause" width="100%" alt />
</div>
<!-- <el-button type="text" @click="startPlayOrPause">{{ | transPlayPause}}</el-button> -->
<div class="forward" @click="add">
<div style="width:20px;height:20px;background:blue"></div>
</div>
</div>
<!-- <el-button v-show="!" type="text" @click="startMutedOrNot">{{ | transMutedOrNot}}</el-button> -->
<!-- <el-slider v-show="!" v-model="volume" :format-tooltip="formatVolumeToolTip" @change="changeVolume" class="slider"></el-slider> -->
<!-- <a :href="url" v-show="!" 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 = (second / 3600);
second = second - hours * 3600;
var mimute = (second / 60);
second = second - mimute * 60;
// return hours + ':' + ('0' + mimute).slice(-2) + ':' + ('0' + second).slice(-2)
return ("0" + mimute).slice(-2) + ":" + ("0" + second).slice(-2);
} else {
return "00:00";
}
}
import { Slider } from "vant";
import "vant/lib/";
export default {
components: {
vanSlider: Slider
},
props: {
//音频路径
theUrl: {
type: String,
required: true
},
//播放速度 未测试
theSpeeds: {
type: Array,
default() {
return [1, 1.5, 2];
}
},
//
theControlList: {
type: String,
default: ""
}
},
name: "VueAudio",
data() {
return {
L: 0,
url: || "/images/ti100audio/201909/2019/1569407886_019499.mp3",
audio: {
currentTime: 0,//当前播放时间
maxTime: 0,//最大时长
playing: false, //是否自动播放
muted: false, //是否静音
speed: 1,//播放速度
waiting: true, // 处于等待状态
preload: "auto" //是否重新播放
},
sliderTime: 0, //开始播放位置,
volume: 100,//音量
speeds: , // 播放速度
controlList: {
// 不显示下载
noDownload: false,
// 不显示静音
noMuted: false,
// 不显示音量条
noVolume: false,
// 不显示进度条
noProcess: false,
// 只能播放一个
onlyOnePlaying: false,
// 不要快进按钮
noSpeed: false
}
};
},
methods: {
setControlList() {
let controlList = (" ");
(item => {
// ([item]);
if ([item] !== undefined) {
[item] = true;
}
});
},
changeSpeed() {
let index = () + 1;
= [index % ];
this.$ = ;
},
startMutedOrNot() {
this.$ = !this.$;
= this.$;
},
// 音量条toolTip
formatVolumeToolTip(index) {
return "音量条: " + index;
},
// 进度条toolTip
formatProcessToolTip(index = 0) {
index = parseInt(( / 100) * index);
return "进度条: " + realFormatSecond(index);
},
// 音量改变
changeVolume(index = 0) {
this.$ = index / 100;
= index;
},
// 播放跳转
changeCurrentTime(index) {
this.$ = parseInt(
(index / 100) *
);
},
startPlayOrPause() {
return ? () : ();
},
// 开始播放
startPlay() {
this.$();
},
// 暂停
pausePlay() {
this.$();
},
// 当音频暂停
onPause() {
= false;
},
// 当发生错误, 就出现loading状态
onError() {
= true;
},
// 当音频开始等待
onWaiting(res) {
(res);
},
// 当音频开始播放
onPlay(res) {
// (res)
= true;
= false;
if (!) {
return;
}
let target = ;
let audios = ("audio");
[...audios].forEach(item => {
if (item !== target) {
();
}
});
},
// 当timeupdate事件大概每秒一次,用来更新音频流的当前播放时间
onTimeupdate(res) {
// ('timeupdate')
//(res)
= ;
= parseInt(
( / ) * 100
);
},
// 当加载语音流元数据完成后,会触发该事件的回调函数
// 语音元数据主要是语音的长度之类的数据
onLoadedmetadata(res) {
("loadedmetadata");
(res);
= false;
= parseInt();
// = parseInt( this.$);
("总时间", this.$);
this.$emit("loading-true", 11);
},
add() {
//前进15s
let current_t = parseInt(this.$);
let total_t = parseInt(this.$);
//(this.$);
this.$ =
current_t + 15 >= total_t ? total_t : current_t + 15;
(current_t, total_t, this.$);
// (this.$);
},
minus() {
//后退15秒
let current_t = parseInt(this.$);
this.$ = current_t - 15 <= 0 ? 0 : current_t - 15;
}
},
watch: {},
filters: {
formatSecond(second = 0) {
return realFormatSecond(second);
},
transPlayPause(value) {
// (value);
//return value ? require("../assets/img/") : require("../assets/img/")
return "123";
},
transMutedOrNot(value) {
return value ? "放音" : "静音";
},
transSpeed(value) {
return "快进: x" + value;
}
},
watch: {
url(val, oldval) {
(val, oldval);
},
sliderTime(val, oldval) {
// (val,oldval);
if (val >= 98) {
= 98;
return;
}
= val;
}
},
created() {
// let audio = new Audio();
// = ; //audio链接
// ('loadedmetadata', function() {
// ();
// //
// });
();
}
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.van-slider {
width: 100%;
}
.boxs {
display: flex;
justify-content: center;
position: fixed;
bottom: 14vw;
width: 100%;
border-bottom: 1px solid #dfdfdf;
}
.track {
background: #f8f8f8;
height: 15vw;
display: flex;
justify-content: flex-start;
align-items: center;
box-sizing: border-box;
width: 100%;
}
.times {
color: #fff;
}
.startT {
padding: 0 4vw;
color: #333333;
}
.endT {
padding: 0 4vw;
color: #333333;
}
.operation {
margin-top: 4vw;
display: flex;
justify-content: center;
align-items: center;
}
.play-bt {
font-size: 0;
width: 76px;
height: 75px;
}
.back-box {
margin-right: 50px;
}
.forward {
margin-left: 50px;
}
.back-box,
.forward {
font-size: 0;
width: 47px;
height: 46px;
}
.sliders-box {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.div_box {
height: 100px;
position: relative;
}
.div0 {
width: 10px;
height: 10px;
border-radius: 5px;
background: red;
position: absolute;
top: 0;
}
.main-wrap {
padding: 0;
}
.download {
color: #409eff;
margin-left: 15px;
}
.dn {
display: none;
}
</style>