vue-AudioComponent 音频播放组件
本文参考https://blog.csdn.net/weixin_40404336/article/details/84570070感谢上面博主分享,为了方便前端开发人员查阅,提供新的连接。~_~.下面代码有个细节,slider滑块这里采用的vant,原理同上。定义vue 文件 :vueAudio.vue,代码内容如下:(引用代码后,在其他页面导入该组件即可,不懂的可以看上面博主分享...
本文参考 https://blog.csdn.net/weixin_40404336/article/details/84570070
感谢上面博主分享,为了方便前端开发人员查阅,提供新的连接。~_~.
下面代码有个细节,slider滑块这里采用的vant,原理同上。
定义vue 文件 :vueAudio.vue,代码内容如下:(引用代码后,在其他页面导入该组件即可,不懂的可以看上面博主分享)
<template>
<div class="di main-wrap">
<!-- 这里设置了ref属性后,在vue组件中,就可以用this.$refs.audio来访问该dom元素 -->
<template>
<div class="di main-wrap">
<!-- 这里设置了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>
<!-- 倍率播放速度 -->
<!-- <el-button v-show="!controlList.noSpeed" type="text" @click="changeSpeed">{{audio.speed | transSpeed}}</el-button> -->
<div class="boxs">
<div class="track">
<!-- <el-tag type="info">{{ audio.currentTime | formatSecond}}</el-tag> -->
<div class="times startT" @click="startPlayOrPause">播放</div>
<div class="sliders-box">
<!-- <el-slider
v-show="!controlList.noProcess"
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">{{ audio.maxTime | formatSecond }}</div>
<!-- <el-tag type="info">{{ audio.maxTime | 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="audio.playing | transPlayPause" width="100%" alt />
</div>
<!-- <el-button type="text" @click="startPlayOrPause">{{audio.playing | transPlayPause}}</el-button> -->
<div class="forward" @click="add">
<div style="width:20px;height:20px;background:blue"></div>
</div>
</div>
<!-- <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> -->
<!-- <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)
return ("0" + mimute).slice(-2) + ":" + ("0" + second).slice(-2);
} else {
return "00:00";
}
}
import { Slider } from "vant";
import "vant/lib/index.css";
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: this.theUrl || "http://res01.zyxschool.com/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: this.theSpeeds, // 播放速度
controlList: {
// 不显示下载
noDownload: false,
// 不显示静音
noMuted: false,
// 不显示音量条
noVolume: false,
// 不显示进度条
noProcess: false,
// 只能播放一个
onlyOnePlaying: false,
// 不要快进按钮
noSpeed: false
}
};
},
methods: {
setControlList() {
let controlList = this.theControlList.split(" ");
controlList.forEach(item => {
// console.log(this.controlList[item]);
if (this.controlList[item] !== undefined) {
this.controlList[item] = 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);
//this.audio.maxTime = parseInt( this.$refs.audio.duration);
console.log("总时间", this.$refs.audio.duration);
this.$emit("loading-true", 11);
},
add() {
//前进15s
let current_t = parseInt(this.$refs.audio.currentTime);
let total_t = parseInt(this.$refs.audio.duration);
//console.log(this.$refs.audio);
this.$refs.audio.currentTime =
current_t + 15 >= total_t ? total_t : current_t + 15;
console.log(current_t, total_t, this.$refs.audio.currentTime);
// console.log(this.$refs.audio.played);
},
minus() {
//后退15秒
let current_t = parseInt(this.$refs.audio.currentTime);
this.$refs.audio.currentTime = current_t - 15 <= 0 ? 0 : current_t - 15;
}
},
watch: {},
filters: {
formatSecond(second = 0) {
return realFormatSecond(second);
},
transPlayPause(value) {
// console.log(value);
//return value ? require("../assets/img/pause.png") : require("../assets/img/play.png")
return "123";
},
transMutedOrNot(value) {
return value ? "放音" : "静音";
},
transSpeed(value) {
return "快进: x" + value;
}
},
watch: {
url(val, oldval) {
console.log(val, oldval);
},
sliderTime(val, oldval) {
// console.log(val,oldval);
if (val >= 98) {
this.L = 98;
return;
}
this.L = val;
}
},
created() {
// let audio = new Audio();
// audio.src = this.url; //audio链接
// audio.addEventListener('loadedmetadata', function() {
// console.log(audio.duration);
// //
// });
this.setControlList();
}
};
</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>
更多推荐
所有评论(0)