采用 Artplayer #64

This commit is contained in:
BTMuli
2023-12-06 18:02:09 +08:00
parent d9fa158076
commit d271444610
3 changed files with 125 additions and 42 deletions

View File

@@ -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
View File

@@ -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'}

View File

@@ -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>