683 lines
17 KiB
Vue
683 lines
17 KiB
Vue
<template>
|
|
<!--音频组件-->
|
|
<view>
|
|
<view class="bgfff">
|
|
<view>
|
|
<view class="audo-video">
|
|
|
|
<!-- 播放封面 -->
|
|
<view :class="['fengmianBox','defaultBg', succes ? 'playAnimate' : '']" :style="{ backgroundImage: `url(${fengImg})` }"></view>
|
|
|
|
<!--音频播放按钮处-->
|
|
<view class="audo-top">
|
|
<!-- 顺序播放 -->
|
|
<image v-if="orderPlayBtn" style="width:50rpx;height:50rpx;" src="/static/orderPlaya.png" mode="aspectFill" @click="orderPlay(false)"></image>
|
|
<image v-else style="width:50rpx;height:50rpx;" src="/static/orderPlay.png" mode="aspectFill" @click="orderPlay(true)"></image>
|
|
|
|
<!--上一首切换按钮-->
|
|
<image v-if="jian" @click="sig" src="/static/xys.png" style="width:50rpx;height:50rpx;transform:rotate(180deg)"
|
|
mode="aspectFill"></image>
|
|
<image v-else style="width:50rpx;height:50rpx;" @click="nosig" src="/static/sys.png" mode="aspectFill"></image>
|
|
<!--上一首切换按钮-->
|
|
|
|
<!--快退按钮-->
|
|
<!-- <image src="/static/kt.png" style="width:45rpx;height:45rpx;" mode="aspectFill" @click="kt()"></image> -->
|
|
<!--快退按钮-->
|
|
|
|
<!--播放按钮-->
|
|
<image :src="succes?'/static/bofang2.png':'/static/zt.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>
|
|
|
|
<!-- 播放目录 -->
|
|
<image src="/static/libIcon.png" style="width:45rpx;height:45rpx;" mode="aspectFill" @click="showLib()"></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="#2fc348" @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>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="h-100"></view>
|
|
<!--占位-->
|
|
</view>
|
|
<!--音频组件 Author:chenxin-->
|
|
</template>
|
|
|
|
<script>
|
|
/*
|
|
list -- 音频文件传入 不传无法播放/数组形式
|
|
Faskms -- 快进秒数 number 默认15秒
|
|
Slowms -- 快退秒数 number 默认15秒
|
|
autoNext -- 是否自动播放下一首
|
|
autoplays -- 进入页面是否自动播放 - 默认false
|
|
slideYes -- 滑动进度条时是否开启播放 - 默认false
|
|
switAud -- 切换上下音频是否开启播放 - 默认false
|
|
BsNav -- 倍数数据传入/数组形式
|
|
|
|
按钮图片未自定义,如想改动请在组件内部修改,页面头部已注释 -- 逻辑根据自己需求改
|
|
目前只测试 微信小程序和H5和APP -- 其他平台未知
|
|
Author:chenxin 交流vx:cxalq8-24
|
|
*/
|
|
import {
|
|
mapState,mapMutations
|
|
} from 'vuex';
|
|
export default {
|
|
name: "cx-audio-play",
|
|
props: {
|
|
list: { //音频数据
|
|
Type: Array,
|
|
default:[]
|
|
},
|
|
fengImg:{
|
|
// 封面img
|
|
type:String,
|
|
default:''
|
|
},
|
|
Faskms: { //快进秒数
|
|
Type: Number,
|
|
default: 15,
|
|
},
|
|
jia:{
|
|
Type: Boolean,
|
|
default: false,
|
|
},
|
|
// orderPlayBtn:{
|
|
// // 按顺序播放
|
|
// Type: Boolean,
|
|
// default: false
|
|
// },
|
|
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,
|
|
},
|
|
|
|
jian: { //减-切换图标
|
|
type:Boolean,
|
|
default:false
|
|
},
|
|
cctime:{ // 初始化播放位置(秒)
|
|
type:Object,
|
|
default:{}
|
|
},
|
|
BsNav: { //倍数-传入 0.5/0.8/1.0/1.25/1.5/2.0
|
|
Type: Array,
|
|
default: () => [{
|
|
id: 0.5,
|
|
bs: '0.5',
|
|
}, {
|
|
id: 0.8,
|
|
bs: '0.8'
|
|
}, {
|
|
id: 1.0,
|
|
bs: '1.0'
|
|
},{
|
|
id: 1.25,
|
|
bs: '1.25'
|
|
},{
|
|
id: 1.5,
|
|
bs: '1.5'
|
|
},{
|
|
id: 2.0,
|
|
bs: '2.0'
|
|
}
|
|
|
|
],
|
|
},
|
|
|
|
},
|
|
data() {
|
|
return {
|
|
orderPlayBtn:false,
|
|
shows: false, //倍数弹框
|
|
show: true, //倍数弹框动画默认开启
|
|
// jia: true, //加-切换图标
|
|
succes: true, //播放按钮
|
|
bsid: '', //倍数默认显示第一个
|
|
bsindex: 2, //倍数默认显示第一个
|
|
num: 0,
|
|
current: 0, //当前选中的索引
|
|
recorPath: '', //音频播放地址
|
|
lock: false, // 锁
|
|
currentTime: 0, //当前进度
|
|
duration: 1, // 总进度
|
|
videoContext: null,
|
|
loading: true, //锁 加载
|
|
audioMannager:null ,// 背景音乐
|
|
saveInterVal:null,
|
|
}
|
|
},
|
|
onReady() {},
|
|
onShow() {
|
|
|
|
},
|
|
onBackPress() {
|
|
},
|
|
mounted() {
|
|
// console.log(this.cctime,'cctime') // 默认播放的位置(秒),第一次加载
|
|
this.videoContext = uni.getBackgroundAudioManager()
|
|
// this.videoContext = uni.createVideoContext('myVideo', this)
|
|
//默认播放第一个 -- 按钮展示
|
|
if (this.list.length != 0) {
|
|
this.loading = true
|
|
this.videoContext.title = '暂无'
|
|
this.videoContext.singer = '暂无'
|
|
this.videoContext.coverImgUrl = this.fengImg
|
|
this.videoContext.src = this.list[0].recorPath
|
|
this.playloading()
|
|
// if (this.list.length > 1) { //音频文件大于1 -- 下一个切换默认显示
|
|
// // this.jia = false
|
|
// if (this.autoplays) {
|
|
// this.succes = true
|
|
// }
|
|
// }
|
|
}
|
|
this.videoContext.onEnded(() => {
|
|
this.next()
|
|
//this.setUserInfo({playFlag:false});
|
|
//console.log(this.userInfo.playFlag,'playFlag')
|
|
}) // 播放结束加载下一首
|
|
this.videoContext.onError((err) => {
|
|
console.log(err)
|
|
this.setUserInfo({playFlag:true});
|
|
this.next()
|
|
}) // 播放错误加载下一首
|
|
|
|
this.videoContext.onCanplay(() =>{
|
|
// this.setUserInfo({playFlag:true});
|
|
// console.log(this.userInfo.playFlag,'playFlag')
|
|
this.duration = this.videoContext.duration
|
|
// this.loading = false
|
|
uni.hideLoading()
|
|
this.succes = true
|
|
if(this.cctime.flag == 'init'){
|
|
// 页面初始化时
|
|
this.currentTime = this.cctime.time
|
|
// 跳转到指定的秒数上
|
|
this.videoContext.seek(this.currentTime)
|
|
console.log('获取到初始值,进行时间跳转')
|
|
}
|
|
})
|
|
this.videoContext.onPlay(() => {
|
|
this.playSeconds = Math.ceil(this.currentTime) // 秒数取整
|
|
|
|
})
|
|
this.videoContext.onTimeUpdate((res) => {
|
|
//console.log(this.videoContext.currentTime,'onTimeUpdate');
|
|
this.currentTime = Math.max(0, this.videoContext.currentTime)
|
|
// console.log(this.currentTime,'当前秒数');
|
|
// var ss = Math.floor(this.playSeconds / 60)
|
|
// console.log(ss, this.playSeconds)
|
|
// if(ss > this.playSeconds){
|
|
// this.playSeconds = ss
|
|
// console.log(ss)
|
|
|
|
// }
|
|
})
|
|
},
|
|
updated() {
|
|
|
|
},
|
|
onLoad() {
|
|
|
|
},
|
|
onHide() { //监听页面离开 - 销毁音频
|
|
// this.videoContext.stop();
|
|
console.log('onHide')
|
|
},
|
|
onUnload() { //监听页面卸载 - 销毁音频
|
|
// this.videoContext.stop();
|
|
console.log('onUnload')
|
|
},
|
|
destroyed() {
|
|
// if(this.videoContext){
|
|
// this.videoContext.stop();
|
|
// }
|
|
console.log('destroyed')
|
|
|
|
},
|
|
computed: {
|
|
...mapState(['userInfo']),
|
|
timer() {
|
|
return calcTimer(this.currentTime)
|
|
},
|
|
overTimer() {
|
|
return calcTimer(this.duration)
|
|
}
|
|
|
|
},
|
|
watch: {
|
|
|
|
},
|
|
methods: {
|
|
...mapMutations(['setUserInfo']),
|
|
// 存储听书进度
|
|
saveListenRate(){
|
|
console.log('存储听书进度')
|
|
this.$emit('saveRate',this.currentTime)
|
|
},
|
|
// 顺序播放
|
|
orderPlay(val){
|
|
// console.log(val)
|
|
if(val){
|
|
uni.showToast({
|
|
title:'开启顺序播放',
|
|
icon:'none'
|
|
})
|
|
this.orderPlayBtn = true
|
|
}else{
|
|
uni.showToast({
|
|
title:'关闭顺序播放',
|
|
icon:'none'
|
|
})
|
|
this.orderPlayBtn = false
|
|
}
|
|
},
|
|
// 显示播放列表
|
|
showLib(){
|
|
this.$emit('showLib',true)
|
|
},
|
|
plays() { //播放暂停
|
|
if (!this.list || this.list.length == 0) {
|
|
uni.showToast({
|
|
title: '暂无音频数据~',
|
|
icon: "none"
|
|
})
|
|
// console.log('暂无音频数据.~')
|
|
return;
|
|
}
|
|
// this.playloading()
|
|
this.succes = !this.succes
|
|
/// console.log('修改后',this.succes)
|
|
if (this.succes) {
|
|
console.log('去播放',this.succes)
|
|
// this.setUserInfo({playFlag:true});
|
|
this.videoContext.play()
|
|
|
|
} else {
|
|
// this.succes = false
|
|
console.log('去暂停',this.succes )
|
|
// this.setUserInfo({playFlag:false});
|
|
uni.hideLoading()
|
|
//#ifdef H5
|
|
this.videoContext.pause()
|
|
this.saveListenRate()
|
|
//#endif
|
|
//#ifndef H5
|
|
this.videoContext.pause()
|
|
this.saveListenRate()
|
|
//#endif
|
|
|
|
}
|
|
},
|
|
// beishu() { //倍速弹框
|
|
// this.shows = !this.shows
|
|
// },
|
|
// 倍速
|
|
// setRate(index, item) {
|
|
// this.bsid = item.id
|
|
// this.bsindex = index
|
|
// this.shows = false
|
|
// //#ifdef H5
|
|
// this.videoContext.playbackRate(2)
|
|
// //#endif
|
|
// //#ifndef H5
|
|
// this.videoContext.playbackRate(2)
|
|
// //#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.videoContext.play()
|
|
//#endif
|
|
//#ifndef H5
|
|
this.videoContext.play()
|
|
//#endif
|
|
this.succes = true
|
|
}
|
|
//#ifdef H5
|
|
this.videoContext.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.videoContext.pause()
|
|
//#endif
|
|
//#ifndef H5
|
|
this.videoContext.pause()
|
|
//#endif
|
|
}
|
|
this.currentTime = data.detail.value
|
|
},
|
|
|
|
// 视频加载完成
|
|
loadedmetadata(data) {
|
|
this.duration = data.detail.duration
|
|
},
|
|
sig() { //上一首
|
|
this.$emit('playPrev',true)
|
|
// if (!this.list || this.list.length == 0) {
|
|
// console.log('暂无音频数据~')
|
|
// return;
|
|
// }
|
|
// this.num -= 1
|
|
// console.log(this.num,'this.num')
|
|
// 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() { //下一首
|
|
|
|
this.$emit("xiayishou");
|
|
|
|
// 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"
|
|
})
|
|
},
|
|
next(data) { //监听音频结束
|
|
// console.log('开始播放下一首')
|
|
this.succes = false
|
|
/*音频结束--是否自动播放下一首*/
|
|
//if(this.orderPlayBtn){
|
|
setTimeout(()=>{
|
|
this.$emit("xiayishou");
|
|
},100)
|
|
// }else{
|
|
// console.log('音频结束-------')
|
|
// return
|
|
// }
|
|
// if (!this.autoNext) {
|
|
// return
|
|
// }
|
|
// if (this.num + 1 < this.list.length) {
|
|
// 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
|
|
}
|
|
this.succes = 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>
|
|
@-webkit-keyframes rotation {
|
|
from {
|
|
-webkit-transform: rotate(0deg);
|
|
}
|
|
to {
|
|
-webkit-transform: rotate(360deg);
|
|
}
|
|
}
|
|
.playAnimate{
|
|
-webkit-transform: rotate(360deg);
|
|
animation: rotation 6s linear infinite;
|
|
-moz-animation: rotation 6s linear infinite;
|
|
-webkit-animation: rotation 6s linear infinite;
|
|
-o-animation: rotation 6s linear infinite;
|
|
}
|
|
.fengmianBox{text-align: center; width: 400rpx; height: 400rpx; position: relative; border-radius: 400rpx; margin: 0 auto; margin-bottom: 140rpx; background-size: contain;}
|
|
.fengmianBox:after{
|
|
content: ''; display: inline-block; left:0; top:0; z-index: 0;width: 400rpx; height: 400rpx; position: absolute; border-radius: 400rpx; box-shadow: rgba(177, 235, 202, 0.8) 0px 0px 29px 0px;
|
|
}
|
|
.fengmianBox.defaultBg{background-image: url('@/static/icon/home_icon_0.png');}
|
|
|
|
page {
|
|
background-color: #F6F6F8;
|
|
}
|
|
|
|
/* #video {
|
|
width: 100%;
|
|
} */
|
|
.audo-video {
|
|
padding-bottom: 20rpx;
|
|
color: #999;
|
|
}
|
|
|
|
.slider-box {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 27rpx;
|
|
color: #999; margin: 0 auto;
|
|
}
|
|
|
|
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: 750rpx;
|
|
position: relative;
|
|
z-index: 9; margin: 0 auto;
|
|
}
|
|
|
|
.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>
|