<template>
|
<!--音频组件-->
|
<view>
|
<view>音频已经播放了:{{ playCount }}遍</view>
|
<view class="">
|
音频名称:{{ audioName }}
|
</view>
|
<view>
|
<text>Success 时长: {{ formattedDuration }}</text>
|
</view>
|
<view class="bgfff">
|
<view>
|
<view class="audo-video">
|
<!--音频播放按钮处-->
|
<view class="audo-top">
|
<!--上一首切换按钮-->
|
<!-- <image
|
v-if="jian"
|
style="width: 50rpx; height: 50rpx"
|
@click="nosig"
|
src="/static/sys.png"
|
mode="aspectFill"
|
></image>
|
<image
|
v-else
|
@click="sig"
|
src="/static/xys.png"
|
style="width: 50rpx; height: 50rpx; transform: rotate(180deg)"
|
mode="aspectFill"
|
></image> -->
|
<!--上一首切换按钮-->
|
<!--快退按钮-->
|
<!-- <i :class="succes ? 'el-icon-video-pause':'el-icon-video-play'"
|
mode="aspectFill"
|
style="width: 180rpx; height: 180rpx"
|
@click="plays()"></i> -->
|
<!-- <image
|
src="/static/kt.png"
|
style="width: 45rpx; height: 45rpx"
|
mode="aspectFill"
|
@click="kt()"
|
></image> -->
|
<!--快退按钮-->
|
<!--播放按钮-->
|
<image
|
:src="succes ? '/static/icon/bofang_1.png' : '/static/icon/bofang.png'"
|
mode="aspectFill"
|
style="width: 180rpx; height: 180rpx"
|
@click="plays()"
|
></image>
|
<!--播放按钮-->
|
<!--快进按钮-->
|
<!-- <image
|
src="/static/kj.png"
|
style="width: 45rpx; height: 45rpx"
|
mode="aspectFill"
|
@click="kj()"
|
></image> -->
|
<!--快进按钮-->
|
<!--下一首切换按钮-->
|
<!-- <image
|
v-if="jia"
|
@click="noxig"
|
style="width: 50rpx; height: 50rpx; transform: rotate(180deg)"
|
src="/static/sys.png"
|
mode="aspectFill"
|
>
|
</image>
|
<image
|
v-else
|
style="width: 50rpx; height: 50rpx"
|
src="/static/xys.png"
|
@click="xig"
|
mode="aspectFill"
|
></image> -->
|
|
<!--下一首切换按钮-->
|
|
</view>
|
|
<!--音频播放按钮处-->
|
|
<!--音频api处[视频代替音频-实现倍数功能]-->
|
|
<video
|
id="myVideo"
|
ref="myVideo"
|
:src="recorPath"
|
class="hidden"
|
@timeupdate="timeupdate"
|
:autoplay="autoplays"
|
@loadedmetadata="loadedmetadata"
|
@ended="next"
|
controls
|
style="width: 10rpx; height: 10rpx"
|
></video>
|
|
<!--音频api处[视频代替音频-实现倍数功能]-->
|
|
<view class="audo-a" style="margin: 0 auto">
|
<!--进度条-->
|
<view class="slider-box">
|
<text class="mm">{{ timer }}</text>
|
<slider
|
style="width: 370rpx"
|
@change="sliderChange"
|
@changing="sliderChanging"
|
class="audio-slider"
|
block-size="16"
|
:min="0"
|
:max="duration"
|
:value="currentTime"
|
activeColor="#FFA929"
|
@touchstart="lock = true"
|
@touchend="lock = false"
|
/>
|
<text class="ss" v-if="overTimer != 'NaN:NaN'">{{
|
overTimer
|
}}</text>
|
<text class="ss" v-else>00.00</text>
|
</view>
|
<!--进度条-->
|
<!--倍数-->
|
|
<view
|
class="beishu"
|
style="border: 3rpx solid #c8c9cc"
|
@click="beishu"
|
>{{ BsNav[bsindex].bs }} X
|
</view>
|
<view class="absolute" style="right: 0; top: 80rpx" v-if="shows">
|
<!-- <u-transition :show="show" mode="slide-right" duration="300"> -->
|
<view
|
class="beishu-a"
|
style="border: 2rpx solid #c8c9cc"
|
v-if="show"
|
>
|
<view
|
v-for="(item, index) in BsNav"
|
:key="index"
|
@click="setRate(index, item)"
|
class="title"
|
:style="{ color: bsid == item.id ? '#8D48FE' : '' }"
|
>
|
{{ item.bs }} X
|
</view>
|
</view>
|
<!-- </u-transition> -->
|
</view>
|
<!--倍数-->
|
</view>
|
</view>
|
|
</view>
|
|
</view>
|
<view class="h-100"></view>
|
<!--占位-->
|
</view>
|
<!--音频组件 Author:chenxin-->
|
</template>
|
<script>
|
export default {
|
name: "cx-audio-play",
|
props: {
|
list: {
|
//音频数据
|
Type: Array,
|
default: () => [],
|
},
|
Faskms: {
|
//快进秒数
|
Type: Number,
|
default: 15,
|
},
|
Slowms: {
|
//快退秒数
|
Type: Number,
|
default: 15,
|
},
|
autoNext: {
|
Type: Boolean,
|
default: false,
|
},
|
|
autoplays: {
|
|
//是否开启自动播放
|
|
Type: Boolean,
|
|
default: true,
|
|
},
|
|
slideYes: {
|
|
//滑动进度条 - 是否开启播放
|
|
Type: Boolean,
|
|
default: false,
|
|
},
|
|
switAud: {
|
|
Type: Boolean, //切换上下音频 - 是否开启播放
|
|
default: false,
|
|
},
|
|
BsNav: {
|
|
//倍数-传入
|
|
Type: Array,
|
|
default: () => [
|
|
{
|
id: 1.0,
|
bs: "1.0",
|
},
|
{
|
id: 1.5,
|
bs: "1.5",
|
},
|
{
|
id: 2.0,
|
bs: "2.0",
|
},
|
],
|
},
|
},
|
data() {
|
return {
|
audioName:'',
|
playCount:0,
|
shows: false, //倍数弹框
|
show: true, //倍数弹框动画默认开启
|
jian: true, //减-切换图标
|
jia: true, //加-切换图标
|
succes: true, //播放按钮
|
bsid: "", //倍数默认显示第一个
|
bsindex: 0, //倍数默认显示第一个
|
num: 0,
|
current: 0, //当前选中的索引
|
recorPath: "", //音频播放地址
|
lock: false, // 锁
|
currentTime: 0, //当前进度
|
duration: 100, // 总进度
|
duration1:0,
|
timer1:null,
|
videoContext: null,
|
loading: true, //锁 加载
|
currentPlayTime: 0, // 当前播放时间(秒)
|
formattedPlayTime: '00:00', // 格式化后的播放时间字符串
|
};
|
|
},
|
|
onReady() {},
|
onShow() {},
|
mounted() {
|
if (this.succes) {
|
this.startTimer();
|
}else{
|
this.stopTimer()
|
}
|
// 监听页面的卸载,确保清除计时器
|
this.$once('hook:beforeDestroy', () => {
|
this.stopTimer();
|
});
|
|
//默认播放第一个 -- 按钮展示
|
if (this.list.length != 0) {
|
this.recorPath = this.list[0].recorPath;
|
this.audioName = this.list[0].name
|
this.$nextTick(() => {
|
this.videoContext.play();
|
});
|
if (this.list.length > 1) {
|
//音频文件大于1 -- 下一个切换默认显示
|
this.jia = false;
|
if (this.autoplays) {
|
this.succes = true;
|
}
|
}
|
}
|
//倍数默认处理
|
if (this.BsNav.length != 0) {
|
this.bsid = this.BsNav[0].id;
|
this.$nextTick(() => {
|
//#ifdef H5
|
this.$refs.myVideo.playbackRate(this.bsid);
|
//#endif
|
//#ifndef H5
|
this.videoContext.playbackRate(this.bsid);
|
//#endif
|
});
|
}
|
},
|
updated() {},
|
|
onLoad() {
|
console.log(this.$refs)
|
},
|
|
onHide() {
|
//监听页面离开 - 销毁音频
|
//#ifdef H5
|
this.$refs.myVideo.stop();
|
//#endif
|
//#ifndef H5
|
this.videoContext.stop();
|
//#endif
|
},
|
onUnload() {
|
//监听页面卸载 - 销毁音频
|
//#ifdef H5
|
|
this.$refs.myVideo.stop();
|
|
//#endif
|
|
//#ifndef H5
|
|
this.videoContext.stop();
|
|
//#endif
|
|
},
|
|
destroyed() {
|
|
// this.innerAudioContext.stop();
|
|
},
|
|
computed: {
|
formattedDuration() {
|
// 将毫秒转换为分:秒格式
|
const minutes = Math.floor(this.duration1 / 60000);
|
const seconds = Math.floor((this.duration1 % 60000) / 1000);
|
return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
|
},
|
timer() {
|
return calcTimer(this.currentTime);
|
},
|
overTimer() {
|
return calcTimer(this.duration);
|
},
|
},
|
watch: {},
|
methods: {
|
startTimer() {
|
this.timer1 = setInterval(() => {
|
this.duration1 += 1000;
|
}, 1000);
|
},
|
stopTimer() {
|
console.log('zhanting')
|
clearInterval(this.timer1);
|
this.timer1 = null;
|
},
|
updateDisplayTime() {
|
// 更新当前播放时间并格式化显示
|
this.currentPlayTime = Math.round(this.$refs.myAudio.currentTime);
|
this.formattedPlayTime = this.formatTime(this.currentPlayTime);
|
},
|
formatTime(seconds) {
|
// 将秒数格式化为分:秒的字符串
|
const minutes = Math.floor(seconds / 60);
|
const secs = seconds % 60;
|
return `${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
|
},
|
videoEnded() {
|
console.log('视频播放结束');
|
this.playCount++; // 每次播放结束,递增播放次数
|
console.log('已播放次数:', this.playCount); // 输出当前播放次数
|
// 在这里可以执行其他逻辑,比如更新页面上的显示等
|
},
|
|
plays() {
|
//播放暂停
|
if (!this.list || this.list.length == 0) {
|
console.log("暂无音频数据~");
|
|
return;
|
}
|
|
this.playloading();
|
|
this.succes = !this.succes;
|
|
if (this.succes) {
|
|
this.startTimer();
|
// this.currentTime = 0
|
|
// console.log('-----------------')
|
|
//#ifdef H5
|
|
this.$refs.myVideo.play();
|
|
//#endif
|
|
//#ifndef H5
|
|
this.videoContext.play();
|
|
//#endif
|
|
} else {
|
this.stopTimer();
|
uni.hideLoading();
|
|
//#ifdef H5
|
|
this.$refs.myVideo.pause();
|
|
//#endif
|
|
//#ifndef H5
|
|
this.videoContext.pause();
|
|
//#endif
|
|
}
|
|
},
|
|
beishu() {
|
|
//倍速弹框
|
|
this.shows = !this.shows;
|
|
},
|
|
// 倍速
|
|
setRate(index, item) {
|
this.bsid = item.id;
|
this.bsindex = index;
|
this.shows = false;
|
//#ifdef H5
|
this.$refs.myVideo.playbackRate(item.id);
|
//#endif
|
//#ifndef H5
|
this.videoContext.playbackRate(item.id);
|
//#endif
|
},
|
// 更新进度条
|
timeupdate(event) {
|
if (this.lock) return; // 锁
|
var currentTime, duration;
|
if (event.detail.detail) {
|
currentTime = event.detail.detail.currentTime;
|
duration = event.detail.detail.duration;
|
} else {
|
currentTime = event.detail.currentTime;
|
duration = event.detail.duration;
|
}
|
this.currentTime = currentTime;
|
this.duration = duration;
|
},
|
// 拖动进度条
|
sliderChange(data) {
|
//此处滑动进度条--开始播放
|
if (this.slideYes && !this.succes) {
|
//#ifdef H5
|
this.$refs.myVideo.play();
|
//#endif
|
//#ifndef H5
|
this.videoContext.play();
|
//#endif
|
this.succes = true;
|
}
|
//#ifdef H5
|
this.$refs.myVideo.seek(data.detail.value); //获取秒数
|
//#endif
|
//#ifndef H5
|
this.videoContext.seek(data.detail.value); //获取秒数
|
//#endif
|
},
|
//拖动中
|
sliderChanging(data) {
|
if (data.detail.value == 0) {
|
this.succes = false;
|
//#ifdef H5
|
|
this.$refs.myVideo.pause();
|
|
//#endif
|
|
//#ifndef H5
|
|
this.videoContext.pause();
|
|
//#endif
|
|
}
|
|
this.currentTime = data.detail.value;
|
|
},
|
|
// 视频加载完成
|
|
loadedmetadata(data) {
|
|
this.duration = data.detail.duration;
|
|
},
|
|
sig() {
|
|
//上一首
|
|
if (!this.list || this.list.length == 0) {
|
|
console.log("暂无音频数据~");
|
|
return;
|
|
}
|
|
this.num -= 1;
|
|
if (this.num < this.list.length) {
|
|
this.loading = true;
|
|
this.playloading(); //加载框
|
|
}
|
|
if (this.num + 1 < this.list.length && this.num + 1 != 1) {
|
|
//点击上一首小于音频数据总长度
|
|
this.jia = false; // 下按钮-亮且可点击
|
|
this.jian = false; // 上按钮-亮且可点击
|
|
} else {
|
|
this.jian = true; // 上按钮-灰且阻止
|
|
this.jia = false; // 下按钮-亮且可点击
|
|
}
|
|
this.recorPath = this.list[this.num].recorPath;
|
|
if (this.switAud) {
|
|
//切换时是否默认开启播放
|
|
this.succes = true;
|
|
setTimeout(() => {
|
|
//#ifdef H5
|
|
this.$refs.myVideo.play();
|
|
//#endif
|
|
//#ifndef H5
|
|
this.videoContext.play();
|
|
//#endif
|
|
}, 100);
|
|
} else {
|
|
this.succes = false;
|
|
}
|
|
},
|
|
xig() {
|
//下一首
|
if (!this.list || this.list.length == 0) {
|
console.log("暂无音频数据~");
|
return;
|
}
|
this.num += 1;
|
if (this.num < this.list.length) {
|
this.loading = true;
|
this.playloading(); //加载框
|
}
|
if (this.num + 1 < this.list.length) {
|
//点击下一首小于音频数据总长度
|
this.jia = false; // 下按钮-亮且可点击
|
this.jian = false; // 上按钮-亮且可点击
|
} else {
|
//大于总长度
|
this.jia = true; //下按钮 - 灰且阻止
|
this.jian = false; //上按钮 - 亮可点击
|
}
|
this.recorPath = this.list[this.num].recorPath;
|
if (this.switAud) {
|
//切换时是否默认开启播放
|
this.succes = true;
|
setTimeout(() => {
|
//#ifdef H5
|
this.$refs.myVideo.play();
|
//#endif
|
//#ifndef H5
|
this.videoContext.play();
|
//#endif
|
}, 100);
|
} else {
|
this.succes = false;
|
}
|
},
|
|
nosig() {
|
|
uni.showToast({
|
title: "到头了~",
|
icon: "none",
|
});
|
},
|
noxig() {
|
uni.showToast({
|
title: "没有更多了~",
|
icon: "none",
|
});
|
},
|
|
kt() {
|
//快退
|
if (!this.list || this.list.length == 0) {
|
console.log("暂无音频数据~");
|
return;
|
}
|
let a = (this.currentTime - Math.floor(15 % 60)).toFixed(0); //当前时间-15秒
|
if (a < 1) {
|
this.succes = false;
|
//#ifdef H5
|
this.$refs.myVideo.pause();
|
//#endif
|
//#ifndef H5
|
this.videoContext.pause();
|
//#endif
|
}
|
//#ifdef H5
|
this.$refs.myVideo.seek(a);
|
//#endif
|
//#ifndef H5
|
this.videoContext.seek(a);
|
//#endif
|
},
|
|
kj() {
|
//快进
|
if (!this.list || this.list.length == 0) {
|
console.log("暂无音频数据~");
|
return;
|
}
|
let a = (this.currentTime + Math.floor(15 % 60)).toFixed(0); //当前时间+15秒
|
//#ifdef H5
|
this.$refs.myVideo.seek(a);
|
//#endif
|
//#ifndef H5
|
this.videoContext.seek(a);
|
//#endif
|
},
|
next(data) {
|
//监听音频结束
|
this.playCount++
|
this.succes = false;
|
/*音频结束--是否自动播放下一首*/
|
if (!this.autoNext) {
|
return;
|
}
|
if (this.num + 1 < 1000) {
|
this.succes = true;
|
this.num += 1;
|
// this.recorPath = this.list[this.num].recorPath;
|
setTimeout(() => {
|
//#ifdef H5
|
this.$refs.myVideo.play();
|
//#endif
|
//#ifndef H5
|
this.videoContext.play();
|
//#endif
|
}, 100);
|
} else {
|
this.jia = true; //下按钮 - 灰且阻止
|
this.jian = false; //上按钮 - 亮可点击
|
}
|
},
|
playloading() {
|
//加载框--封
|
if (this.loading) {
|
uni.showLoading({
|
title: "音频缓存中...",
|
});
|
this.loading = false;
|
}
|
setTimeout(() => {
|
uni.hideLoading();
|
}, 1600);
|
},
|
},
|
watch: {},
|
};
|
|
//时间换算
|
function calcTimer(timer) {
|
if (timer === 0 || typeof timer !== "number") {
|
return "00:00";
|
}
|
let mm = Math.floor(timer / 60);
|
let ss = Math.floor(timer % 60);
|
if (mm < 10) {
|
mm = "0" + mm;
|
}
|
if (ss < 10) {
|
ss = "0" + ss;
|
}
|
return mm + ":" + ss;
|
}
|
</script>
|
<style lang="scss" scoped>
|
page {
|
background-color: #f6f6f8;
|
}
|
.audo-video {
|
padding-bottom: 20rpx;
|
color: #999;
|
}
|
.slider-box {
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
font-size: 27rpx;
|
color: #999;
|
}
|
button {
|
display: inline-block;
|
|
width: 100rpx;
|
|
background-color: #fff;
|
|
font-size: 24rpx;
|
|
color: #000;
|
|
padding: 0;
|
|
}
|
|
.hidden {
|
|
position: fixed;
|
|
top: 0;
|
|
left: -10rpx;
|
|
z-index: -1;
|
|
width: 1rpx;
|
|
height: 1rpx;
|
|
}
|
|
.audo-top {
|
|
padding: 20rpx 40rpx;
|
|
display: flex;
|
|
justify-content: space-around;
|
|
align-items: center;
|
|
image {
|
|
width: 45rpx;
|
|
height: 45rpx;
|
|
}
|
|
}
|
|
.audo-a {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
width: 700rpx;
|
|
position: relative;
|
|
z-index: 9;
|
|
}
|
|
.beishu {
|
|
position: relative;
|
|
width: 100rpx;
|
|
padding-top: 5rpx;
|
|
padding-bottom: 5rpx;
|
|
text-align: center;
|
|
border-radius: 25rpx;
|
|
font-size: 28rpx;
|
|
}
|
|
.absolute {
|
|
position: absolute;
|
|
.beishu-a {
|
|
width: 200rpx;
|
|
border-radius: 20rpx;
|
|
text-align: center;
|
|
line-height: 90rpx;
|
|
background: #fff;
|
|
.title {
|
|
pdding-left: 30rpx;
|
|
}
|
|
}
|
|
}
|
|
</style>
|