采用 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

@@ -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,34 +41,46 @@ 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;
const secTotal = Math.floor(duration / 1000);
@@ -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>