optimize player

This commit is contained in:
mubai
2023-04-10 18:16:00 +08:00
parent 51cce69df7
commit b791a1db2b
26 changed files with 427 additions and 172 deletions

View File

@@ -11,10 +11,11 @@
},
"dependencies": {
"@element-plus/icons-vue": "^2.1.0",
"@videojs-player/vue": "^1.0.0",
"axios": "^1.3.4",
"element-plus": "^2.3.2",
"vue": "^3.2.47",
"vue3-video-play": "^1.3.1-beta.6"
"video.js": "^8.0.4",
"vue": "^3.2.47"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.1.0",

View File

@@ -64,7 +64,7 @@
</div>
<div class="play_list">
<h2 class="hidden-md-and-down">播放列表:(右侧切换播放源)</h2>
<el-tabs type="card" class="plya_tabs" tab-transition="fade" tab-animation="300" lazy>
<el-tabs type="card" class="play_tabs">
<el-tab-pane v-for="(p,i) in data.detail.playList" :label="`播放地址${i+1}`" >
<div class="play_content">
<a v-for="(item,index) in p" href="javascript:;"
@@ -136,7 +136,7 @@ const showContent = (flag: boolean) => {
</script>
<!--移动端适配-->
<style>
<style scoped>
@media (max-width: 650px) {
.title_mt {
padding: 0 3px;
@@ -190,6 +190,13 @@ const showContent = (flag: boolean) => {
font-size: 12px;
padding: 6px 12px !important;
}
:deep(.el-tabs__item) {
width: 70px;
height: 35px!important;
margin: 17px 5px 0 0 !important;
font-size: 13px;
}
}
</style>
@@ -236,9 +243,16 @@ const showContent = (flag: boolean) => {
margin: 8px 12px;
background: #888888;
}
}
.plya_tabs {
.play_active {
color: orange !important;
background: #424242 !important;
}
.play_content .play_tabs {
background: #2e2e2e;
}
@@ -252,7 +266,7 @@ const showContent = (flag: boolean) => {
margin-bottom: 0;
border-bottom: none !important;
background: rgb(34, 34, 34);
height: 65px !important;
height: 50px !important;
}
:deep(.el-tabs__nav) {
@@ -269,8 +283,8 @@ const showContent = (flag: boolean) => {
}
:deep(.el-tabs__item) {
height: 65px;
line-height: 65px;
height: 50px;
line-height: 50px;
margin-left: 2px;
border-radius: 8px 8px 0 0;
border: none !important;
@@ -278,8 +292,6 @@ const showContent = (flag: boolean) => {
background: #2e2e2e;
}
:deep(.el-tab-pane) {
}
/*顶部影片信息显示区域*/

View File

@@ -1,9 +1,12 @@
<template>
<div class="player_area" v-show="data.loading">
<div class="player_p" >
<videoPlay class="player" v-bind="data.options" poster='/src/assets/image/play.png'
/>
</div>
<div class="player_p">
<video-player @mounted="handleBtn" :src="data.options.src" poster="https://s2.loli.net/2023/04/10/H23F6qDXlnwmPG9.png" controls :loop="false"
@keydown="handlePlay"
:volume="data.options.volume"
crossorigin="anonymous" playsinline class="video-player"
:playback-rates="[0.5, 1.0, 1.5, 2.0]" />
</div>
<div class="current_play_info">
<div class="play_info_left">
<h3 class="current_play_title">{{ `${data.detail.name}&emsp;${data.current.episode}` }}</h3>
@@ -23,12 +26,13 @@
<!-- 播放选集 -->
<div class="play_list">
<h2 class="hidden-md-and-down">播放列表:(右侧切换播放源)</h2>
<el-tabs type="card" v-model="data.currentTabName" class="plya_tabs" >
<el-tabs type="card" v-model="data.currentTabName" class="plya_tabs">
<el-tab-pane v-for="(p,i) in data.detail.playList"
:name="`tab-${i}`"
:label="`播放列表${i+1}`">
<div class="play_content">
<a v-for="(item,index) in p" href="javascript:void(false)" @click="playChange({sourceIndex: i, episodeIndex: index, target: this})"
<a v-for="(item,index) in p" href="javascript:void(false)"
@click="playChange({sourceIndex: i, episodeIndex: index, target: this})"
:class="item.link == data.current.link?'play_active':''">{{ item.episode }}</a>
</div>
@@ -47,12 +51,57 @@
import {onBeforeMount, onMounted, reactive, ref, withDirectives} from "vue";
import {useRouter} from "vue-router";
import {ApiGet} from "../../utils/request";
import {ElMessage} from "element-plus";
import RelateList from "../../components/RelateList.vue";
import {Promotion} from "@element-plus/icons-vue";
// 引入视频播放器组件
import 'vue3-video-play/dist/style.css'
import {videoPlay } from 'vue3-video-play'
import {ElMessage} from "element-plus";
import {VideoPlayer} from '@videojs-player/vue'
import 'video.js/dist/video-js.css'
const handlePlay = (e:any)=>{
e.preventDefault()
switch (e.keyCode) {
case 32:
console.log(e.target.paused)
if(e.target.paused) {
e.target.play()
} else {
e.target.pause()
}
break
case 37:
e.target.currentTime = e.target.currentTime-5 < 0 ? 0 : e.target.currentTime-5
break
case 39:
e.target.currentTime = e.target.currentTime+5 > e.target.duration ? e.target.duration : e.target.currentTime+5
break
case 38:
data.options.volume = data.options.volume + 0.05 > 1 ? 1 : data.options.volume + 0.05
break
case 40:
data.options.volume = data.options.volume - 0.05 < 0 ? 0 : data.options.volume - 0.05
break
}
}
// 主动触发快捷键
const tiggerKeyMap = (keyCode:number)=>{
let player = document.getElementsByTagName("video")[0]
player.focus()
const event = document.createEvent('HTMLEvents');
event.initEvent('keydown', true, false);
event.keyCode = keyCode; // 设置键码
player.dispatchEvent(event)
}
const handleBtn = (e:any)=> {
let btns = document.getElementsByClassName('vjs-button')
for (let el of btns) {
el.addEventListener('keydown', function (t:any){
t.preventDefault()
tiggerKeyMap(t.keyCode)
})
}
}
// 播放页所需数据
@@ -64,23 +113,12 @@ const data = reactive({
currentPlayFrom: 0,
currentEpisode: 0,
relate: [{}],
// vue3-video-play 播放属性设置
// @videojs-player 播放属性设置
options: {
width: '100%', //播放器高度
height: '100%', //播放器高度
color: "rgba(155,73,231,0.72)", //主题色
title: "", //视频名称
src: "", //视频源
type: 'm3u8', //视频类型
muted: false, //静音
webFullScreen: false,
speedRate: ["0.75", "1.0", "1.25", "1.5", "2.0"], //播放倍速
autoPlay: false, //自动播放
loop: false, //循环播放
mirror: false, //镜像画面
ligthOff: false, //关灯模式
volume: 0.3, //默认音量大小
control: true, //是否显示控制器
volume: 0.6, // 音量
currentTime: 0,
}
})
@@ -108,32 +146,54 @@ onBeforeMount(() => {
})
// 点击播集数播放对应影片
const playChange = (play: { sourceIndex: number, episodeIndex: number, target:any }) => {
const playChange = (play: { sourceIndex: number, episodeIndex: number, target: any }) => {
let currPlay = data.detail.playList[play.sourceIndex][play.episodeIndex]
data.current = {index: play.episodeIndex, episode: currPlay.episode, link: currPlay.link}
data.options.src = currPlay.link
data.options.title = `${data.detail.name} ${currPlay.episode} `
data.options.title = data.detail.name + " " + currPlay.episode
}
</script>
<style scoped>
/*vue3-video-play 相关设置*/
/*//播放器控件区域大小*/
:deep(#refPlayerWrap) {
.video-player {
width: 100% !important;
height: 100% !important;
border-radius: 6px;
position: absolute;
}
/*将鼠标右键触发元素的层级降低,回避触发右键视频菜单信息*/
:deep(.d-player-contextmenu){
z-index: -100!important;
border-radius: 6px;
}
:deep(.vjs-big-play-button){
line-height: 2em;
height: 2em;
width: 2em;
border-radius: 50%;
border: none;
background: rgba(0,0,0,0.65);
}
:deep(.vjs-control-bar){
background: rgba(0,0,0,0.32);
}
/*取消video被选中的白边*/
:deep(video:focus) {
border: none!important;
outline: none;
}
:deep(.data-vjs-player:focus){
border: none!important;
outline: none;
}
:deep(.vjs-tech){
border-radius: 6px;
}
:deep(img) {
border-radius: 6px;
}
/*当前播放的影片信息展示*/
.current_play_info {
@@ -177,6 +237,7 @@ const playChange = (play: { sourceIndex: number, episodeIndex: number, target:an
margin: 0 8px;
font-size: 12px;
}
.play_content a {
font-size: 12px;
flex-basis: calc(10% - 24px);
@@ -196,7 +257,6 @@ const playChange = (play: { sourceIndex: number, episodeIndex: number, target:an
margin: 0;
padding-bottom: 56.25% !important;
position: relative;
background: red;
border-radius: 6px;
display: flex;
}
@@ -228,7 +288,6 @@ const playChange = (play: { sourceIndex: number, episodeIndex: number, target:an
}
/*集数选中效果*/
.play_active {
color: orange !important;
@@ -290,6 +349,7 @@ const playChange = (play: { sourceIndex: number, episodeIndex: number, target:an
.player_area {
padding: 5px 10px;
}
.tags b {
padding: 5px 10px;
background-color: rgba(155, 73, 231, 0.72);
@@ -308,6 +368,7 @@ const playChange = (play: { sourceIndex: number, episodeIndex: number, target:an
font-size: 12px;
padding: 6px 12px !important;
}
.tags span {
padding: 6px 10px;
background-color: #404042;
@@ -316,10 +377,11 @@ const playChange = (play: { sourceIndex: number, episodeIndex: number, target:an
margin: 0 3px;
font-size: 12px;
}
:deep(.el-tabs__item){
:deep(.el-tabs__item) {
width: 70px;
height: 35px;
margin: 17px 5px 0 0!important;
margin: 17px 5px 0 0 !important;
font-size: 13px;
}

View File

@@ -7,29 +7,29 @@ import {ElementPlusResolver} from "unplugin-vue-components/resolvers";
// https://vitejs.dev/config/
export default defineConfig({
// 本地测试环境
// server: {
// host: '0.0.0.0',
// port: 3600,
// proxy: {
// "/api": {
// target: `http://127.0.0.1:3601`,
// changeOrigin: true, // 允许跨域
// rewrite: path => path.replace(/^\/api/,'')
// }
// },
// },
// nginx发布构建时使用此配置
server: {
host: 'localhost',
host: '0.0.0.0',
port: 3600,
proxy: {
"/api": {
target: `http://localhost`,
target: `http://127.0.0.1:3601`,
changeOrigin: true, // 允许跨域
rewrite: path => path.replace(/^\/api/,'')
}
},
},
// nginx发布构建时使用此配置
// server: {
// host: 'localhost',
// port: 3600,
// proxy: {
// "/api": {
// target: `http://localhost`,
// changeOrigin: true, // 允许跨域
// rewrite: path => path.replace(/^\/api/,'')
// }
// },
// },
plugins: [
vue(),