lzc-video-player 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +1 -0
- package/.eslintrc.cjs +18 -0
- package/.prettierrc.json +5 -0
- package/AGENTS.md +31 -0
- package/README.md +38 -0
- package/build.sh +10 -0
- package/demo/.vscode/extensions.json +3 -0
- package/demo/README.md +40 -0
- package/demo/env.d.ts +1 -0
- package/demo/index.html +13 -0
- package/demo/package-lock.json +2037 -0
- package/demo/package.json +25 -0
- package/demo/public/favicon.ico +0 -0
- package/demo/src/App.vue +25 -0
- package/demo/src/assets/base.css +70 -0
- package/demo/src/assets/logo.svg +1 -0
- package/demo/src/assets/main.css +33 -0
- package/demo/src/main.ts +8 -0
- package/demo/tsconfig.config.json +8 -0
- package/demo/tsconfig.json +16 -0
- package/demo/vite.config.ts +14 -0
- package/docs/progress-bar-style-analysis.md +87 -0
- package/env.d.ts +1 -0
- package/error_pages/502.html.tpl +13 -0
- package/i18next-parser.config.mjs +147 -0
- package/index.html +54 -0
- package/lazycat.png +0 -0
- package/lib/README.md +48 -0
- package/lib/package.json +22 -0
- package/lzc-build.local.yml +65 -0
- package/lzc-build.yml +65 -0
- package/lzc-manifest.yml +53 -0
- package/makefile +15 -0
- package/package.json +69 -0
- package/postcss.config.js +6 -0
- package/public/512x512.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/languages/en/translation.json +125 -0
- package/public/languages/zh/translation.json +125 -0
- package/public/libass-wasm/4.1.0/default.woff2 +0 -0
- package/public/libass-wasm/4.1.0/subtitles-octopus-worker-legacy.js +40 -0
- package/public/libass-wasm/4.1.0/subtitles-octopus-worker.js +1 -0
- package/public/libass-wasm/4.1.0/subtitles-octopus-worker.wasm +0 -0
- package/public/libass-wasm/4.1.0/subtitles-octopus.js +1680 -0
- package/public/square-128x128.png +0 -0
- package/public/square-256x256.png +0 -0
- package/public/square-512x512.png +0 -0
- package/src/App.vue +18 -0
- package/src/assets/base.scss +104 -0
- package/src/assets/cloud.png +0 -0
- package/src/assets/logo.svg +1 -0
- package/src/components/Dialog/index.vue +96 -0
- package/src/components/MultipleEdit/choose.vue +39 -0
- package/src/components/PlayList/index.vue +521 -0
- package/src/components/Spectrum/index.vue +58 -0
- package/src/components/Video/NativeVideoPlayer.vue +748 -0
- package/src/components/Video/README.md +3 -0
- package/src/components/Video/clientPlayer.ts +348 -0
- package/src/components/Video/components/LzcModal/components/simpleList.vue +57 -0
- package/src/components/Video/components/LzcModal/list.vue +52 -0
- package/src/components/Video/components/LzcModal/playrate.vue +45 -0
- package/src/components/Video/components/LzcModal/resolution.vue +117 -0
- package/src/components/Video/components/LzcModal/subtitle.vue +499 -0
- package/src/components/Video/components/LzcModal/useModal.ts +18 -0
- package/src/components/Video/components/LzcOverlay/SubtitleLayer.vue +321 -0
- package/src/components/Video/components/LzcOverlay/cast.vue +253 -0
- package/src/components/Video/components/LzcOverlay/casting.vue +205 -0
- package/src/components/Video/components/LzcOverlay/error.vue +103 -0
- package/src/components/Video/components/LzcOverlay/helper.ts +81 -0
- package/src/components/Video/components/LzcOverlay/index.vue +99 -0
- package/src/components/Video/components/LzcOverlay/playing.vue +496 -0
- package/src/components/Video/components/LzcOverlay/playingButtons.vue +122 -0
- package/src/components/Video/components/LzcOverlay/playingLayout.vue +287 -0
- package/src/components/Video/components/LzcOverlay/useCast.ts +235 -0
- package/src/components/Video/components/LzcOverlay/useCommon.ts +41 -0
- package/src/components/Video/components/LzcOverlay/useOctopusRenderer.ts +230 -0
- package/src/components/Video/components/LzcOverlay/useSubtitleRenderEngine.ts +79 -0
- package/src/components/Video/components/LzcOverlay/useSubtitleTrack.ts +139 -0
- package/src/components/Video/components/useLzcCommon.ts +16 -0
- package/src/components/Video/directPlay.ts +345 -0
- package/src/components/Video/getSubtitleInfo.ts +42 -0
- package/src/components/Video/native/EventEmitter.ts +62 -0
- package/src/components/Video/native/NativeControls.vue +510 -0
- package/src/components/Video/native/NativeModal.vue +133 -0
- package/src/components/Video/native/NativePlayer.ts +913 -0
- package/src/components/Video/native/NativePlayer.vue +53 -0
- package/src/components/Video/native/index.ts +9 -0
- package/src/components/Video/native/native-player.css +183 -0
- package/src/components/Video/native/playerKey.ts +5 -0
- package/src/components/Video/native/useNativeCastMiddleware.ts +50 -0
- package/src/components/Video/native/useNativePlayer.ts +3 -0
- package/src/components/Video/native/useNativePlayerFullscreen.ts +44 -0
- package/src/components/Video/native/useNativePlayerHistory.ts +69 -0
- package/src/components/Video/native/useNativePlayerModal.ts +68 -0
- package/src/components/Video/native/useNativePlayerPlaylist.ts +67 -0
- package/src/components/Video/native/useNativePlayerState.ts +225 -0
- package/src/components/Video/player.ts +99 -0
- package/src/components/Video/theme/index.scss +291 -0
- package/src/components/Video/theme/videojs.css +1797 -0
- package/src/components/Video/useSource.ts +1431 -0
- package/src/components/Video/useSubtitlePreference.ts +66 -0
- package/src/components/Video/useWebview.ts +79 -0
- package/src/components/Video/videoFrame.ts +58 -0
- package/src/env.d.ts +3 -0
- package/src/i18n/README.md +392 -0
- package/src/i18n/index.ts +49 -0
- package/src/icons/Video_Player.svg +69 -0
- package/src/icons/box.svg +15 -0
- package/src/icons/client.svg +17 -0
- package/src/icons/logo.svg +28 -0
- package/src/icons//344/270/212/344/270/200/344/270/252.svg +6 -0
- package/src/icons//344/270/213/344/270/200/344/270/252.svg +4 -0
- package/src/icons//344/272/256/345/272/246.svg +13 -0
- package/src/icons//345/200/215/351/200/237.svg +14 -0
- package/src/icons//345/205/250/345/261/217.svg +16 -0
- package/src/icons//345/205/250/351/200/211_/345/267/262/351/200/211/344/270/255.svg +16 -0
- package/src/icons//345/205/250/351/200/211_/346/234/252/351/200/211/344/270/255.svg +15 -0
- package/src/icons//345/205/263/351/227/255/345/244/232/351/200/211.svg +14 -0
- package/src/icons//345/205/263/351/227/255/346/212/225/345/261/217.svg +11 -0
- package/src/icons//345/233/236/346/224/266/347/253/231.svg +15 -0
- package/src/icons//345/244/261/346/225/210.svg +17 -0
- package/src/icons//346/207/222/347/214/253/346/222/255/346/224/276/345/231/250-icon.png +0 -0
- package/src/icons//346/207/222/347/214/253/346/222/255/346/224/276/345/231/250.png +0 -0
- package/src/icons//346/212/225/345/261/217.svg +11 -0
- package/src/icons//346/212/225/351/200/201/344/270/255.jpg +0 -0
- package/src/icons//346/212/225/351/200/201/344/270/255.svg +21 -0
- package/src/icons//346/222/255/346/224/276.svg +3 -0
- package/src/icons//346/232/202/345/201/234.svg +4 -0
- package/src/icons//346/232/202/346/227/240.svg +21 -0
- package/src/icons//346/233/264/345/244/232/346/223/215/344/275/234.svg +11 -0
- package/src/icons//347/224/265/350/247/206.svg +18 -0
- package/src/icons//347/247/273/345/212/250/347/253/257_/350/203/214/346/231/257.webp +0 -0
- package/src/icons//350/203/214/346/231/257.png +0 -0
- package/src/icons//350/277/224/345/233/236.svg +13 -0
- package/src/icons//350/277/233/345/205/245/345/205/250/345/261/217.svg +13 -0
- package/src/icons//351/200/200/345/207/272/345/205/250/345/261/217.svg +15 -0
- package/src/icons//351/200/211/346/213/251.svg +15 -0
- package/src/icons//351/237/263/351/207/217.svg +13 -0
- package/src/index.d.ts +9 -0
- package/src/lzc-video-player.scss +7 -0
- package/src/lzc-video-player.ts +6 -0
- package/src/main.ts +62 -0
- package/src/model.ts +77 -0
- package/src/quasar-variables.sass +10 -0
- package/src/router/index.ts +74 -0
- package/src/stores/pinia.ts +3 -0
- package/src/stores/playlist.ts +146 -0
- package/src/use/useKeyBind.ts +61 -0
- package/src/use/useMultipleEdit.ts +60 -0
- package/src/use/useSdk.ts +5 -0
- package/src/use/useSubtitle.ts +39 -0
- package/src/use/useUtils.ts +22 -0
- package/src/use/useVideoFrame.ts +60 -0
- package/src/views/Home.ts +99 -0
- package/src/views/mobile/Home.vue +246 -0
- package/src/views/mobile/Player.vue +141 -0
- package/tailwind.config.js +15 -0
- package/tsconfig.config.json +8 -0
- package/tsconfig.json +20 -0
- package/vite.config.lib.ts +88 -0
- package/vite.config.ts +122 -0
- package/vue-shim.d.ts +4 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "demo",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"scripts": {
|
|
5
|
+
"dev": "vite",
|
|
6
|
+
"build": "run-p type-check build-only",
|
|
7
|
+
"preview": "vite preview --port 4173",
|
|
8
|
+
"build-only": "vite build",
|
|
9
|
+
"type-check": "vue-tsc --noEmit"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@lazycatcloud/lzc-video-player": "file:../lib",
|
|
13
|
+
"pinia": "^2.0.21",
|
|
14
|
+
"vue": "^3.2.38"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@types/node": "^16.11.56",
|
|
18
|
+
"@vitejs/plugin-vue": "^3.0.3",
|
|
19
|
+
"@vue/tsconfig": "^0.1.3",
|
|
20
|
+
"npm-run-all": "^4.1.5",
|
|
21
|
+
"typescript": "~4.7.4",
|
|
22
|
+
"vite": "^3.0.9",
|
|
23
|
+
"vue-tsc": "^0.40.7"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
Binary file
|
package/demo/src/App.vue
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { LzcVideoPlayer } from "@lazycatcloud/lzc-video-player"
|
|
3
|
+
function onBack() {
|
|
4
|
+
console.log("onback")
|
|
5
|
+
}
|
|
6
|
+
function onInit(player: any) {
|
|
7
|
+
console.log("player: ", player)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const options: any = {
|
|
11
|
+
showTopBar: false,
|
|
12
|
+
}
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<template>
|
|
16
|
+
<LzcVideoPlayer
|
|
17
|
+
:style="{
|
|
18
|
+
height: '100%',
|
|
19
|
+
width: '100%',
|
|
20
|
+
}"
|
|
21
|
+
@back="onBack"
|
|
22
|
+
:on-init="onInit"
|
|
23
|
+
:options="options"
|
|
24
|
+
/>
|
|
25
|
+
</template>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/* color palette from <https://github.com/vuejs/theme> */
|
|
2
|
+
:root {
|
|
3
|
+
--vt-c-white: #ffffff;
|
|
4
|
+
--vt-c-white-soft: #f8f8f8;
|
|
5
|
+
--vt-c-white-mute: #f2f2f2;
|
|
6
|
+
|
|
7
|
+
--vt-c-black: #181818;
|
|
8
|
+
--vt-c-black-soft: #222222;
|
|
9
|
+
--vt-c-black-mute: #282828;
|
|
10
|
+
|
|
11
|
+
--vt-c-indigo: #2c3e50;
|
|
12
|
+
|
|
13
|
+
--vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
|
|
14
|
+
--vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
|
|
15
|
+
--vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
|
|
16
|
+
--vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
|
|
17
|
+
|
|
18
|
+
--vt-c-text-light-1: var(--vt-c-indigo);
|
|
19
|
+
--vt-c-text-light-2: rgba(60, 60, 60, 0.66);
|
|
20
|
+
--vt-c-text-dark-1: var(--vt-c-white);
|
|
21
|
+
--vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/* semantic color variables for this project */
|
|
25
|
+
:root {
|
|
26
|
+
--color-background: var(--vt-c-white);
|
|
27
|
+
--color-background-soft: var(--vt-c-white-soft);
|
|
28
|
+
--color-background-mute: var(--vt-c-white-mute);
|
|
29
|
+
|
|
30
|
+
--color-border: var(--vt-c-divider-light-2);
|
|
31
|
+
--color-border-hover: var(--vt-c-divider-light-1);
|
|
32
|
+
|
|
33
|
+
--color-heading: var(--vt-c-text-light-1);
|
|
34
|
+
--color-text: var(--vt-c-text-light-1);
|
|
35
|
+
|
|
36
|
+
--section-gap: 160px;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@media (prefers-color-scheme: dark) {
|
|
40
|
+
:root {
|
|
41
|
+
--color-background: var(--vt-c-black);
|
|
42
|
+
--color-background-soft: var(--vt-c-black-soft);
|
|
43
|
+
--color-background-mute: var(--vt-c-black-mute);
|
|
44
|
+
|
|
45
|
+
--color-border: var(--vt-c-divider-dark-2);
|
|
46
|
+
--color-border-hover: var(--vt-c-divider-dark-1);
|
|
47
|
+
|
|
48
|
+
--color-heading: var(--vt-c-text-dark-1);
|
|
49
|
+
--color-text: var(--vt-c-text-dark-2);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
html,
|
|
54
|
+
body {
|
|
55
|
+
margin: 0;
|
|
56
|
+
padding: 0;
|
|
57
|
+
width: 100vw;
|
|
58
|
+
height: 100vh;
|
|
59
|
+
color: var(--color-text);
|
|
60
|
+
background: var(--color-background);
|
|
61
|
+
transition: color 0.5s, background-color 0.5s;
|
|
62
|
+
line-height: 1.6;
|
|
63
|
+
font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
|
64
|
+
Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue",
|
|
65
|
+
sans-serif;
|
|
66
|
+
font-size: 15px;
|
|
67
|
+
text-rendering: optimizeLegibility;
|
|
68
|
+
-webkit-font-smoothing: antialiased;
|
|
69
|
+
-moz-osx-font-smoothing: grayscale;
|
|
70
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69" xmlns:v="https://vecta.io/nano"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
@import "./base.css";
|
|
2
|
+
|
|
3
|
+
#app {
|
|
4
|
+
width: 100vw;
|
|
5
|
+
height: 100vh;
|
|
6
|
+
font-weight: normal;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
a,
|
|
10
|
+
.green {
|
|
11
|
+
text-decoration: none;
|
|
12
|
+
color: hsla(160, 100%, 37%, 1);
|
|
13
|
+
transition: 0.4s;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@media (hover: hover) {
|
|
17
|
+
a:hover {
|
|
18
|
+
background-color: hsla(160, 100%, 37%, 0.2);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@media (min-width: 1024px) {
|
|
23
|
+
body {
|
|
24
|
+
display: flex;
|
|
25
|
+
place-items: center;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
#app {
|
|
29
|
+
display: grid;
|
|
30
|
+
grid-template-columns: 1fr 1fr;
|
|
31
|
+
padding: 0 2rem;
|
|
32
|
+
}
|
|
33
|
+
}
|
package/demo/src/main.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "@vue/tsconfig/tsconfig.web.json",
|
|
3
|
+
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
|
|
4
|
+
"compilerOptions": {
|
|
5
|
+
"baseUrl": ".",
|
|
6
|
+
"paths": {
|
|
7
|
+
"@/*": ["./src/*"]
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
|
|
11
|
+
"references": [
|
|
12
|
+
{
|
|
13
|
+
"path": "./tsconfig.config.json"
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { fileURLToPath, URL } from "node:url"
|
|
2
|
+
|
|
3
|
+
import { defineConfig } from "vite"
|
|
4
|
+
import vue from "@vitejs/plugin-vue"
|
|
5
|
+
|
|
6
|
+
// https://vitejs.dev/config/
|
|
7
|
+
export default defineConfig({
|
|
8
|
+
plugins: [vue()],
|
|
9
|
+
resolve: {
|
|
10
|
+
alias: {
|
|
11
|
+
"@": fileURLToPath(new URL("./src", import.meta.url)),
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
})
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# 进度条样式分析
|
|
2
|
+
|
|
3
|
+
## 一、原生播放器进度条(当前使用)
|
|
4
|
+
|
|
5
|
+
### 1. 结构位置
|
|
6
|
+
|
|
7
|
+
- **文件**:`src/components/Video/native/NativeControls.vue`
|
|
8
|
+
- **DOM**:`.native-progress-wrap` 内:左侧时间 → `<input type="range" class="native-range native-progress">` → 右侧时间
|
|
9
|
+
- **布局**:在 `.native-controls-wrap` 内,进度条在控制栏上方(`bottom: 4rem`),与主题 `.vjs-theme-lzc` 一致
|
|
10
|
+
|
|
11
|
+
### 2. 样式定义(native-theme.scss)
|
|
12
|
+
|
|
13
|
+
| 元素 | 类名 | 说明 |
|
|
14
|
+
|------|------|------|
|
|
15
|
+
| 进度条容器 | `.native-progress-wrap` | `position: absolute`,`bottom: 4rem`,`padding: 0 2rem`(≥480px 为 4.4rem),横向 flex |
|
|
16
|
+
| 时间文字 | `.native-time` | 1.2rem、PingFangSC-Semibold、白色;首项 `margin-right: 1.7rem`,末项 `margin-left: 1.7rem` |
|
|
17
|
+
| 滑轨(range) | `.native-range.native-progress` | 轨道 + 拇指样式 |
|
|
18
|
+
|
|
19
|
+
### 3. 滑轨与拇指
|
|
20
|
+
|
|
21
|
+
- **轨道**
|
|
22
|
+
- `flex: 1`,`height: 0.2rem`,`min-height: 0.2rem`
|
|
23
|
+
- `padding: 1.2rem 0`(增大可点区域)
|
|
24
|
+
- `background: $native-progress-bg` → `rgba(255,255,255,0.3)`
|
|
25
|
+
- `border-radius: 0.15rem`
|
|
26
|
+
- `-webkit-appearance: none` / `appearance: none`
|
|
27
|
+
|
|
28
|
+
- **拇指(Thumb)**
|
|
29
|
+
- **WebKit**:`::-webkit-slider-thumb`
|
|
30
|
+
- 1.2rem × 1.2rem,圆角 0.65rem
|
|
31
|
+
- 背景 `$native-progress-played`(#5f86ff)
|
|
32
|
+
- `box-shadow: 0 0 0 0.7rem rgba(95,134,255,0.15)`(外圈光晕)
|
|
33
|
+
- **Firefox**:`::-moz-range-thumb`
|
|
34
|
+
- 同尺寸、同背景、无边框
|
|
35
|
+
|
|
36
|
+
### 4. 变量(与主题一致)
|
|
37
|
+
|
|
38
|
+
```scss
|
|
39
|
+
$native-progress-played: #5f86ff; // 已播放/拇指
|
|
40
|
+
$native-progress-bg: rgba(255, 255, 255, 0.3); // 轨道背景
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 5. 行为与数据
|
|
44
|
+
|
|
45
|
+
- **数值**:`displayProgressPercent`(拖拽时用 `seekValue`,否则用 `currentTime/duration`)
|
|
46
|
+
- **事件**:`@input` 实时 seek,`@change` / `@mouseup` / `@touchend` 结束拖拽并同步时间
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 二、与原版 Video.js 主题对比(.vjs-theme-lzc)
|
|
51
|
+
|
|
52
|
+
| 项目 | 原版 (theme/index.scss) | 原生 (native-theme.scss) |
|
|
53
|
+
|------|-------------------------|---------------------------|
|
|
54
|
+
| 进度条位置 | `bottom: 6.3rem`,padding 2rem / 4.4rem | 在 `.native-progress-wrap` 内,整体 `bottom: 4rem`,padding 一致 |
|
|
55
|
+
| 轨道高度 | `.vjs-progress-holder` 高 0.2rem,上下 padding 1.2rem | range 高 0.2rem,padding 1.2rem 0 |
|
|
56
|
+
| 轨道背景 | `&:after` 宽 100%、高 0.2rem、`$progress-color` | range 背景 `$native-progress-bg`(同色) |
|
|
57
|
+
| 已播放色 | `.vjs-play-progress` 背景 #5f86ff | 拇指 #5f86ff,**轨道已播放段** 需用 range 渐变或伪元素实现 |
|
|
58
|
+
| 拇指/圆点 | `.vjs-play-progress:after` 1.2rem×1.2rem,圆角 0.65rem,右侧 -0.6rem | 拇指 1.2rem×1.2rem,圆角 0.65rem |
|
|
59
|
+
| 时间字体 | progress-text mixin:1.2rem、PingFangSC-Semibold | `.native-time` 一致 |
|
|
60
|
+
|
|
61
|
+
原版还有 `.vjs-play-progress:before`(2.6rem 大圆、opacity 0.15)做光晕;原生用 `box-shadow` 做拇指外圈,效果类似。
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 三、当前差异与可选优化
|
|
66
|
+
|
|
67
|
+
1. **轨道“已播放”颜色**
|
|
68
|
+
原版整段已播放是蓝色条;原生用的是 `<input type="range">`,**轨道左侧已播放部分**在部分浏览器下不会自动变蓝,需要:
|
|
69
|
+
- 用 `linear-gradient` 根据 `value` 画左侧蓝色、右侧灰色,或
|
|
70
|
+
- 用 `::-webkit-slider-runnable-track` / `::-moz-range-track` 做分段背景。
|
|
71
|
+
|
|
72
|
+
2. **内联 style**
|
|
73
|
+
`NativeControls.vue` 里进度条有 `style="height: 10px"`,会覆盖 scss 的 `0.2rem`,若要保持和原版一致,建议去掉内联 height,统一用样式表。
|
|
74
|
+
|
|
75
|
+
3. **模板里的静态块**
|
|
76
|
+
同一 template 里有一段带 `.vjs-progress` 的静态结构(写死的 4:13、56:59、7.42% 等),没有绑定数据,也不会被原生逻辑使用,可删除避免干扰或误以为在用 Video.js 进度条。
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 四、相关文件一览
|
|
81
|
+
|
|
82
|
+
| 文件 | 作用 |
|
|
83
|
+
|------|------|
|
|
84
|
+
| `native/NativeControls.vue` | 进度条 DOM、range 绑定与事件 |
|
|
85
|
+
| `native/native-theme.scss` | 进度条容器、时间、轨道、拇指样式 |
|
|
86
|
+
| `theme/index.scss` | 原版 .vjs-theme-lzc 进度条样式参考 |
|
|
87
|
+
| `components/LzcProgress.ts` | Video.js 版进度组件(原生播放器未用) |
|
package/env.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author: Bin
|
|
3
|
+
* @Date: 2025-01-06
|
|
4
|
+
* @FilePath: /lzc-video-player/i18next-parser.config.mjs
|
|
5
|
+
*/
|
|
6
|
+
export default {
|
|
7
|
+
contextSeparator: "_",
|
|
8
|
+
// Key separator used in your translation keys
|
|
9
|
+
|
|
10
|
+
createOldCatalogs: true,
|
|
11
|
+
// Save the \_old files
|
|
12
|
+
|
|
13
|
+
defaultNamespace: "translation",
|
|
14
|
+
// Default namespace used in your i18next config
|
|
15
|
+
|
|
16
|
+
defaultValue: "",
|
|
17
|
+
// Default value to give to keys with no value
|
|
18
|
+
// You may also specify a function accepting the locale, namespace, key, and value as arguments
|
|
19
|
+
|
|
20
|
+
indentation: 2,
|
|
21
|
+
// Indentation of the catalog files
|
|
22
|
+
|
|
23
|
+
keepRemoved: false,
|
|
24
|
+
// Keep keys from the catalog that are no longer in code
|
|
25
|
+
// You may either specify a boolean to keep or discard all removed keys.
|
|
26
|
+
// You may also specify an array of patterns: the keys from the catalog that are no long in the code but match one of the patterns will be kept.
|
|
27
|
+
// The patterns are applied to the full key including the namespace, the parent keys and the separators.
|
|
28
|
+
|
|
29
|
+
keySeparator: ".",
|
|
30
|
+
// Key separator used in your translation keys
|
|
31
|
+
// If you want to use plain english keys, separators such as `.` and `:` will conflict. You might want to set `keySeparator: false` and `namespaceSeparator: false`. That way, `t('Status: Loading...')` will not think that there are a namespace and three separator dots for instance.
|
|
32
|
+
|
|
33
|
+
// see below for more details
|
|
34
|
+
lexers: {
|
|
35
|
+
hbs: ["HandlebarsLexer"],
|
|
36
|
+
handlebars: ["HandlebarsLexer"],
|
|
37
|
+
|
|
38
|
+
htm: ["HTMLLexer"],
|
|
39
|
+
html: ["HTMLLexer"],
|
|
40
|
+
|
|
41
|
+
vue: [
|
|
42
|
+
{
|
|
43
|
+
lexer: "JavascriptLexer",
|
|
44
|
+
functions: ["t", "$t"], // Array of functions to match
|
|
45
|
+
namespaceFunctions: ["useTranslation", "withTranslation"],
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
lexer: "HTMLLexer",
|
|
49
|
+
functions: ["t", "$t"],
|
|
50
|
+
vueBindAttr: true,
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
mjs: ["JavascriptLexer"],
|
|
54
|
+
js: ["JavascriptLexer"], // if you're writing jsx inside .js files, change this to JsxLexer
|
|
55
|
+
ts: ["JavascriptLexer"],
|
|
56
|
+
jsx: ["JsxLexer"],
|
|
57
|
+
tsx: ["JsxLexer"],
|
|
58
|
+
|
|
59
|
+
default: ["JavascriptLexer"],
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
lineEnding: "auto",
|
|
63
|
+
// Control the line ending. See options at https://github.com/ryanve/eol
|
|
64
|
+
|
|
65
|
+
locales: ["en", "zh"],
|
|
66
|
+
// An array of the locales in your applications
|
|
67
|
+
|
|
68
|
+
namespaceSeparator: ":",
|
|
69
|
+
// Namespace separator used in your translation keys
|
|
70
|
+
// If you want to use plain english keys, separators such as `.` and `:` will conflict. You might want to set `keySeparator: false` and `namespaceSeparator: false`. That way, `t('Status: Loading...')` will not think that there are a namespace and three separator dots for instance.
|
|
71
|
+
|
|
72
|
+
output: "public/languages/$LOCALE/$NAMESPACE.json",
|
|
73
|
+
// Supports $LOCALE and $NAMESPACE injection
|
|
74
|
+
// Supports JSON (.json) and YAML (.yml) file formats
|
|
75
|
+
// Where to write the locale files relative to process.cwd()
|
|
76
|
+
|
|
77
|
+
pluralSeparator: "_",
|
|
78
|
+
// Plural separator used in your translation keys
|
|
79
|
+
// If you want to use plain english keys, separators such as `_` might conflict. You might want to set `pluralSeparator` to a different string that does not occur in your keys.
|
|
80
|
+
// If you don't want to generate keys for plurals (for example, in case you are using ICU format), set `pluralSeparator: false`.
|
|
81
|
+
|
|
82
|
+
input: "src/**/*.{js,ts,jsx,tsx,vue}",
|
|
83
|
+
// An array of globs that describe where to look for source files
|
|
84
|
+
// relative to the location of the configuration file
|
|
85
|
+
|
|
86
|
+
sort: true,
|
|
87
|
+
// Whether or not to sort the catalog. Can also be a [compareFunction](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#parameters)
|
|
88
|
+
|
|
89
|
+
verbose: true,
|
|
90
|
+
// Display info about the parsing including some stats
|
|
91
|
+
|
|
92
|
+
failOnWarnings: false,
|
|
93
|
+
// Exit with an exit code of 1 on warnings
|
|
94
|
+
|
|
95
|
+
failOnUpdate: false,
|
|
96
|
+
// Exit with an exit code of 1 when translations are updated (for CI purpose)
|
|
97
|
+
|
|
98
|
+
customValueTemplate: null,
|
|
99
|
+
// If you wish to customize the value output the value as an object, you can set your own format.
|
|
100
|
+
//
|
|
101
|
+
// - ${defaultValue} is the default value you set in your translation function.
|
|
102
|
+
// - ${filePaths} will be expanded to an array that contains the absolute
|
|
103
|
+
// file paths where the translations originated in, in case e.g., you need
|
|
104
|
+
// to provide translators with context
|
|
105
|
+
//
|
|
106
|
+
// Any other custom property will be automatically extracted from the 2nd
|
|
107
|
+
// argument of your `t()` function or tOptions in <Trans tOptions={...} />
|
|
108
|
+
//
|
|
109
|
+
// Example:
|
|
110
|
+
// For `t('my-key', {maxLength: 150, defaultValue: 'Hello'})` in
|
|
111
|
+
// /path/to/your/file.js,
|
|
112
|
+
//
|
|
113
|
+
// Using the following customValueTemplate:
|
|
114
|
+
//
|
|
115
|
+
// customValueTemplate: {
|
|
116
|
+
// message: "${defaultValue}",
|
|
117
|
+
// description: "${maxLength}",
|
|
118
|
+
// paths: "${filePaths}",
|
|
119
|
+
// }
|
|
120
|
+
//
|
|
121
|
+
// Will result in the following item being extracted:
|
|
122
|
+
//
|
|
123
|
+
// "my-key": {
|
|
124
|
+
// "message": "Hello",
|
|
125
|
+
// "description": 150,
|
|
126
|
+
// "paths": ["/path/to/your/file.js"]
|
|
127
|
+
// }
|
|
128
|
+
|
|
129
|
+
resetDefaultValueLocale: null,
|
|
130
|
+
// The locale to compare with default values to determine whether a default value has been changed.
|
|
131
|
+
// If this is set and a default value differs from a translation in the specified locale, all entries
|
|
132
|
+
// for that key across locales are reset to the default value, and existing translations are moved to
|
|
133
|
+
// the `_old` file.
|
|
134
|
+
|
|
135
|
+
i18nextOptions: null,
|
|
136
|
+
// If you wish to customize options in internally used i18next instance, you can define an object with any
|
|
137
|
+
// configuration property supported by i18next (https://www.i18next.com/overview/configuration-options).
|
|
138
|
+
// { compatibilityJSON: 'v3' } can be used to generate v3 compatible plurals.
|
|
139
|
+
|
|
140
|
+
yamlOptions: null,
|
|
141
|
+
// If you wish to customize options for yaml output, you can define an object here.
|
|
142
|
+
// Configuration options are here (https://github.com/nodeca/js-yaml#dump-object---options-).
|
|
143
|
+
// Example:
|
|
144
|
+
// {
|
|
145
|
+
// lineWidth: -1,
|
|
146
|
+
// }
|
|
147
|
+
}
|
package/index.html
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" href="/favicon.ico" />
|
|
6
|
+
<link rel="apple-touch-icon" sizes="512x512" href="square-512x512.png" />
|
|
7
|
+
<link rel="apple-touch-icon" sizes="256x256" href="square-256x256.png" />
|
|
8
|
+
<link rel="apple-touch-icon" sizes="128x128" href="square-128x128.png" />
|
|
9
|
+
<meta
|
|
10
|
+
name="viewport"
|
|
11
|
+
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover"
|
|
12
|
+
/>
|
|
13
|
+
<meta name="lzcapp-navigation-bar-scheme" content="hidden" />
|
|
14
|
+
<title>视频播放器</title>
|
|
15
|
+
</head>
|
|
16
|
+
<body>
|
|
17
|
+
<div id="app"></div>
|
|
18
|
+
<script
|
|
19
|
+
type="module"
|
|
20
|
+
src="/src/main.ts"
|
|
21
|
+
crossorigin="use-credentials"
|
|
22
|
+
></script>
|
|
23
|
+
<script>
|
|
24
|
+
const translations = {
|
|
25
|
+
zh: {
|
|
26
|
+
title: "视频播放器",
|
|
27
|
+
},
|
|
28
|
+
en: {
|
|
29
|
+
title: "Video Player",
|
|
30
|
+
},
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function getTranslation(language) {
|
|
34
|
+
switch (true) {
|
|
35
|
+
case language.startsWith("zh"):
|
|
36
|
+
return translations.zh
|
|
37
|
+
case language.startsWith("en"):
|
|
38
|
+
return translations.en
|
|
39
|
+
default:
|
|
40
|
+
return {}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function setTranslation(translation) {
|
|
45
|
+
if (Object.keys(translation).length === 0) {
|
|
46
|
+
return
|
|
47
|
+
}
|
|
48
|
+
document.title = translation.title
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
setTranslation(getTranslation(navigator.language))
|
|
52
|
+
</script>
|
|
53
|
+
</body>
|
|
54
|
+
</html>
|
package/lazycat.png
ADDED
|
Binary file
|
package/lib/README.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# lzc-video-player
|
|
2
|
+
|
|
3
|
+
## 播放器(NativeVideoPlayer)
|
|
4
|
+
|
|
5
|
+
基于原生 `<video>` + hls.js 的播放器,不依赖 Video.js,提供 HLS 播放与基础控制:
|
|
6
|
+
|
|
7
|
+
增加对ass特效字幕的渲染能力,需要配合服务端提供的字体集
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import { LzcVideoPlayer } from "@lazycatcloud/lzc-video-player";
|
|
11
|
+
|
|
12
|
+
// 需配合 openVideo 事件传入片源;onInit 中可拿到 player 并调用 trigger({ type: "openVideo", info })
|
|
13
|
+
<LzcVideoPlayer @back="onBack" :on-init="onInit" :options="options" />
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## 支持选择字幕功能
|
|
17
|
+
|
|
18
|
+
## 调整选择字幕样式
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
<script setup lang="ts">
|
|
22
|
+
import { LzcVideoPlayer } from "@lazycatcloud/lzc-video-player";
|
|
23
|
+
import type { NativePlayerAPI } from "@lazycatcloud/lzc-video-player";
|
|
24
|
+
|
|
25
|
+
function onBack() {
|
|
26
|
+
console.log("onback");
|
|
27
|
+
}
|
|
28
|
+
function onInit(player: NativePlayerAPI) {
|
|
29
|
+
console.log("player: ", player);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const options = {
|
|
33
|
+
showTopBar: false,
|
|
34
|
+
};
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<template>
|
|
38
|
+
<LzcVideoPlayer
|
|
39
|
+
:style="{
|
|
40
|
+
height: '100%',
|
|
41
|
+
width: '100%',
|
|
42
|
+
}"
|
|
43
|
+
@back="onBack"
|
|
44
|
+
:on-init="onInit"
|
|
45
|
+
:options="options"
|
|
46
|
+
/>
|
|
47
|
+
</template>
|
|
48
|
+
```
|
package/lib/package.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lazycatcloud/lzc-video-player",
|
|
3
|
+
"version": "1.2.7",
|
|
4
|
+
"description": "",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/lzc-video-player.js",
|
|
7
|
+
"types": "dist/lzc-video-player.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"README.md"
|
|
11
|
+
],
|
|
12
|
+
"access": "public",
|
|
13
|
+
"author": "",
|
|
14
|
+
"license": "ISC",
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "vite build"
|
|
17
|
+
},
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"registry": "https://registry.npmjs.org",
|
|
20
|
+
"access": "public"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# 整个文件中,可以通过 ${var} 的方式,使用 manifest.yml 文件中定义的值
|
|
2
|
+
|
|
3
|
+
# buildscript
|
|
4
|
+
# - 可以为构建脚本的路径地址
|
|
5
|
+
# - 如果构建命令简单,也可以直接写 sh 的命令
|
|
6
|
+
buildscript: ./build.sh
|
|
7
|
+
|
|
8
|
+
# manifest: 指定 lpk 包的 manifest.yml 文件路径
|
|
9
|
+
manifest: ./lzc-manifest.yml
|
|
10
|
+
|
|
11
|
+
# contentdir: 指定打包的内容,将会打包到 lpk 中
|
|
12
|
+
contentdir: ./build
|
|
13
|
+
|
|
14
|
+
# pkgout: lpk 包的输出路径
|
|
15
|
+
pkgout: ./lpk
|
|
16
|
+
|
|
17
|
+
# icon 指定 lpk 包 icon 的路径路径,如果不指定将会警告
|
|
18
|
+
# icon 仅仅允许 png 后缀的文件
|
|
19
|
+
icon: ./lazycat.png
|
|
20
|
+
|
|
21
|
+
# devshell 自定义应用的开发容器环境
|
|
22
|
+
# - routers 指定应用容器的访问路由
|
|
23
|
+
|
|
24
|
+
# devshell 没有指定 image 的情况,将会默认使用 registry.lazycat.cloud/lzc-cli/devshell:latest
|
|
25
|
+
# devshell:
|
|
26
|
+
# routers:
|
|
27
|
+
# - /=http://127.0.0.1:8080
|
|
28
|
+
|
|
29
|
+
# devshell 指定 image 的情况
|
|
30
|
+
# devshell:
|
|
31
|
+
# routes:
|
|
32
|
+
# - /=http://127.0.0.1:3000
|
|
33
|
+
# image: registry.lazycat.cloud/lzc-cli/devshell:0.0.4
|
|
34
|
+
|
|
35
|
+
# devshell 指定构建Dockerfile
|
|
36
|
+
# image 字段如果没有定义,将默认使用 ${package}-devshell:${version}
|
|
37
|
+
# devshell:
|
|
38
|
+
# routes:
|
|
39
|
+
# - /=http://127.0.0.1:3000
|
|
40
|
+
# image: ${package}-devshell:${version}
|
|
41
|
+
# pull_policy: build
|
|
42
|
+
# build: .
|
|
43
|
+
|
|
44
|
+
# dvshell 指定开发依赖的情况
|
|
45
|
+
# 这种情况下,选用 apline:3.16 作为基础镜像,在 dependencies 中添加所需要的开发依赖即可
|
|
46
|
+
# 如果 dependencies 和 build 同时存在,将会优先使用 dependencies
|
|
47
|
+
devshell:
|
|
48
|
+
routes:
|
|
49
|
+
# - /=http://[fc03:1136:386f:abb0:ee12:ec32:c25a:401]:3000/
|
|
50
|
+
- /=http://${LocalIP}:5173
|
|
51
|
+
image: registry.lazycat.cloud/lzc-cli/devshell:v0.0.5
|
|
52
|
+
dependencies:
|
|
53
|
+
- nodejs
|
|
54
|
+
- vim
|
|
55
|
+
- npm
|
|
56
|
+
# setupscript 每次进入到app container后都会执行的配置脚本
|
|
57
|
+
# - 可以为脚本的路径地址
|
|
58
|
+
# - 如果构建命令简单,也可以直接写 sh 的命令
|
|
59
|
+
# setupscript: export GOPROXY=https://goproxy.cn
|
|
60
|
+
# setupscript: ./setupscript.sh
|
|
61
|
+
setupscript: |
|
|
62
|
+
export GOPROXY=https://goproxy.cn
|
|
63
|
+
export npm_config_registry=https://registry.npmmirror.com
|
|
64
|
+
export PATH=/root/go/bin:$PATH
|
|
65
|
+
# go install github.com/go-delve/delve/cmd/dlv@latest
|