feat(video-card): preview support more video types
Some checks are pending
CI / Test (lts/*, ubuntu-latest) (push) Waiting to run
CI / Test (lts/*, windows-latest) (push) Waiting to run
CI / Test (lts/-1, ubuntu-latest) (push) Waiting to run
CI / Test (lts/-1, windows-latest) (push) Waiting to run

This commit is contained in:
Hakadao
2025-01-07 11:55:13 +08:00
parent e21ecc0ae2
commit ea6c2aa5f3
4 changed files with 218 additions and 6 deletions

View File

@@ -73,9 +73,9 @@ const API_VIDEO = {
},
afterHandle: AHS.J_D,
},
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/video/info.md#%E8%8E%B7%E5%8F%96%E8%A7%86%E9%A2%91%E8%B6%85%E8%AF%A6%E7%BB%86%E4%BF%A1%E6%81%AFweb%E7%AB%AF
// https://socialsisteryi.github.io/bilibili-API-collect/docs/video/info.html#%E8%8E%B7%E5%8F%96%E8%A7%86%E9%A2%91%E8%AF%A6%E7%BB%86%E4%BF%A1%E6%81%AF-web%E7%AB%AF
getVideoInfo: {
url: 'https://api.bilibili.com/x/web-interface/view/detail',
url: 'https://api.bilibili.com/x/web-interface/view',
_fetch: {
method: 'get',
},

View File

@@ -6,6 +6,7 @@ import { useToast } from 'vue-toastification'
import Button from '~/components/Button.vue'
import { useBewlyApp } from '~/composables/useAppProvider'
import { accessKey, settings } from '~/logic'
import type { VideoInfo } from '~/models/video/videoInfo'
import type { VideoPreviewResult } from '~/models/video/videoPreview'
import api from '~/utils/api'
import { getTvSign, TVAppKey } from '~/utils/authProvider'
@@ -75,15 +76,28 @@ const previewVideoUrl = ref<string>('')
const contentVisibility = ref<'auto' | 'visible'>('auto')
const videoElement = ref<HTMLVideoElement | null>(null)
watch(() => isHover.value, (newValue) => {
watch(() => isHover.value, async (newValue) => {
if (!props.video || !newValue)
return
if (props.showPreview && settings.value.enableVideoPreview
&& !previewVideoUrl.value && props.video.cid) {
&& !previewVideoUrl.value && (props.video.aid || props.video.bvid)) {
let cid = props.video.cid
if (!cid) {
try {
const res: VideoInfo = await api.video.getVideoInfo({
bvid: props.video.bvid,
})
if (res.code === 0)
cid = res.data.cid
}
catch {
}
}
api.video.getVideoPreview({
bvid: props.video.bvid,
cid: props.video.cid,
cid,
}).then((res: VideoPreviewResult) => {
if (res.code === 0)
previewVideoUrl.value = res.data.durl[0].url

View File

@@ -27,7 +27,7 @@ export interface Video {
goto?: string
/** After set the `url`, clicking the video will navigate to this url. It won't be affected by aid, bvid or epid */
url?: string
/** If you want to show preview video, you should set the cid value */
/** Better to provide cid, otherwise video preview will need to call another API to get it */
cid?: number
followed?: boolean

View File

@@ -0,0 +1,198 @@
// https://app.quicktype.io/?l=ts
export interface VideoInfo {
code: number
message: string
ttl: number
data: Data
}
export interface Data {
bvid: string
aid: number
videos: number
tid: number
tname: string
copyright: number
pic: string
title: string
pubdate: number
ctime: number
desc: string
desc_v2: DescV2[]
state: number
duration: number
mission_id: number
rights: { [key: string]: number }
owner: Owner
stat: Stat
argue_info: ArgueInfo
dynamic: string
cid: number
dimension: Dimension
premiere: null
teenage_mode: number
is_chargeable_season: boolean
is_story: boolean
is_upower_exclusive: boolean
is_upower_play: boolean
enable_vt: number
vt_display: string
no_cache: boolean
pages: Page[]
subtitle: Subtitle
staff: Staff[]
is_season_display: boolean
user_garb: UserGarb
honor_reply: HonorReply
like_icon: string
need_jump_bv: boolean
disable_show_up_info: boolean
}
export interface ArgueInfo {
argue_msg: string
argue_type: number
argue_link: string
}
export interface DescV2 {
raw_text: string
type: number
biz_id: number
}
export interface Dimension {
width: number
height: number
rotate: number
}
export interface HonorReply {
honor: Honor[]
}
export interface Honor {
aid: number
type: number
desc: string
weekly_recommend_num: number
}
export interface Owner {
mid: number
name: string
face: string
}
export interface Page {
cid: number
page: number
from: string
part: string
duration: number
vid: string
weblink: string
dimension: Dimension
}
export interface Staff {
mid: number
title: string
name: string
face: string
vip: Vip
official: Official
follower: number
label_style: number
}
export interface Official {
role: number
title: string
desc: string
type: number
}
export interface Vip {
type: number
status: number
due_date: number
vip_pay_type: number
theme_type: number
label: Label
avatar_subscript: number
nickname_color: string
role: number
avatar_subscript_url: string
tv_vip_status: number
tv_vip_pay_type: number
tv_due_date: number
}
export interface Label {
path: string
text: string
label_theme: string
text_color: string
bg_style: number
bg_color: string
border_color: string
use_img_label: boolean
img_label_uri_hans: string
img_label_uri_hant: string
img_label_uri_hans_static: string
img_label_uri_hant_static: string
}
export interface Stat {
aid: number
view: number
danmaku: number
reply: number
favorite: number
coin: number
share: number
now_rank: number
his_rank: number
like: number
dislike: number
evaluation: string
vt: number
}
export interface Subtitle {
allow_submit: boolean
list: List[]
}
export interface List {
id: number
lan: string
lan_doc: string
is_lock: boolean
subtitle_url: string
type: number
id_str: string
ai_type: number
ai_status: number
author: Author
}
export interface Author {
mid: number
name: string
sex: string
face: string
sign: string
rank: number
birthday: number
is_fake_account: number
is_deleted: number
in_reg_audit: number
is_senior_member: number
}
export interface UserGarb {
url_image_ani_cut: string
}