mirror of
https://github.com/ProudMuBai/GoFilm.git
synced 2026-02-04 06:54:41 +08:00
optimize player
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
|
||||
/*顶部影片信息显示区域*/
|
||||
|
||||
|
||||
@@ -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} ${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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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(),
|
||||
|
||||
Reference in New Issue
Block a user