<template>
|
<div
|
class="di main-wrap"
|
v-loading="audio.waiting"
|
element-loading-text="音视频加载中"
|
element-loading-spinner="el-icon-loading"
|
>
|
<!-- 这里设置了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>
|
<!-- 播放 -->
|
<i
|
class="el-icon-microphone"
|
v-if="audio.playing == true"
|
style="color: rgb(10 243 61); font-size: 18px"
|
></i>
|
<i class="el-icon-microphone" v-else style="font-size: 18px"></i>
|
<el-button style="margin: 0 10px" type="text" @click="startPlayOrPause">{{
|
audio.playing | transPlayPause
|
}}</el-button>
|
|
<!-- 播放最大时间 -->
|
<span type="info">{{ audio.maxTime | formatSecond }}</span>
|
|
<!-- 快进按钮 -->
|
<el-button
|
v-show="!controlList.noSpeed"
|
type="text"
|
@click="changeSpeed"
|
>{{ audio.speed | transSpeed }}</el-button
|
>
|
<a
|
:href="url"
|
v-show="!controlList.noDownload"
|
target="_blank"
|
class="download"
|
download
|
>下载</a
|
>
|
<br />
|
|
<!-- 播放时间 -->
|
<!-- <el-tag type="info">{{ audio.currentTime | formatSecond }}</el-tag> -->
|
|
<!-- 播放进度条 -->
|
<el-slider
|
v-show="!controlList.noProcess"
|
v-model="sliderTime"
|
:format-tooltip="formatProcessToolTip"
|
@change="changeCurrentTime"
|
class="slider"
|
></el-slider>
|
|
<!-- 静音按钮 -->
|
<!-- <el-button
|
v-show="!controlList.noMuted"
|
type="text"
|
@click="startMutedOrNot"
|
>{{ audio.muted | transMutedOrNot }}</el-button
|
> -->
|
|
<!-- 音量大小 -->
|
<el-slider
|
v-show="!controlList.noVolume"
|
v-model="volume"
|
:format-tooltip="formatVolumeToolTip"
|
@change="changeVolume"
|
class="slider"
|
></el-slider>
|
</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];
|
},
|
},
|
theControlList: {
|
type: String,
|
default: "",
|
},
|
},
|
data() {
|
return {
|
url: this.theUrl,
|
audio: {
|
currentTime: 0,
|
maxTime: 0, // 音频时长
|
playing: false, // 是否在播放
|
muted: false,
|
speed: 1,
|
waiting: false,
|
preload: "auto",
|
},
|
sliderTime: 0,
|
volume: 100,
|
speeds: this.theSpeeds,
|
controlList: {
|
// 不显示下载
|
noDownload: false,
|
// 不显示静音
|
noMuted: false,
|
// 不显示音量条
|
noVolume: false,
|
// 不显示进度条
|
noProcess: false,
|
// 只能播放一个
|
onlyOnePlaying: false,
|
// 不要快进按钮
|
noSpeed: false,
|
},
|
};
|
},
|
methods: {
|
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() {
|
// console.log("播放");
|
this.$refs.audio.play();
|
},
|
// 暂停播放
|
pausePlay() {
|
// console.log("暂停");
|
this.$refs.audio.pause();
|
},
|
|
// 音频暂停时触发
|
onPause() {
|
this.audio.playing = false;
|
},
|
// 音频错误时触发
|
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();
|
}
|
});
|
},
|
// 播放数量限制(同时只能播放一个)
|
setControlList() {
|
// 注意父组件传的值是否满足要求
|
let controlList = this.theControlList.split(" ");
|
controlList.forEach((item) => {
|
if (this.controlList[item] !== undefined) {
|
this.controlList[item] = true;
|
}
|
});
|
},
|
|
// 当timeupdate事件大概每秒一次,用来更新音频流的当前播放时间
|
onTimeupdate(res) {
|
this.audio.currentTime = res.target.currentTime;
|
this.sliderTime = parseInt(
|
(this.audio.currentTime / this.audio.maxTime) * 100
|
);
|
},
|
|
// 当加载语音流元数据完成后,会触发该事件的回调函数
|
onLoadedmetadata(res) {
|
// 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;
|
},
|
},
|
created() {
|
this.setControlList();
|
},
|
};
|
</script>
|
|
<style scoped>
|
.slider {
|
display: inline-block;
|
width: 100px;
|
position: relative;
|
top: 14px;
|
margin-left: 15px;
|
}
|
.di {
|
display: inline-block;
|
}
|
.download {
|
color: #409eff;
|
margin-left: 15px;
|
}
|
.dn {
|
display: none;
|
}
|
</style>
|