feat: 调整视频播放组件(使用腾讯直播sdk)

This commit is contained in:
LittleBoy 2024-12-17 16:51:38 +08:00
parent e1a4005e27
commit 8e6d7fe702
17 changed files with 450 additions and 265 deletions

View File

@ -6,6 +6,7 @@
"description": "数字人直播间",
"scripts": {
"dev": "vite --host",
"dev-test": "vite --host --mode=test",
"build": "tsc && vite build",
"build-test": "tsc && vite build --mode=test",
"build-relative": "tsc && vite build --mode=relative",
@ -31,7 +32,8 @@
"react-dom": "^18.3.1",
"react-player": "^2.16.0",
"react-router-dom": "^6.28.0",
"sass": "^1.81.0"
"sass": "^1.81.0",
"tcplayer.js": "^5.2.0"
},
"devDependencies": {
"@types/file-saver": "^2.0.7",

View File

@ -158,6 +158,12 @@
max-height: calc(100vh - var(--app-header-header) - 200px);
overflow: auto;
}
.video-player{
.video-js{
max-width: 100%;
max-height: 100%;
}
}
.app-main-navigation {
@include media-breakpoint-down(md) {

View File

@ -27,6 +27,7 @@ function rebuildGroups(groups: BlockContent[][]) {
if (!groups || groups.length == 0) return _groups;
groups.forEach((blocks,index) => {
if(!blocks) return;
blocks.sort((a) => a.type == 'text' ? -1 : 1)
if (blocks.length == 1) {
if(index == 0) _groups.push(blocks)
else pushBlocksToGroup(blocks,_groups)

View File

@ -1,18 +1,33 @@
import ReactPlayer from 'react-player'
import { PauseOutlined, PlayCircleOutlined, FullscreenOutlined, FullscreenExitOutlined } from "@ant-design/icons"
import { Progress } from "antd";
import {useState} from "react";
// import ReactPlayer from 'react-player'
// import {PauseOutlined, PlayCircleOutlined, FullscreenOutlined, FullscreenExitOutlined} from "@ant-design/icons"
// import {Progress} from "antd";
import React, {useEffect, useState} from "react";
import TCPlayer from 'tcplayer.js';
import 'tcplayer.js/dist/tcplayer.min.css';
type State = {
playing: boolean
muted: boolean
end?: boolean
error?: boolean
fullscreen: boolean
progress: number
playedSeconds: number
duration: number
}
type StateUpdate = Partial<State> | ((prev: State) => Partial<State>)
export function Player({ url, cover, simple, showControls }: { url: string; cover?: string; simple?: boolean; showControls?: boolean }) {
type Props = {
url?: string; cover?: string; showControls?: boolean; className?: string;
onChange?: (state: State) => void;
}
export type PlayerInstance = {
play: (url: string, currentTime: number) => void;
getState: () => State;
}
export const Player = React.forwardRef<PlayerInstance, Props>((props, ref) => {
const [tcPlayer, setTcPlayer] = useState<TCPlayer | null>(null)
const [prevUrl, setPrevUrl] = useState<string | undefined>();
const [state, _setState] = useState<State>({
playing: false,
muted: false,
@ -22,51 +37,64 @@ export function Player({ url, cover, simple, showControls }: { url: string; cove
playedSeconds: 0,
duration: 0
})
const setState = (data: StateUpdate) => {
console.log('playstate change', data)
_setState(prev => {
if (typeof(data) === 'function') return { ...prev, ...data(prev) }
return { ...prev, ...data }
const _state = typeof (data) === 'function' ? {...prev, ...data(prev)} : {...prev, ...data}
props.onChange?.(_state)
return _state
})
}
return <div className="video-player">
{simple ? <div>
<video style={{width:400,height:400}} preload={'metadata'} src={url} poster={cover} controls={showControls}></video>
</div> : <>
<ReactPlayer
url={url}
controls={true}
light={cover}
width="100%"
height="250px"
onPlay={() => setState({ playing: true })}
onEnded={() => setState({ playing: false })}
onPause={() => setState({ playing: false })}
onReady={(_player) => {
setState({duration: _player.getDuration() })
}}
onProgress={(_) => {
setState(_prev=>({
playedSeconds: _.playedSeconds,
progress: Math.floor(_.playedSeconds / _prev.duration * 100)
}))
}}
/>
<div className="video-control p-2 flex items-center gap-2">
<button>
{state.playing ? <PauseOutlined /> : <PlayCircleOutlined />}
</button>
<div className="whitespace-nowrap flex items-center text-sm">
<span>00:00</span>
<span>/</span>
<span>00:00</span>
</div>
<div className="flex-1">
<Progress size="small" percent={state.progress} showInfo={false} />
</div>
<button>
{state.fullscreen ? <FullscreenExitOutlined /> : <FullscreenOutlined />}
</button>
</div>
</>}
useEffect(() => {
return () => {
if (tcPlayer) tcPlayer.unload()
}
}, [])
React.useImperativeHandle(ref, () => {
return {
play: (url, currentTime = 0) => {
const player = tcPlayer || TCPlayer(
'player-container-id',
{
sources: [{src: url}],
controls: false,
licenseUrl: 'https://license.vod2.myqcloud.com/license/v2/1328581896_1/v_cube.license'
}
)
player.on('pause', () => {
setState({playing: false, end: false, error: false})
})
player.on('playing', () => {
setState({playing: true, end: false, error: false})
})
player.on('ended', () => {
setState({end: true, playing: false, error: false})
})
player.on('error', () => {
setState({end: false, playing: false, error: true})
})
if (!tcPlayer) {
setTcPlayer(() => player)
}
if(prevUrl == url){
player.currentTime(0)
}else{
player.src(url)
}
player.play()
setPrevUrl(url)
if (currentTime > 0) {
player.currentTime(currentTime)
}
},
getState: () => state
}
})
return <div className={`video-player relative ${props.className}`}>
<video id="player-container-id" className="" preload="auto"
playsInline webkit-playsinline="true">
</video>
</div>
}
})

View File

@ -3,10 +3,11 @@ import {useSetState} from "ahooks";
import React, {useEffect} from "react";
import {clsx} from "clsx";
import {Popconfirm} from "antd";
import {CheckCircleFilled, MenuOutlined, MinusCircleFilled} from "@ant-design/icons";
import {CheckCircleFilled, MenuOutlined, MinusCircleFilled,LoadingOutlined} from "@ant-design/icons";
import ImageCover from '@/assets/images/cover.png'
import {IconEdit, IconPlay} from "@/components/icons";
import {VideoStatus} from "@/service/api/video.ts";
type Props = {
video: VideoInfo | LiveVideoInfo,
@ -21,14 +22,14 @@ type Props = {
onRemove?: () => void;
id: number;
className?: string;
type?:'live'|'create'
}
export const VideoListItem = (
{
// index,
id, video, onPlay, onRemove, checked,
onCheckedChange, onEdit, active, editable,
className, sortable
className, sortable,type
}: Props) => {
const {
attributes, listeners,
@ -59,8 +60,16 @@ export const VideoListItem = (
<MenuOutlined/>
</button> : <button disabled className="cursor-not-allowed"><MenuOutlined/></button>)}
{onPlay &&
<button className="hover:text-blue-500" onClick={onPlay} style={{fontSize: '1.3em'}}><IconPlay/>
</button>}
<>
{(
type == 'create' && video.status == VideoStatus.Generating
) ? <button title="视频生成中" className="flex items-center justify-center">
<LoadingOutlined className="block text-gray-500" style={{fontSize: '0.85em'}}/>
</button>: <button className="hover:text-blue-500" onClick={onPlay} style={{fontSize: '1.3em'}}><IconPlay/>
</button>
}
</>}
{editable && <>
{onEdit &&
<button className="hover:text-blue-500" onClick={onEdit} style={{fontSize: '1.1em'}}><IconEdit/>

View File

@ -1,90 +0,0 @@
import {useRef, useState} from "react";
import {Button} from "antd";
import FlvJs from "flv.js";
const list = [
{
"id": 10,
"cover_url": "",
"video_id": 51,
"video_title": "以军称在加沙地带打死一名哈马斯高级官员",
"video_duration": 31910,
"video_oss_url": "https://staticplus.gachafun.com/ai-collect/composite_video/2024-12-14/1185251497659736064.flv",
"status": 4,
"order_no": ""
},
{
"id": 8,
"cover_url": "",
"video_id": 43,
"video_title": "历时12天史上第三人 尹锡悦总统弹劾案获通过 一文梳理韩国政坛众生相",
"video_duration": 728840,
"video_oss_url": "https://staticplus.gachafun.com/ai-collect/composite_video/2024-12-14/1185229869001351168.flv",
"status": 4,
"order_no": ""
},
{
"id": 9,
"cover_url": "",
"video_id": 44,
"video_title": "推动房地产市场止跌回稳,发力重点在哪里?",
"video_duration": 57500,
"video_oss_url": "https://staticplus.gachafun.com/ai-collect/composite_video/2024-12-14/1185229857764810752.flv",
"status": 4,
"order_no": ""
},
{
"id": 11,
"cover_url": "",
"video_id": 52,
"video_title": "以军称在加沙地带打死一名哈马斯高级官员",
"video_duration": 37980,
"video_oss_url": "https://staticplus.gachafun.com/ai-collect/composite_video/2024-12-14/1185251495390617600.flv",
"status": 4,
"order_no": ""
}
]
const cache:{
flvPlayer?: FlvJs.Player
} = {
}
export default function Test() {
const videoRef = useRef<HTMLVideoElement | null>(null)
const [index, setIndex] = useState(-1)
const load = (url: string) => {
if (FlvJs.isSupported()) {
if(cache.flvPlayer){
cache.flvPlayer.pause()
cache.flvPlayer.unload()
}
cache.flvPlayer = FlvJs.createPlayer({
type: 'flv',
url: url
})
cache.flvPlayer.attachMediaElement(videoRef.current!)
cache.flvPlayer.load()
cache.flvPlayer.play()
}
// const url = 'https://staticplus.gachafun.com/ai-collect/composite_video/2024-12-14/1185229869001351168.flv'
// if (videoRef.current) {
// videoRef.current!.src = url
// videoRef.current?.play()
// }
}
const play = () => {
const next = index >= list.length - 1 ? 0 : index + 1
load(list[next].video_oss_url)
setIndex(next)
}
return (<div className="test container m-auto">
<div className="my-10">
<video controls className="border w-[400px] max-h-[600px]" ref={videoRef}></video>
</div>
<Button onClick={play}>load {index > -1 ? <span>
{index} {list[index].video_title}
</span>:''}</Button>
</div>)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

View File

@ -2,7 +2,7 @@ import {useState} from "react";
import {useNavigate, useSearchParams} from "react-router-dom";
import type {FormProps} from 'antd';
import {LockOutlined, UserOutlined} from '@ant-design/icons';
import {Button, Checkbox, Flex, Form, Input} from 'antd';
import {Button, Checkbox, Divider, Flex, Form, Input} from 'antd';
import {clsx} from "clsx";
import useAuth from "@/hooks/useAuth.ts";
@ -37,7 +37,7 @@ export default function FormLogin() {
};
return (<div className="form">
<h1 className={'text-center text-2xl pb-10 pt-4'}></h1>
<Divider className=" pb-8 pt-4"><div className={'text-center text-2xl'}></div></Divider>
<Form<FieldType>
name="basic"
style={{maxWidth: 600}}
@ -72,17 +72,10 @@ export default function FormLogin() {
</div>
</Form.Item>
<Form.Item>
<div className="absolute text-red-500 text-center inset-x-0" style={{top: -20}}>{error}</div>
<Flex justify="space-between" align="center">
<Form.Item name="remember" valuePropName="checked" noStyle>
<Checkbox></Checkbox>
</Form.Item>
<a href=""></a>
</Flex>
</Form.Item>
<Form.Item>
<Form.Item className={"mt-14"}>
<div className="absolute text-red-500 text-center inset-x-0" style={{top: -30}}>{error}</div>
<Button disabled={disabled || loading} loading={loading} type="primary" size={'large'} htmlType="submit"
block shape={'round'}>
{loading ? '登录中...' : '立即登录'}

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

View File

@ -1,9 +1,11 @@
import styles from './style.module.scss'
import FormLogin from "./components/form-login.tsx";
import useAuth from "@/hooks/useAuth.ts";
import {useNavigate, useSearchParams} from "react-router-dom";
import {useEffect} from "react";
import useAuth from "@/hooks/useAuth.ts";
import MainBgImage from './components/bg.png'
import styles from './style.module.scss'
import FormLogin from "./components/form-login.tsx";
export default function UserIndex(){
const {user} = useAuth();
const navigate = useNavigate() ;
@ -14,6 +16,10 @@ export default function UserIndex(){
}
}, [user])
return (<div className={styles.main}>
<div className={"flex-1 ml-[15%]"}>
{/*<h2 className="text-4xl mb-10 text-white/90">数字人直播间</h2>*/}
<img className="w-[450px]" src={MainBgImage} alt=""/>
</div>
<div className={styles.boxLogin}>
<FormLogin />
</div>

View File

@ -1,6 +1,6 @@
.main {
@apply py-10;
background-image: url(https://lf-webcast-platform.bytetos.com/obj/webcast-platform-cdn/ies/webcast_union_platform/static/image/bg.71a36267.png);
background-image: url(components/main-bg.jpg);
background-size: 100% 100%;
height: 100vh;
min-height: 500px;

View File

@ -1,26 +1,32 @@
import {Button, Modal} from "antd";
import React, {useState} from "react";
import {showErrorToast, showToast} from "@/components/message.ts";
import {push2room} from "@/service/api/video.ts";
import {push2room, VideoStatus} from "@/service/api/video.ts";
export default function ButtonPush2Room(props: { ids: Id[]}){
const [loading,setLoading] = useState(false)
const handlePush = ()=>{
export default function ButtonPush2Room(props: { ids: Id[]; list: VideoInfo[] }) {
const [loading, setLoading] = useState(false)
const handlePush = () => {
setLoading(true)
push2room(props.ids).then(()=>{
showToast('一键推流成功,已推流至数字人直播间,请前往数字人直播间页面查看!', 'success')
}).catch(showErrorToast).finally(()=>{
// 只需要已经生成视频的数据id
const vids = props.list.filter(v => v.status == VideoStatus.Generated && props.ids.includes(v.id)).map(v => v.id)
push2room(vids).then(() => {
if(props.ids.length == vids.length){
showToast('一键推流成功,已推流至数字人直播间,请前往数字人直播间页面查看!', 'success')
}else{
showToast('选择视频中有部分视频还在生成中无法推送,推流成功视频前往数字人直播间页面查看!', 'success')
}
}).catch(showErrorToast).finally(() => {
setLoading(false)
})
}
const onPushClick = ()=>{
const onPushClick = () => {
if (props.ids.length === 0) {
showToast('请选择要推流的新闻', 'warning')
return
}
Modal.confirm({
title:'操作提示',
title: '操作提示',
content: '是否确定一键推流选中新闻视频??',
onOk: handlePush
})

View File

@ -8,18 +8,18 @@ import {clsx} from "clsx";
import {VideoListItem} from "@/components/video/video-list-item.tsx";
import ArticleEditModal from "@/components/article/edit-modal.tsx";
import {deleteByIds, getList, modifyOrder, push2room} from "@/service/api/video.ts";
import {deleteByIds, getList, modifyOrder, VideoStatus} from "@/service/api/video.ts";
import {formatDuration} from "@/util/strings.ts";
import ButtonBatch from "@/components/button-batch.tsx";
import {showToast} from "@/components/message.ts";
import FlvJs from "flv.js";
import {Player, PlayerInstance} from "@/components/video/player.tsx";
import ButtonPush2Room from "@/pages/video/components/button-push2room.tsx";
const cache:{flvPlayer?: FlvJs.Player} = {}
export default function VideoIndex() {
const [editId, setEditId] = useState(-1)
const [videoData, setVideoData] = useState<VideoInfo[]>([])
const [modal, contextHolder] = Modal.useModal()
const videoRef = useRef<HTMLVideoElement | null>(null)
const player = useRef<PlayerInstance>(null)
const [state, setState] = useSetState({
checkedAll: false,
playingIndex: -1,
@ -27,34 +27,27 @@ export default function VideoIndex() {
const [checkedIdArray, setCheckedIdArray] = useState<number[]>([])
// 加载列表
const loadList = () => {
const loadList = (needReset = true) => {
getList().then((ret) => {
setCheckedIdArray([])
setVideoData(ret.list || [])
setState({checkedAll: false, playingIndex: -1})
const list = ret.list || []
setVideoData(list)
if (needReset) {
setCheckedIdArray([])
setState({checkedAll: false, playingIndex: -1})
}
// 判断是否有生成中的视频
if (list.filter(s => s.status == VideoStatus.Generating).length > 0) {
// 每5s重新获取一次最新数据
setTimeout(() => loadList(false), 5000)
}
})
}
// 播放视频
const playVideo = (video: VideoInfo, playingIndex: number) => {
if (videoRef.current && video.oss_video_url) {
if (video.oss_video_url && video.status == 2) {
setState({playingIndex})
if (FlvJs.isSupported()) {
// 已经有播放实例 则销毁
if(cache.flvPlayer){
cache.flvPlayer.pause()
cache.flvPlayer.unload()
}
cache.flvPlayer = FlvJs.createPlayer({
type: 'flv',
url: video.oss_video_url
})
cache.flvPlayer.attachMediaElement(videoRef.current!)
cache.flvPlayer.load()
cache.flvPlayer.play()
}
videoRef.current!.src = video.oss_video_url
player.current?.play(video.oss_video_url, 0)
}
}
// 处理全选
@ -83,7 +76,7 @@ export default function VideoIndex() {
return (<div className="container py-10 page-live">
{contextHolder}
<div className="flex">
<div className="video-list-container bg-white p-10 rounded flex-1">
<div className="video-list-container bg-white p-10 rounded flex flex-col flex-1">
<div className="live-control flex justify-between mb-5">
<div className="pl-[70px]">
<span>: {formatDuration(totalDuration)}</span>
@ -94,8 +87,8 @@ export default function VideoIndex() {
selected={checkedIdArray}
emptyMessage={`请选择要删除的新闻视频`}
confirmMessage={`是否删除当前的${checkedIdArray.length}个新闻视频?`}
onSuccess={()=>{
showToast('删除成功!','success')
onSuccess={() => {
showToast('删除成功!', 'success')
loadList()
}}
></ButtonBatch>
@ -106,7 +99,7 @@ export default function VideoIndex() {
</button>
</div>
</div>
<div className={'video-list-sort-container'}>
<div className={'video-list-sort-container flex-1'}>
<div className="flex my-2">
{videoData.length == 0 ? <div className="m-auto"><Empty/></div> : <>
<div className="sort-number-container mr-2">
@ -146,6 +139,7 @@ export default function VideoIndex() {
index={index + 1}
id={v.id}
key={index}
type={'create'}
active={state.playingIndex == index}
checked={checkedIdArray.includes(v.id)}
className={`list-item-${index} mt-3 mb-2`}
@ -170,22 +164,28 @@ export default function VideoIndex() {
</div>
</div>
<div className="text-right mt-5">
<ButtonBatch
type={'primary'}
onProcess={push2room}
selected={checkedIdArray}
emptyMessage={`请选择要推流的新闻`}
confirmMessage={`是否确定一键推流选中新闻视频?`}
onSuccess={loadList}
></ButtonBatch>
{/*<ButtonPush2Room ids={checkedIdArray}/>*/}
{/*<ButtonBatch*/}
{/* type={'primary'}*/}
{/* onProcess={push2room}*/}
{/* selected={checkedIdArray}*/}
{/* emptyMessage={`请选择要推流的新闻`}*/}
{/* confirmMessage={`是否确定一键推流选中新闻视频?`}*/}
{/* onSuccess={loadList}*/}
{/*>一键推流</ButtonBatch>*/}
<ButtonPush2Room ids={checkedIdArray}/>
</div>
</div>
<div className="video-player-container ml-16 min-w-[360px] flex flex-col">
<div className="text-center text-base mt-10"></div>
<div className="video-player flex items-center mt-20">
<div className=" rounded overflow-hidden">
<video ref={videoRef} controls autoPlay className="w-full bg-white min-w-[360px]"></video>
<div className="video-player-container ml-16 w-[360px] flex flex-col">
<div className="text-center text-base"></div>
<div className="video-player flex items-center mt-2">
<div className=" w-[360px] h-[640px] rounded overflow-hidden">
{/*<video ref={videoRef} poster={videoData[state.playingIndex]?.cover} preload="auto" playsinline webkit-playsinline className="w-full bg-white w-[360px] h-[640px]"></video>*/}
<Player
ref={player} url={videoData[state.playingIndex]?.oss_video_url}
onChange={(state) => {
if (state.end || state.end) setState({playingIndex: -1})
}}
className="w-[360px] h-[640px] bg-white"/>
</div>
</div>
</div>

View File

@ -1,23 +1,22 @@
import {RouteObject} from "react-router-dom";
import ErrorBoundary from "@/routes/error.tsx";
import UserAuth from "@/pages/user";
import Test from "@/pages/test";
import CreateIndex from "../pages/video";
import LibraryIndex from "@/pages/library";
import LiveIndex from "@/pages/live";
import NewsIndex from "@/pages/news";
import NewsEdit from "@/pages/news/edit.tsx";
;
import DashboardLayout from "@/routes/layout/dashboard-layout.tsx";
import React from "react";
const UserAuth = React.lazy(() => import("@/pages/user"))
const CreateVideoIndex = React.lazy(() => import("@/pages/video"))
const LibraryIndex = React.lazy(() => import("@/pages/library"))
const LiveIndex = React.lazy(() => import("@/pages/live"))
const NewsIndex = React.lazy(() => import("@/pages/news"))
const NewsEdit = React.lazy(() => import("@/pages/news/edit.tsx"))
const routes: RouteObject[] = [
{
path: '/user',
element: <UserAuth/>,
},
{
path: '/test',
element: <Test/>,
},
{
path: '/',
element: <DashboardLayout/>,
@ -33,7 +32,7 @@ const routes: RouteObject[] = [
},
{
path: 'create',
element: <CreateIndex/>
element: <CreateVideoIndex/>
},
{
path: 'library',

View File

@ -36,4 +36,11 @@ export function modifyOrder(ids: Id[]) {
export function push2room(video_ids: Id[]) {
return post('/video/push2room', {video_ids})
}
export enum VideoStatus {
// 生成中
Generating = 1,
// 已生成
Generated = 2,
}

View File

@ -4,44 +4,50 @@ import {resolve} from "path";
// https://vitejs.dev/config/
export default defineConfig(({mode}) => {
return {
plugins: [react()],
base: process.env.PUBLIC_PATH || (mode == 'relative' ? './' : '/'),
define: {
AppConfig: JSON.stringify({
SITE_URL: process.env.APP_SITE_URL || null,
API_PREFIX: process.env.APP_API_PREFIX || '/mgmt/v1/metahuman',
AUTH_TOKEN_KEY: process.env.AUTH_TOKEN_KEY || 'digital-person-token',
AUTHED_PERSON_DATA_KEY: process.env.AUTHED_PERSON_DATA_KEY || 'digital-person-user-info',
}),
AppMode: JSON.stringify(mode)
},
resolve: {
alias: {
'@': resolve(__dirname, './src')
}
},
css:{
preprocessorOptions:{
scss:{
api:'modern'
}
}
},
server: {
port: 10021,
proxy: {
'/mgmt': {
target: 'http://124.220.14.192', // http://124.220.14.192/ 192.168.0.231:9999
changeOrigin: true,
// rewrite: (path) => path.replace(/^\/api/, '')
},
'/api': {
target: 'http://124.220.14.192',
changeOrigin: true,
// rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
}
const devServerHost = mode == 'test' ? '124.220.14.192' : '192.168.0.231:9999'
const AUTH_TOKEN_KEY = mode == 'production' ? 'digital-person-token' : `digital-person-token_${mode}`
if (mode !== 'production') {
console.log('dev server is', devServerHost,mode)
}
return {
plugins: [react()],
base: process.env.PUBLIC_PATH || (mode == 'relative' ? './' : '/'),
define: {
AppConfig: JSON.stringify({
SITE_URL: process.env.APP_SITE_URL || null,
API_PREFIX: process.env.APP_API_PREFIX || '/mgmt/v1/metahuman',
AUTH_TOKEN_KEY: process.env.AUTH_TOKEN_KEY || AUTH_TOKEN_KEY,
AUTHED_PERSON_DATA_KEY: process.env.AUTHED_PERSON_DATA_KEY || 'digital-person-user-info',
}),
AppMode: JSON.stringify(mode)
},
resolve: {
alias: {
'@': resolve(__dirname, './src')
}
},
css: {
preprocessorOptions: {
scss: {
api: 'modern'
}
}
},
server: {
port: 10021,
proxy: {
'/mgmt': {
target: `http://${devServerHost}`, // http://124.220.14.192/ 192.168.0.231:9999
changeOrigin: true,
// rewrite: (path) => path.replace(/^\/api/, '')
},
'/api': {
target: `http://${devServerHost}`,
changeOrigin: true,
// rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
}
})

214
yarn.lock
View File

@ -1137,6 +1137,14 @@ axios@^1.7.7:
form-data "^4.0.0"
proxy-from-env "^1.1.0"
babel-runtime@^6.9.2:
version "6.26.0"
resolved "https://registry.npmmirror.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
integrity sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==
dependencies:
core-js "^2.4.0"
regenerator-runtime "^0.11.0"
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
@ -1147,6 +1155,11 @@ binary-extensions@^2.0.0:
resolved "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522"
integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==
blueimp-md5@^2.10.0:
version "2.19.0"
resolved "https://registry.npmmirror.com/blueimp-md5/-/blueimp-md5-2.19.0.tgz#b53feea5498dcb53dc6ec4b823adb84b729c4af0"
integrity sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@ -1213,6 +1226,11 @@ chalk@^4.0.0:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
charenc@0.0.2:
version "0.0.2"
resolved "https://registry.npmmirror.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
integrity sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==
chokidar@^3.6.0:
version "3.6.0"
resolved "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b"
@ -1291,6 +1309,11 @@ copy-to-clipboard@^3.3.3:
dependencies:
toggle-selection "^1.0.6"
core-js@^2.4.0:
version "2.6.12"
resolved "https://registry.npmmirror.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
core-util-is@~1.0.0:
version "1.0.3"
resolved "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
@ -1305,6 +1328,11 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2:
shebang-command "^2.0.0"
which "^2.0.1"
crypt@0.0.2:
version "0.0.2"
resolved "https://registry.npmmirror.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==
cssesc@^3.0.0:
version "3.0.0"
resolved "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
@ -1327,6 +1355,11 @@ debug@^4.1.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4:
dependencies:
ms "^2.1.3"
decode-uri-component@^0.2.0:
version "0.2.2"
resolved "https://registry.npmmirror.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9"
integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==
deep-is@^0.1.3:
version "0.1.4"
resolved "https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
@ -1380,6 +1413,11 @@ doctrine@^3.0.0:
dependencies:
esutils "^2.0.2"
dom-walk@^0.1.0:
version "0.1.2"
resolved "https://registry.npmmirror.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84"
integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==
eastasianwidth@^0.2.0:
version "0.2.0"
resolved "https://registry.npmmirror.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
@ -1412,6 +1450,11 @@ es-errors@^1.3.0:
resolved "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
es5-shim@^4.5.1:
version "4.6.7"
resolved "https://registry.npmmirror.com/es5-shim/-/es5-shim-4.6.7.tgz#bc67ae0fc3dd520636e0a1601cc73b450ad3e955"
integrity sha512-jg21/dmlrNQI7JyyA2w7n+yifSxBng0ZralnSfVZjoCawgNTCnS+yBCyVM9DL5itm7SUnDGgv7hcq2XCZX4iRQ==
es6-promise@^4.2.8:
version "4.2.8"
resolved "https://registry.npmmirror.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
@ -1734,6 +1777,22 @@ glob@^7.1.3:
once "^1.3.0"
path-is-absolute "^1.0.0"
global@4.3.2, global@~4.3.0:
version "4.3.2"
resolved "https://registry.npmmirror.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f"
integrity sha512-/4AybdwIDU4HkCUbJkZdWpe4P6vuw/CUtu+0I1YlLIPe7OlUO7KNJ+q/rO70CW2/NW6Jc6I62++Hzsf5Alu6rQ==
dependencies:
min-document "^2.19.0"
process "~0.5.1"
global@^4.3.1:
version "4.4.0"
resolved "https://registry.npmmirror.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406"
integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==
dependencies:
min-document "^2.19.0"
process "^0.11.10"
globals@^11.1.0:
version "11.12.0"
resolved "https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
@ -1827,6 +1886,11 @@ imurmurhash@^0.1.4:
resolved "https://registry.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
individual@^2.0.0:
version "2.0.0"
resolved "https://registry.npmmirror.com/individual/-/individual-2.0.0.tgz#833b097dad23294e76117a98fb38e0d9ad61bb97"
integrity sha512-pWt8hBCqJsUWI/HtcfWod7+N9SgAqyPEaF7JQjwzjn5vGrpg6aQ5qeAFQ7dx//UH4J1O+7xqew+gCeeFt6xN/g==
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
@ -1852,6 +1916,11 @@ is-binary-path@~2.1.0:
dependencies:
binary-extensions "^2.0.0"
is-buffer@~1.1.6:
version "1.1.6"
resolved "https://registry.npmmirror.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
is-core-module@^2.13.0:
version "2.15.1"
resolved "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.15.1.tgz#a7363a25bee942fefab0de13bf6aa372c82dcc37"
@ -1869,6 +1938,11 @@ is-fullwidth-code-point@^3.0.0:
resolved "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
is-function@^1.0.1:
version "1.0.2"
resolved "https://registry.npmmirror.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08"
integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==
is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
version "4.0.3"
resolved "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
@ -1927,6 +2001,11 @@ js-yaml@^4.1.0:
dependencies:
argparse "^2.0.1"
jsencrypt@^3.2.0:
version "3.3.2"
resolved "https://registry.npmmirror.com/jsencrypt/-/jsencrypt-3.3.2.tgz#b0f1a2278810c7ba1cb8957af11195354622df7c"
integrity sha512-arQR1R1ESGdAxY7ZheWr12wCaF2yF47v5qpB76TtV64H1pyGudk9Hvw8Y9tb/FiTIaaTRUyaSnm5T/Y53Ghm/A==
jsesc@^3.0.2:
version "3.0.2"
resolved "https://registry.npmmirror.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e"
@ -2047,6 +2126,15 @@ lru-cache@^5.1.1:
dependencies:
yallist "^3.0.2"
md5@^2.3.0:
version "2.3.0"
resolved "https://registry.npmmirror.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f"
integrity sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==
dependencies:
charenc "0.0.2"
crypt "0.0.2"
is-buffer "~1.1.6"
memoize-one@^5.1.1:
version "5.2.1"
resolved "https://registry.npmmirror.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e"
@ -2077,6 +2165,13 @@ mime-types@^2.1.12:
dependencies:
mime-db "1.52.0"
min-document@^2.19.0:
version "2.19.0"
resolved "https://registry.npmmirror.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
integrity sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==
dependencies:
dom-walk "^0.1.0"
minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
version "3.1.2"
resolved "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
@ -2140,7 +2235,7 @@ normalize-range@^0.1.2:
resolved "https://registry.npmmirror.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==
object-assign@^4.0.1, object-assign@^4.1.1:
object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
@ -2205,6 +2300,11 @@ parent-module@^1.0.0:
dependencies:
callsites "^3.0.0"
parse-headers@^2.0.0:
version "2.0.5"
resolved "https://registry.npmmirror.com/parse-headers/-/parse-headers-2.0.5.tgz#069793f9356a54008571eb7f9761153e6c770da9"
integrity sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==
path-exists@^4.0.0:
version "4.0.0"
resolved "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
@ -2321,6 +2421,16 @@ process-nextick-args@~2.0.0:
resolved "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
process@^0.11.10:
version "0.11.10"
resolved "https://registry.npmmirror.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==
process@~0.5.1:
version "0.5.2"
resolved "https://registry.npmmirror.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf"
integrity sha512-oNpcutj+nYX2FjdEW7PGltWhXulAnFlM0My/k48L90hARCOJtvBbQXc/6itV2jDvU5xAAtonP+r6wmQgCcbAUA==
prop-types@^15.7.2:
version "15.8.1"
resolved "https://registry.npmmirror.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
@ -2347,6 +2457,15 @@ qs@^6.12.1:
dependencies:
side-channel "^1.0.6"
query-string@^5.0.1:
version "5.1.1"
resolved "https://registry.npmmirror.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb"
integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==
dependencies:
decode-uri-component "^0.2.0"
object-assign "^4.1.0"
strict-uri-encode "^1.0.0"
queue-microtask@^1.2.2:
version "1.2.3"
resolved "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
@ -2795,6 +2914,11 @@ readdirp@~3.6.0:
dependencies:
picomatch "^2.2.1"
regenerator-runtime@^0.11.0:
version "0.11.1"
resolved "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
regenerator-runtime@^0.14.0:
version "0.14.1"
resolved "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f"
@ -2865,11 +2989,25 @@ run-parallel@^1.1.9:
dependencies:
queue-microtask "^1.2.2"
rust-result@^1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/rust-result/-/rust-result-1.0.0.tgz#34c75b2e6dc39fe5875e5bdec85b5e0f91536f72"
integrity sha512-6cJzSBU+J/RJCF063onnQf0cDUOHs9uZI1oroSGnHOph+CQTIJ5Pp2hK5kEQq1+7yE/EEWfulSNXAQ2jikPthA==
dependencies:
individual "^2.0.0"
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.2"
resolved "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
safe-json-parse@4.0.0:
version "4.0.0"
resolved "https://registry.npmmirror.com/safe-json-parse/-/safe-json-parse-4.0.0.tgz#7c0f578cfccd12d33a71c0e05413e2eca171eaac"
integrity sha512-RjZPPHugjK0TOzFrLZ8inw44s9bKox99/0AZW9o/BEQVrJfhI+fIHMErnPyRa89/yRXUUr93q+tiN6zhoVV4wQ==
dependencies:
rust-result "^1.0.0"
sass@^1.81.0:
version "1.81.0"
resolved "https://registry.npmmirror.com/sass/-/sass-1.81.0.tgz#a9010c0599867909dfdbad057e4a6fbdd5eec941"
@ -2964,6 +3102,21 @@ slash@^3.0.0:
resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
store2@^2.7.1:
version "2.14.3"
resolved "https://registry.npmmirror.com/store2/-/store2-2.14.3.tgz#24077d7ba110711864e4f691d2af941ec533deb5"
integrity sha512-4QcZ+yx7nzEFiV4BMLnr/pRa5HYzNITX2ri0Zh6sT9EyQHbBHacC6YigllUPU9X3D0f/22QCgfokpKs52YRrUg==
store@^2.0.12:
version "2.0.12"
resolved "https://registry.npmmirror.com/store/-/store-2.0.12.tgz#8c534e2a0b831f72b75fc5f1119857c44ef5d593"
integrity sha512-eO9xlzDpXLiMr9W1nQ3Nfp9EzZieIQc10zPPMP5jsVV7bLOziSFFBP0XoDXACEIFtdI+rIz0NwWVA/QVJ8zJtw==
strict-uri-encode@^1.0.0:
version "1.1.0"
resolved "https://registry.npmmirror.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
integrity sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==
string-convert@^0.2.0:
version "0.2.1"
resolved "https://registry.npmmirror.com/string-convert/-/string-convert-0.2.1.tgz#6982cc3049fbb4cd85f8b24568b9d9bf39eeff97"
@ -3072,6 +3225,26 @@ tailwindcss@^3.4.7:
resolve "^1.22.8"
sucrase "^3.35.0"
tcplayer.js@^5.2.0:
version "5.2.0"
resolved "https://registry.npmmirror.com/tcplayer.js/-/tcplayer.js-5.2.0.tgz#95a1cf8e5548a831d1eb945a3585cfd7e9f4480b"
integrity sha512-rXxHhS9ajp07maE81OXNrsOQuPbvrW/GVn+Z+aS9Oxpl8yC/pIg8wthUZUK/C1Va3GNZt6bE2oFoQTPut3bRww==
dependencies:
babel-runtime "^6.9.2"
blueimp-md5 "^2.10.0"
global "4.3.2"
jsencrypt "^3.2.0"
md5 "^2.3.0"
query-string "^5.0.1"
safe-json-parse "4.0.0"
store "^2.0.12"
store2 "^2.7.1"
tsml "1.0.1"
videojs-font "2.1.0"
videojs-ie8 "1.1.2"
videojs-vtt.js "0.12.4"
xhr "2.4.0"
text-table@^0.2.0:
version "0.2.0"
resolved "https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
@ -3123,6 +3296,11 @@ tslib@^2.0.0, tslib@^2.4.1:
resolved "https://registry.npmmirror.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
tsml@1.0.1:
version "1.0.1"
resolved "https://registry.npmmirror.com/tsml/-/tsml-1.0.1.tgz#89f8218b9d9e257f47d7f6b56d01c5a4d2c68fc3"
integrity sha512-3KmepnH9SUsoOVtg013CRrL7c+AK7ECaquAsJdvu4288EDJuraqBlP4PDXT/rLEJ9YDn4jqLAzRJsnFPx+V6lg==
type-check@^0.4.0, type-check@~0.4.0:
version "0.4.0"
resolved "https://registry.npmmirror.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
@ -3165,6 +3343,25 @@ util-deprecate@^1.0.2, util-deprecate@~1.0.1:
resolved "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
videojs-font@2.1.0:
version "2.1.0"
resolved "https://registry.npmmirror.com/videojs-font/-/videojs-font-2.1.0.tgz#a25930a67f6c9cfbf2bb88dacb8c6b451f093379"
integrity sha512-zFqWpLrXf1q8NtYx5qtZhMC6SLUFScDmR6j+UGPogobxR21lvXShhnzcNNMdOxJUuFLiToJ/BPpFUQwX4xhpvA==
videojs-ie8@1.1.2:
version "1.1.2"
resolved "https://registry.npmmirror.com/videojs-ie8/-/videojs-ie8-1.1.2.tgz#a23d3d8608ad7192b69c6077fc4eb848998d35d9"
integrity sha512-0Zb2T4MLkpfZbeGMK/Z93b8Lrepr+rLFoHgQV1CoDeFqXvH7b+Vsd/VHoILGxQrgCSHFQ7mAODR6oyMjuiD4/g==
dependencies:
es5-shim "^4.5.1"
videojs-vtt.js@0.12.4:
version "0.12.4"
resolved "https://registry.npmmirror.com/videojs-vtt.js/-/videojs-vtt.js-0.12.4.tgz#38f2499e31efb3fa93590ddad4cb663275a4b161"
integrity sha512-JQ5eozH5SLOL5xI8ALb1aWf9HjcewQmOytf1gPIsFBTQlSgtSdJ8E8x0GO0ZEXVtFCaPDFiYWAhrjuTI125tBQ==
dependencies:
global "^4.3.1"
vite@^5.2.0:
version "5.4.11"
resolved "https://registry.npmmirror.com/vite/-/vite-5.4.11.tgz#3b415cd4aed781a356c1de5a9ebafb837715f6e5"
@ -3216,6 +3413,21 @@ wrappy@1:
resolved "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
xhr@2.4.0:
version "2.4.0"
resolved "https://registry.npmmirror.com/xhr/-/xhr-2.4.0.tgz#e16e66a45f869861eeefab416d5eff722dc40993"
integrity sha512-TUbBsdAuJbX8olk9hsDwGK8P1ri1XlV+PdEWkYw+HQQbpkiBR8PLgD1F3kQDPBs9l4Px34hP9rCYAZOCCAENbw==
dependencies:
global "~4.3.0"
is-function "^1.0.1"
parse-headers "^2.0.0"
xtend "^4.0.0"
xtend@^4.0.0:
version "4.0.2"
resolved "https://registry.npmmirror.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
yallist@^3.0.2:
version "3.1.1"
resolved "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"