perf: 优化音频播放器
This commit is contained in:
parent
3b4a3236a3
commit
19e2fdbbb2
@ -15,7 +15,6 @@
|
||||
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml"
|
||||
},
|
||||
"dependencies": {
|
||||
"@moefe/vue-aplayer": "^2.0.0-beta.5",
|
||||
"ant-design-vue": "^1.6.5",
|
||||
"artplayer": "^4.5.4",
|
||||
"clipboard": "^2.0.6",
|
||||
@ -23,6 +22,7 @@
|
||||
"e-vue-contextmenu": "^0.1.3",
|
||||
"gsap": "^3.2.6",
|
||||
"highlightjs-line-numbers.js": "^2.7.0",
|
||||
"hls.js": "^1.4.0",
|
||||
"htmlhint": "^0.13.0",
|
||||
"jquery": "^3.5.0",
|
||||
"jquery-contextmenu": "^2.9.1",
|
||||
|
||||
@ -1,22 +1,25 @@
|
||||
<template>
|
||||
<div ref="audioPreview" v-if="show">
|
||||
<div class="audio-player"
|
||||
v-aplayerDrag="{ x: transformX, y: transformY }"
|
||||
@mouseenter="closeBarShow = true" @mouseleave="closeBarShow = false" @touchmove="closeBarShow = true"
|
||||
@touchend="touchend">
|
||||
<a-player
|
||||
ref="audioPlayer"
|
||||
autoplay
|
||||
listFolded
|
||||
loop.sync="all"
|
||||
order.sync="list"
|
||||
:mini.sync="mini"
|
||||
:audio="list"
|
||||
:lrc-type="0"
|
||||
>
|
||||
</a-player>
|
||||
<div v-show="closeBarShow" class="close-bar" @click="close">
|
||||
<svg-icon class="audio-player-close" icon-class="close"/>
|
||||
<div ref="asdfasdf">
|
||||
<div ref="audioPreview" v-if="show">
|
||||
<div class="audio-player"
|
||||
v-aplayerDrag="{ x: transformX, y: transformY }"
|
||||
@mouseenter="closeBarShow = true" @mouseleave="closeBarShow = false" @touchmove="closeBarShow = true"
|
||||
@touchend="touchend">
|
||||
<vue-a-player
|
||||
ref="audioPlayer"
|
||||
listFolded
|
||||
controls
|
||||
preload="auto"
|
||||
:repeat="repeat"
|
||||
:shuffle="shuffle"
|
||||
:music="currentMusic"
|
||||
:mini.sync="mini"
|
||||
:list="list"
|
||||
>
|
||||
</vue-a-player>
|
||||
<div v-show="closeBarShow" class="close-bar" @click="close">
|
||||
<svg-icon class="audio-player-close" icon-class="close"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -25,11 +28,13 @@
|
||||
<script>
|
||||
import '@/utils/directives.js'
|
||||
import Bus from '@/assets/js/bus'
|
||||
import VueAPlayer from 'vue-aplayer'
|
||||
VueAPlayer.disableVersionBadge = true
|
||||
import fileConfig from '@/utils/file-config'
|
||||
|
||||
export default {
|
||||
name: 'AudioPreview',
|
||||
components: {},
|
||||
components: {VueAPlayer},
|
||||
props: {},
|
||||
computed: {},
|
||||
data() {
|
||||
@ -39,20 +44,11 @@ export default {
|
||||
transformY: !this.$pc ? document.body.clientHeight / 2 - 100 : 0,
|
||||
show: false,
|
||||
closeBarShow: false,
|
||||
// api ==> https://aplayer.netlify.app/docs/guide/options.html#volume
|
||||
audios: [],
|
||||
currentMusic: {},
|
||||
list: [],
|
||||
mini: !this.$pc,
|
||||
audioPlayerDoc: undefined
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
show(val) {
|
||||
if (val && !this.audioPlayerDoc) {
|
||||
this.$nextTick(() => {
|
||||
this.audioPlayerDoc = document.querySelector('.audio-player')
|
||||
})
|
||||
}
|
||||
repeat: 'no-repeat',
|
||||
shuffle: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@ -60,46 +56,35 @@ export default {
|
||||
if (!this.show) {
|
||||
this.show = true
|
||||
}
|
||||
let url = fileConfig.previewUrl(this.$store.state.user.name, newFile, this.$store.getters.token)
|
||||
if (this.$store.getters.token === undefined) {
|
||||
url = fileConfig.publicPreviewUrl(newFile.id, window.shareId, this.$store.getters.shareToken);
|
||||
}
|
||||
let music = newFile.music
|
||||
let fileName = newFile.name.substring(0, newFile.name.length - newFile.suffix.length - 1)
|
||||
let musicOperation = {
|
||||
id: newFile.id,
|
||||
url: url,
|
||||
name: music ? music.songName || fileName : fileName,
|
||||
artist: music ? music.singer || fileName : fileName,
|
||||
cover: music ? audioCoverUrl + newFile.id : '',
|
||||
type: newFile.contentType
|
||||
}
|
||||
let musicIndex = this.audios.findIndex(item => item.id === newFile.id)
|
||||
if (musicIndex < 0) {
|
||||
if (this.audios.length === 1) {
|
||||
let loop = document.querySelector('.aplayer-icon.aplayer-icon-loop');
|
||||
loop.style.display = 'inline'
|
||||
let order = document.querySelector('.aplayer-icon.aplayer-icon-order');
|
||||
order.style.display = 'inline'
|
||||
this.$nextTick(() => {
|
||||
console.log('this.$refs', this.$refs)
|
||||
let url = fileConfig.previewUrl(this.$store.state.user.name, newFile, this.$store.getters.token)
|
||||
if (this.$store.getters.token === undefined) {
|
||||
url = fileConfig.publicPreviewUrl(newFile.id, window.shareId, this.$store.getters.shareToken);
|
||||
}
|
||||
this.audios.push(musicOperation)
|
||||
setTimeout(() => {
|
||||
this.list = this.audios
|
||||
setTimeout(() => {
|
||||
this.$refs.audioPlayer.switch(this.audios.length - 1)
|
||||
}, 0)
|
||||
}, 0)
|
||||
} else {
|
||||
this.$refs.audioPlayer.switch(musicIndex)
|
||||
}
|
||||
let music = newFile.music
|
||||
let fileName = newFile.name.substring(0, newFile.name.length - newFile.suffix.length - 1)
|
||||
this.currentMusic = {
|
||||
id: newFile.id,
|
||||
src: url,
|
||||
title: music ? music.songName || fileName : fileName,
|
||||
artist: music ? music.singer || fileName : fileName,
|
||||
pic: music ? audioCoverUrl + newFile.id : '',
|
||||
theme: 'pic'
|
||||
}
|
||||
let musicIndex = this.list.findIndex(item => item.id === newFile.id)
|
||||
if (musicIndex < 0) {
|
||||
this.list.push(this.currentMusic)
|
||||
}
|
||||
this.$refs.audioPlayer.thenPlay()
|
||||
console.log(this.$refs.audioPlayer.repeat, this.$refs.audioPlayer.shuffle);
|
||||
})
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
close() {
|
||||
this.show = false
|
||||
this.audioPlayerDoc = undefined
|
||||
this.$refs.audioPlayer.pause()
|
||||
this.audios.splice(0, this.audios.length)
|
||||
},
|
||||
touchend() {
|
||||
const that = this
|
||||
|
||||
@ -16,7 +16,6 @@
|
||||
<script>
|
||||
import fileConfig from '@/utils/file-config'
|
||||
import Artplayer from "@/components/preview/Artplayer.vue";
|
||||
|
||||
export default {
|
||||
name: 'VideoPreview',
|
||||
components: {
|
||||
@ -72,6 +71,7 @@ export default {
|
||||
{
|
||||
name: 'nplayer',
|
||||
position: 'right',
|
||||
tooltip: 'nPlayer',
|
||||
style: {
|
||||
marginRight: '20px',
|
||||
},
|
||||
@ -81,6 +81,7 @@ export default {
|
||||
{
|
||||
name: 'infuse',
|
||||
position: 'right',
|
||||
tooltip: 'Infuse',
|
||||
style: {
|
||||
marginRight: '20px',
|
||||
},
|
||||
|
||||
@ -41,12 +41,6 @@ Vue.use(vant.ImagePreview)
|
||||
import Minder from '@/components/Minder'
|
||||
Vue.use(Minder)
|
||||
|
||||
import APlayer from '@moefe/vue-aplayer';
|
||||
Vue.use(APlayer, {
|
||||
defaultCover: 'https://images.unsplash.com/photo-1511671782779-c97d3d27a1d4?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=200&q=60',
|
||||
productionTip: false, // 是否在控制台输出版本信息
|
||||
});
|
||||
|
||||
new Vue({
|
||||
el: '#app',
|
||||
router,
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
|
||||
// import Vue from 'vue'
|
||||
|
||||
// v-draw-rectangle 画矩形选区
|
||||
Vue.directive('drawRectangle',{
|
||||
bind(el,binding,vnode,oldVnode){
|
||||
let $$ = function(id){
|
||||
Vue.directive('drawRectangle', {
|
||||
bind(el, binding, vnode, oldVnode) {
|
||||
let $$ = function (id) {
|
||||
return document.getElementById(id)
|
||||
}
|
||||
let draw = el
|
||||
@ -12,7 +11,7 @@ Vue.directive('drawRectangle',{
|
||||
let startX = 0, startY = 0
|
||||
let flag = false
|
||||
let retcLeft = 0, retcTop = 0, retcHeight = 0, retcWidth = 0
|
||||
draw.onmousedown = function(e){
|
||||
draw.onmousedown = function (e) {
|
||||
flag = true
|
||||
let evt = window.event || e
|
||||
let scrollTop = draw.scrollTop || draw.scrollTop
|
||||
@ -33,8 +32,8 @@ Vue.directive('drawRectangle',{
|
||||
div.style.overflow = 'hidden'
|
||||
draw.appendChild(div)
|
||||
|
||||
document.onmousemove = function(e){
|
||||
if(flag){
|
||||
document.onmousemove = function (e) {
|
||||
if (flag) {
|
||||
let evt = window.event || e
|
||||
let scrollTop = document.body.scrollTop || document.documentElement.scrollTop
|
||||
let scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft
|
||||
@ -52,11 +51,11 @@ Vue.directive('drawRectangle',{
|
||||
|
||||
}
|
||||
|
||||
document.onmouseup = function(e){
|
||||
document.onmouseup = function (e) {
|
||||
flag = false
|
||||
if($$(wId)){
|
||||
if ($$(wId)) {
|
||||
draw.removeChild($$(wId))
|
||||
if(retcWidth > 1 && retcHeight > 1){
|
||||
if (retcWidth > 1 && retcHeight > 1) {
|
||||
}
|
||||
}
|
||||
return false
|
||||
@ -70,28 +69,25 @@ Vue.directive('aplayerDrag', {
|
||||
// 获取拖拽内容头部
|
||||
const dialogHeaderEl = el.querySelector('.aplayer-music');
|
||||
const dragDom = el;
|
||||
dragDom.style.transform="translate("+binding.value.x+"px,"+binding.value.y+"px)";
|
||||
// dragDom.style.transform = "translate(" + binding.value.x + "px," + binding.value.y + "px)";
|
||||
dragDom.style.left = binding.value.x + "px"
|
||||
dragDom.style.top = binding.value.y + "px"
|
||||
dialogHeaderEl.style.cursor = 'move';
|
||||
// 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
|
||||
const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null);
|
||||
// 鼠标按下事件
|
||||
dragDom.addEventListener('touchstart', touchstart, false);
|
||||
dragDom.addEventListener('touchmove', touchmove, false);
|
||||
let disX,disY,styL,styT;
|
||||
let disX, disY, styL, styT;
|
||||
|
||||
function touchstart(e) {
|
||||
// 鼠标按下,计算当前元素距离可视区的距离 (鼠标点击位置距离可视窗口的距离)
|
||||
disX = e.touches[0].clientX - dialogHeaderEl.offsetLeft;
|
||||
disY = e.touches[0].clientY - dialogHeaderEl.offsetTop;
|
||||
// 获取到的值带px 正则匹配替换
|
||||
// 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
|
||||
if (sty.left.includes('%')) {
|
||||
styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100) + binding.value.x;
|
||||
styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100) + binding.value.y;
|
||||
} else {
|
||||
styL = +sty.left.replace(/\px/g, '') + binding.value.x;
|
||||
styT = +sty.top.replace(/\px/g, '') + binding.value.y;
|
||||
}
|
||||
styL = binding.value.x
|
||||
styT = binding.value.y
|
||||
}
|
||||
|
||||
// 鼠标拖拽事件
|
||||
function touchmove(e) {
|
||||
e.preventDefault()
|
||||
@ -106,32 +102,25 @@ Vue.directive('aplayerDrag', {
|
||||
} else if (finallyL > document.body.clientWidth - dragDom.clientWidth) {///右边
|
||||
finallyL = document.body.clientWidth - dragDom.clientWidth
|
||||
}
|
||||
|
||||
if (finallyT < 0) {////顶部
|
||||
finallyT = 0
|
||||
} else if (finallyT > document.body.clientHeight - dragDom.clientHeight) (///底部
|
||||
finallyT = document.body.clientHeight - dragDom.clientHeight
|
||||
)
|
||||
dragDom.style.transform = "translate(" + finallyL + "px," + finallyT + "px)";
|
||||
dragDom.style.left = finallyL + "px"
|
||||
dragDom.style.top = finallyT + "px"
|
||||
//将此时的位置传出去
|
||||
binding.value.x = finallyL;
|
||||
binding.value.y = finallyT;
|
||||
}
|
||||
|
||||
// 鼠标按下事件
|
||||
dialogHeaderEl.onmousedown = (e) => {
|
||||
// 鼠标按下,计算当前元素距离可视区的距离 (鼠标点击位置距离可视窗口的距离)
|
||||
const disX = e.clientX - dialogHeaderEl.offsetLeft + 81;
|
||||
const disY = e.clientY - dialogHeaderEl.offsetTop + 14;
|
||||
// 获取到的值带px 正则匹配替换
|
||||
let styL, styT;
|
||||
// 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
|
||||
if (sty.left.includes('%')) {
|
||||
styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100)+binding.value.x;
|
||||
styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100)+binding.value.y;
|
||||
} else {
|
||||
styL = +sty.left.replace(/\px/g, '')+binding.value.x;
|
||||
styT = +sty.top.replace(/\px/g, '')+binding.value.y;
|
||||
};
|
||||
styL = binding.value.x
|
||||
styT = binding.value.y
|
||||
// 鼠标拖拽事件
|
||||
document.onmousemove = function (e) {
|
||||
// 通过事件委托,计算移动的距离 (开始拖拽至结束拖拽的距离)
|
||||
@ -151,10 +140,11 @@ Vue.directive('aplayerDrag', {
|
||||
} else if (finallyT > document.body.clientHeight - dragDom.clientHeight) (///底部
|
||||
finallyT = document.body.clientHeight - dragDom.clientHeight
|
||||
)
|
||||
dragDom.style.transform="translate("+finallyL+"px,"+finallyT+"px)";
|
||||
dragDom.style.left = finallyL + "px"
|
||||
dragDom.style.top = finallyT + "px"
|
||||
//将此时的位置传出去
|
||||
binding.value.x=finallyL;
|
||||
binding.value.y=finallyT;
|
||||
binding.value.x = finallyL;
|
||||
binding.value.y = finallyT;
|
||||
};
|
||||
document.onmouseup = function (e) {
|
||||
document.onmousemove = null;
|
||||
@ -175,9 +165,9 @@ Vue.directive('dialogDrag', {
|
||||
const dialogHeaderEl = el.querySelector('.el-dialog__header');
|
||||
const dragDom = el.querySelector('.el-dialog');
|
||||
let dialogWidth = document.body.clientWidth * binding.value.dialogWidthPercent
|
||||
let x = (document.body.clientWidth - dialogWidth)/2
|
||||
let y = (document.body.clientHeight - document.body.clientHeight * binding.value.dialogWidthPercent)/2
|
||||
dragDom.style.transform="translate("+x+"px,"+y+"px)";
|
||||
let x = (document.body.clientWidth - dialogWidth) / 2
|
||||
let y = (document.body.clientHeight - document.body.clientHeight * binding.value.dialogWidthPercent) / 2
|
||||
dragDom.style.transform = "translate(" + x + "px," + y + "px)";
|
||||
//dialogHeaderEl.style.cursor = 'move';
|
||||
// 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
|
||||
const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null);
|
||||
@ -190,16 +180,17 @@ Vue.directive('dialogDrag', {
|
||||
let styL, styT;
|
||||
// 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
|
||||
if (sty.left.includes('%')) {
|
||||
styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100)+x;
|
||||
styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100)+y;
|
||||
styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100) + x;
|
||||
styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100) + y;
|
||||
} else {
|
||||
styL = +sty.left.replace(/\px/g, '')+x;
|
||||
styT = +sty.top.replace(/\px/g, '')+y;
|
||||
};
|
||||
styL = +sty.left.replace(/\px/g, '') + x;
|
||||
styT = +sty.top.replace(/\px/g, '') + y;
|
||||
}
|
||||
;
|
||||
// 鼠标拖拽事件
|
||||
document.onmousemove = function (e) {
|
||||
// 全屏禁止拖动
|
||||
if((dragDom.offsetParent.clientWidth - dragDom.clientWidth) === 0){
|
||||
if ((dragDom.offsetParent.clientWidth - dragDom.clientWidth) === 0) {
|
||||
return
|
||||
}
|
||||
// 通过事件委托,计算移动的距离 (开始拖拽至结束拖拽的距离)
|
||||
@ -219,9 +210,9 @@ Vue.directive('dialogDrag', {
|
||||
} else if (finallyT > dragDom.offsetParent.clientHeight - dragDom.clientHeight) (///底部
|
||||
finallyT = dragDom.offsetParent.clientHeight - dragDom.clientHeight
|
||||
)
|
||||
x=finallyL;
|
||||
y=finallyT;
|
||||
dragDom.style.transform="translate("+finallyL+"px,"+finallyT+"px)";
|
||||
x = finallyL;
|
||||
y = finallyT;
|
||||
dragDom.style.transform = "translate(" + finallyL + "px," + finallyT + "px)";
|
||||
//将此时的位置传出去
|
||||
// binding.value({x:e.pageX,y:e.pageY})
|
||||
};
|
||||
@ -242,7 +233,7 @@ Vue.directive('dialogDragWidth', {
|
||||
// 鼠标按下,计算当前元素距离可视区的距离
|
||||
const disX = e.clientX - el.offsetLeft
|
||||
|
||||
document.onmousemove = function(e) {
|
||||
document.onmousemove = function (e) {
|
||||
e.preventDefault() // 移动时禁用默认事件
|
||||
|
||||
// 通过事件委托,计算移动的距离
|
||||
@ -250,7 +241,7 @@ Vue.directive('dialogDragWidth', {
|
||||
dragDom.style.width = `${l}px`
|
||||
}
|
||||
|
||||
document.onmouseup = function(e) {
|
||||
document.onmouseup = function (e) {
|
||||
document.onmousemove = null
|
||||
document.onmouseup = null
|
||||
}
|
||||
@ -272,11 +263,13 @@ Vue.directive('clickoutside', { // 初始化指令
|
||||
binding.value(e);
|
||||
}
|
||||
}
|
||||
|
||||
// 给当前元素绑定个私有变量,方便在unbind中可以解除事件监听
|
||||
el.__vueClickOutside__ = documentHandler;
|
||||
document.addEventListener('click', documentHandler);
|
||||
},
|
||||
update() {},
|
||||
update() {
|
||||
},
|
||||
unbind(el, binding) { // 解除事件监听
|
||||
document.removeEventListener('click', el.__vueClickOutside__);
|
||||
delete el.__vueClickOutside__;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user