feat: 为xgplayer增加一个类似于bilibili的锁定的插件

This commit is contained in:
539943419 committed 2024-09-26 17:02:28 +08:00
1 parent 3a18bb3cbd
commit 54c48c0f8f
5 files changed
+174 -8

No files matched your search

+1 -1
View File
@@ -15,7 +15,7 @@ const pluginConfig: registerComponentOption = {
return false
}
for (let i of vFiles) {
for (let s of ['mp4']) {
for (let s of ['mp4', 'mp3']) {
if (i.name.endsWith(s)) {
return true
}
@@ -15,6 +15,7 @@ import XGPlayer from 'xgplayer'
import '@/style/xgplayer.scss'
import TextTrack from 'xgplayer/es/plugins/track'
import 'xgplayer/es/plugins/track/index.css'
import lockScreen from './playerPlugin/lockScreen'
import axios from 'axios'
import { uniq } from 'lodash'
// import config from '@/config'
@@ -93,7 +94,7 @@ const { setVideo } = (() => {
}
_player && _player.destroy()
_player = new XGPlayer({
plugins: [TextTrack],
plugins: [TextTrack, lockScreen],
el: xgPlayer.value,
url: videoVFile.url,
width: '100%',
@@ -105,7 +106,7 @@ const { setVideo } = (() => {
download: true,
screenShot: {
saveImg: true,
quality: 0.92,
quality: 1,
type: 'image/png',
format: '.png'
},
@@ -285,7 +286,7 @@ function ssaToVtt(ssaContent: string): string {
const findVideo = (vFiles: VirtualFile[]) =>
vFiles.filter((v) => {
for (let s of ['mp4', 'm3u8', 'hls']) {
for (let s of ['mp4', 'mp3']) {
if (v.name.endsWith(s)) {
return true
}
@@ -0,0 +1,46 @@
.lock-div {
position: absolute;
z-index: 20;
left: 15px;
top: 50%;
transform: translateY(-50%);
width: 30px;
aspect-ratio: 1;
cursor: pointer;
color: #f2f2f2;
opacity: 1;
visibility: visible;
transition: opacity 0.5s ease, visibility 0.5s ease, width 0.25s ease, left 0.25s ease;
svg {
width: inherit;
height: inherit;
}
&:hover {
width: 36px;
left: 12px;
}
}
.xgplayer.xgplayer-inactive .lock-div {
pointer-events: none;
cursor: default;
visibility: hidden;
opacity: 0;
}
.overlay-div {
position: absolute;
z-index: 10;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0);
display: none;
cursor: auto;
}
.xgplayer.xgplayer-inactive .overlay-div {
pointer-events: none;
cursor: none;
}
@@ -0,0 +1,119 @@
import { BasePlugin } from 'xgplayer'
import './lockScreen.scss'
interface LockPluginConfig {
lockText: string
unlockText: string
}
export default class LockPlugin extends BasePlugin {
static get pluginName() {
return 'lockPlugin'
}
static get defaultConfig(): LockPluginConfig {
return {
lockText: '锁定',
unlockText: '解锁'
}
}
private locked: boolean
private lockDiv: HTMLDivElement | null = null
private overlayDiv: HTMLDivElement | null = null
private lockOpenSVG: string = `
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path d="M336 208v-95a80 80 0 0 0-160 0v95" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32"></path>
<rect x="96" y="208" width="320" height="272" rx="48" ry="48" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32"></rect>
</svg>`
private lockClosedSVG: string = `
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path d="M336 112a80 80 0 0 0-160 0v96" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32"></path>
<rect x="96" y="208" width="320" height="272" rx="48" ry="48" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32"></rect>
</svg>`
constructor(args: any) {
super(args)
this.locked = false
}
afterCreate() {
this.createLockDiv()
this.createOverlayDiv()
this.bindEvents()
}
private createLockDiv() {
this.lockDiv = document.createElement('div')
this.lockDiv.innerHTML = this.lockClosedSVG
this.lockDiv.className = 'lock-div'
this.player.root !== null && this.player.root.appendChild(this.lockDiv)
}
private createOverlayDiv() {
this.overlayDiv = document.createElement('div')
this.overlayDiv.className = 'overlay-div'
this.player.root !== null &&
this.player.root.appendChild(this.overlayDiv)
}
private bindEvents() {
this.lockDiv!.addEventListener('click', this.toggleLock.bind(this))
this.player.root !== null &&
this.player.root.addEventListener(
'click',
this.preventClick.bind(this),
true
)
}
private toggleLock() {
if (this.lockDiv && this.overlayDiv) {
this.locked = !this.locked
this.lockDiv.innerHTML = this.locked
? this.lockOpenSVG
: this.lockClosedSVG
this.overlayDiv.style.display = this.locked ? 'block' : 'none'
this.player.controls &&
(this.locked
? this.player.controls.hide()
: this.player.controls.show())
this.player.root !== null &&
this.player.root.classList.toggle('locked', this.locked)
}
}
private preventClick(event: MouseEvent) {
if (
this.locked &&
event.target instanceof HTMLElement &&
!event.target.classList.contains('lock-div')
) {
event.stopPropagation()
event.preventDefault()
}
}
destroy() {
if (this.lockDiv) {
this.lockDiv.removeEventListener(
'click',
this.toggleLock.bind(this)
)
this.player.root !== null &&
this.player.root.removeEventListener(
'click',
this.preventClick.bind(this),
true
)
this.player.root !== null &&
this.player.root.removeChild(this.lockDiv)
}
if (this.overlayDiv) {
this.player.root !== null &&
this.player.root.removeChild(this.overlayDiv)
}
}
}