mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-15 09:48:14 +08:00
✨ 采用 Artplayer #64
This commit is contained in:
@@ -68,6 +68,7 @@
|
||||
"dependencies": {
|
||||
"@mdi/font": "7.3.67",
|
||||
"@tauri-apps/api": "^1.5.1",
|
||||
"artplayer": "^5.0.9",
|
||||
"clipboard": "^2.0.11",
|
||||
"color-convert": "^2.0.1",
|
||||
"echarts": "^5.4.3",
|
||||
|
||||
29
pnpm-lock.yaml
generated
29
pnpm-lock.yaml
generated
@@ -11,6 +11,9 @@ dependencies:
|
||||
'@tauri-apps/api':
|
||||
specifier: ^1.5.1
|
||||
version: 1.5.1
|
||||
artplayer:
|
||||
specifier: ^5.0.9
|
||||
version: 5.0.9
|
||||
clipboard:
|
||||
specifier: ^2.0.11
|
||||
version: 2.0.11
|
||||
@@ -1241,6 +1244,12 @@ packages:
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/artplayer@5.0.9:
|
||||
resolution: {integrity: sha512-IM/DShYdmKFEA9jl08LYbTK2Jfz9s7qIjEH0xWjnxvVArUKZZKcoqwr6i54U0c4grtc/Uvb4wtCd78kvtSVlgw==}
|
||||
dependencies:
|
||||
option-validator: 2.0.6
|
||||
dev: false
|
||||
|
||||
/astral-regex@2.0.0:
|
||||
resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -3282,7 +3291,6 @@ packages:
|
||||
/kind-of@6.0.3:
|
||||
resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/known-css-properties@0.29.0:
|
||||
resolution: {integrity: sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==}
|
||||
@@ -3707,6 +3715,12 @@ packages:
|
||||
is-wsl: 2.2.0
|
||||
dev: true
|
||||
|
||||
/option-validator@2.0.6:
|
||||
resolution: {integrity: sha512-tmZDan2LRIRQyhUGvkff68/O0R8UmF+Btmiiz0SmSw2ng3CfPZB9wJlIjHpe/MKUZqyIZkVIXCrwr1tIN+0Dzg==}
|
||||
dependencies:
|
||||
kind-of: 6.0.3
|
||||
dev: false
|
||||
|
||||
/optionator@0.9.3:
|
||||
resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
@@ -3871,8 +3885,8 @@ packages:
|
||||
dependencies:
|
||||
htmlparser2: 8.0.2
|
||||
js-tokens: 8.0.2
|
||||
postcss: 8.4.31
|
||||
postcss-safe-parser: 6.0.0(postcss@8.4.31)
|
||||
postcss: 8.4.32
|
||||
postcss-safe-parser: 6.0.0(postcss@8.4.32)
|
||||
dev: true
|
||||
|
||||
/postcss-resolve-nested-selector@0.1.1:
|
||||
@@ -3888,6 +3902,15 @@ packages:
|
||||
postcss: 8.4.31
|
||||
dev: true
|
||||
|
||||
/postcss-safe-parser@6.0.0(postcss@8.4.32):
|
||||
resolution: {integrity: sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==}
|
||||
engines: {node: '>=12.0'}
|
||||
peerDependencies:
|
||||
postcss: ^8.3.3
|
||||
dependencies:
|
||||
postcss: 8.4.32
|
||||
dev: true
|
||||
|
||||
/postcss-selector-parser@6.0.13:
|
||||
resolution: {integrity: sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
<template>
|
||||
<!-- todo 可以根据视频大小调整尺存 -->
|
||||
<div class="mys-post-div">
|
||||
<video class="mys-post-vod" :poster="getVodCover()" controls>
|
||||
<!-- 这边 type 暂时写死 todo -->
|
||||
<source :src="getVodSrc()" :type="getVodType()" />
|
||||
</video>
|
||||
<div class="mys-post-vod-cover-div">
|
||||
<img class="mys-post-vod-cover" alt="cover" :src="getVodCover()" />
|
||||
<img class="mys-post-vod-icon" src="/source/UI/video_play.svg" alt="icon" />
|
||||
<div class="mys-post-vod-time">{{ getVodTime() }}</div>
|
||||
<div class="tp-vod-box">
|
||||
<div class="tp-vod-container" data-html2canvas-ignore />
|
||||
<div class="tp-vod-cover">
|
||||
<img alt="cover" :src="props.data.insert.vod.cover" />
|
||||
<img src="/source/UI/video_play.svg" alt="icon" />
|
||||
<span>{{ getVodTime() }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { computed } from "vue";
|
||||
import Artplayer from "artplayer";
|
||||
import type { Option } from "artplayer/types/option";
|
||||
import { onMounted, ref, toRaw } from "vue";
|
||||
|
||||
interface TpVod {
|
||||
insert: {
|
||||
@@ -23,13 +21,13 @@ interface TpVod {
|
||||
cover: string;
|
||||
resolutions: Array<{
|
||||
url: string;
|
||||
definition: string;
|
||||
definition: "480P" | "720P" | "1080P" | "2K"; // 待补充
|
||||
height: number;
|
||||
width: number;
|
||||
bitrate: number;
|
||||
size: number;
|
||||
format: string;
|
||||
label: string;
|
||||
format: "MP4"; // 待补充
|
||||
label: "480P" | "720P" | "1080P" | "2K"; // 待补充
|
||||
}>;
|
||||
view_num: number;
|
||||
transcode_status: number;
|
||||
@@ -43,33 +41,45 @@ interface TpVodProps {
|
||||
}
|
||||
|
||||
const props = defineProps<TpVodProps>();
|
||||
const highestResolution = computed(() => {
|
||||
let res = undefined;
|
||||
for (const resolution of props.data.insert.vod.resolutions) {
|
||||
if (res === undefined) {
|
||||
res = resolution;
|
||||
} else if (resolution.size > res.size) {
|
||||
res = resolution;
|
||||
const container = ref<Artplayer | null>(null);
|
||||
|
||||
console.log("tpVod", props.data.insert.vod.id, toRaw(props.data).insert.vod);
|
||||
|
||||
onMounted(async () => {
|
||||
const option: Option = {
|
||||
container: ".tp-vod-container",
|
||||
url: "",
|
||||
poster: props.data.insert.vod.cover,
|
||||
type: "",
|
||||
autoSize: true,
|
||||
playbackRate: true,
|
||||
aspectRatio: true,
|
||||
setting: true,
|
||||
hotkey: true,
|
||||
pip: true,
|
||||
quality: [],
|
||||
icons: {
|
||||
// eslint-disable-next-line @typescript-eslint/quotes
|
||||
state: `<img src="/source/UI/video_play.svg" alt="icon" />`,
|
||||
},
|
||||
lang: "zh-cn",
|
||||
airplay: true,
|
||||
};
|
||||
const resolutions = props.data.insert.vod.resolutions;
|
||||
resolutions.forEach((resolution) => {
|
||||
if (option.url === "") {
|
||||
option.url = resolution.url;
|
||||
option.type = resolution.format;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
const quality = {
|
||||
default: false,
|
||||
html: resolution.label,
|
||||
url: resolution.url,
|
||||
};
|
||||
option.quality?.push(quality);
|
||||
});
|
||||
container.value = new Artplayer(option);
|
||||
});
|
||||
|
||||
function getVodSrc(): string {
|
||||
return highestResolution.value.url;
|
||||
}
|
||||
|
||||
function getVodCover(): string {
|
||||
return props.data.insert.vod.cover;
|
||||
}
|
||||
|
||||
function getVodType(): string {
|
||||
if (highestResolution.value.format === "MP4") {
|
||||
return "video/mp4";
|
||||
}
|
||||
// todo 还没有遇到过其他格式的视频
|
||||
return "video/webm";
|
||||
}
|
||||
|
||||
function getVodTime(): string {
|
||||
const duration = props.data.insert.vod.duration;
|
||||
@@ -86,3 +96,52 @@ function getVodTime(): string {
|
||||
return result;
|
||||
}
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tp-vod-box {
|
||||
position: relative;
|
||||
margin: 10px auto;
|
||||
}
|
||||
|
||||
.tp-vod-container {
|
||||
overflow: hidden;
|
||||
max-width: 100%;
|
||||
border-radius: 10px;
|
||||
aspect-ratio: 16 / 9;
|
||||
}
|
||||
|
||||
.tp-vod-cover {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.tp-vod-cover :nth-child(1) {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.tp-vod-cover :nth-child(2) {
|
||||
position: absolute;
|
||||
top: calc(50% - 40px);
|
||||
left: calc(50% - 40px);
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.tp-vod-cover :nth-child(3) {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
bottom: 10px;
|
||||
padding: 0 5px;
|
||||
border-radius: 5px;
|
||||
background: rgb(0 0 0/50%);
|
||||
color: var(--tgc-white-4);
|
||||
font-family: var(--font-title);
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user