Pre Merge pull request !224 from 有梦的人/dev

This commit is contained in:
有梦的人 2025-07-04 03:44:13 +00:00 committed by Gitee
commit a13de09eab
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
5 changed files with 150 additions and 3 deletions

View File

@ -44,7 +44,9 @@
"vue-json-pretty": "2.4.0",
"vue-router": "4.5.0",
"vue-types": "6.0.0",
"vxe-table": "4.13.7"
"vxe-table": "4.13.7",
"xgplayer": "^3.0.22",
"xgplayer-flv": "^3.0.22"
},
"devDependencies": {
"@iconify/json": "^2.2.276",

View File

@ -11,7 +11,7 @@ import { usePermissionStore } from '@/store/modules/permission';
import { ElMessage } from 'element-plus/es';
NProgress.configure({ showSpinner: false });
const whiteList = ['/login', '/register', '/social-callback', '/register*', '/register/*'];
const whiteList = ['/test/*', '/login', '/register', '/social-callback', '/register*', '/register/*'];
const isWhiteList = (path: string) => {
return whiteList.some((pattern) => isPathMatch(pattern, path));

View File

@ -42,6 +42,11 @@ export const constantRoutes: RouteRecordRaw[] = [
hidden: true,
component: () => import('@/layout/components/SocialCallback/index.vue')
},
{
path: '/test/xgplayer',
component: () => import('@/views/test/xgplayer.vue'),
hidden: true
},
{
path: '/login',
component: () => import('@/views/login.vue'),

View File

@ -28,7 +28,7 @@
<el-button v-hasPermi="['system:menu:add']" type="primary" plain icon="Plus" @click="handleAdd()">新增 </el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" @click="handleCascadeDelete" :loading="deleteLoading">级联删除</el-button>
<el-button v-hasPermi="['system:menu:remove']" type="danger" plain icon="Delete" @click="handleCascadeDelete" :loading="deleteLoading">级联删除</el-button>
</el-col>
<right-toolbar v-model:show-search="showSearch" @query-table="getList"></right-toolbar>
</el-row>

140
src/views/test/xgplayer.vue Normal file
View File

@ -0,0 +1,140 @@
<template>
<div>
<!-- 布局选择按钮 -->
<div class="layout-controls">
<button @click="setLayout(1)">1×1</button>
<button @click="setLayout(2)">2×2</button>
<button @click="setLayout(3)">3×3</button>
<button @click="setLayout(4)">4×4</button>
</div>
<!-- 视频容器 -->
<div class="video-container" :class="`grid-${layout}`">
<div v-for="n in layoutCount" :key="n" :id="`vs${n}`" class="video-item"></div>
</div>
</div>
</template>
<script setup name="xgplayer" lang="ts">
import Player from 'xgplayer';
import FlvPlugin from 'xgplayer-flv';
import 'xgplayer/dist/index.min.css';
import { ref, onMounted } from 'vue';
const layout = ref<number>(1); // 1×12×2...
const players = ref<Record<string, any>>({}); //
//
const videoUrls = [
'https://szaq.fjlyyc.com:38443/live/vsigf8eCxFu4f545f19bfe44352bcdc4/live.flv',
'your_flv_url_2',
'your_flv_url_3',
'your_flv_url_4',
'your_flv_url_5',
'your_flv_url_6',
'your_flv_url_7',
'your_flv_url_8',
'your_flv_url_9',
'your_flv_url_10',
'your_flv_url_11',
'your_flv_url_12',
'your_flv_url_13',
'your_flv_url_14',
'your_flv_url_15',
'your_flv_url_16'
];
//
const layoutCount = ref<number>(1);
//
const setLayout = (size: number) => {
layout.value = size;
layoutCount.value = size * size;
// DOM
nextTick(() => {
initPlayers();
});
};
//
const initPlayers = () => {
//
Object.values(players.value).forEach((player) => {
if (player && player.destroy) {
player.destroy();
}
});
players.value = {};
const totalPlayers = layoutCount.value;
for (let i = 1; i <= totalPlayers; i++) {
const url = videoUrls[(i - 1) % videoUrls.length]; // 使 URL
try {
players.value[`player${i}`] = new Player({
id: `vs${i}`,
isLive: true,
plugins: [FlvPlugin],
url,
autoplay: true,
loop: true
});
} catch (error) {
console.error(`Player ${i} initialization failed:`, error);
}
}
};
onMounted(() => {
layoutCount.value = layout.value * layout.value;
initPlayers();
});
</script>
<style lang="scss" scoped>
.video-container {
width: 100vw; //
height: 100vh; //
display: grid;
gap: 8px; //
padding: 0; //
box-sizing: border-box;
background-color: #000;
position: relative;
}
.grid-1 {
grid-template-columns: 1fr;
grid-template-rows: 1fr;
}
.grid-2 {
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(2, 1fr);
}
.grid-3 {
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
}
.grid-4 {
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(4, 1fr);
}
.video-item {
position: relative;
width: 100%;
height: 100%;
background-color: #000;
border: 1px solid #333;
border-radius: 4px;
overflow: hidden;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}
</style>