Skip to content

Commit

Permalink
feat: support enhance ass subtitles on aliyundrive video previewer (#124
Browse files Browse the repository at this point in the history
)

* feat(video): support enhance ass subtitles on aliyundrive video previewer

* Fix: set quality manually when resetPlayUrl called
  • Loading branch information
topjohncian authored Dec 31, 2023
1 parent 06216a7 commit ca02608
Showing 1 changed file with 121 additions and 14 deletions.
135 changes: 121 additions & 14 deletions src/pages/home/previews/aliyun_video.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@ import { getSettingBool, objStore, password } from "~/store"
import { ObjType, PResp } from "~/types"
import { ext, handleResp, notify, r } from "~/utils"
import Artplayer from "artplayer"
import { type Option } from "artplayer/types/option"
import { type Setting } from "artplayer/types/setting"
import { type Events } from "artplayer/types/events"
import artplayerPluginDanmuku from "artplayer-plugin-danmuku"
import artplayerPluginAss from "~/components/artplayer-plugin-ass"
import Hls from "hls.js"
import { currentLang } from "~/app/i18n"
import { VideoBox } from "./video_box"
import { ArtPlayerIconsSubtitle } from "~/components/icons"

export interface Data {
drive_id: string
Expand Down Expand Up @@ -46,7 +51,7 @@ const Preview = () => {
videos = [objStore.obj]
}
let player: Artplayer
let option: any = {
let option: Option = {
id: pathname(),
container: "#video-player",
title: objStore.obj.name,
Expand All @@ -70,6 +75,7 @@ const Preview = () => {
quality: [],
plugins: [],
whitelist: [],
settings: [],
moreVideoAttr: {
// @ts-ignore
"webkit-playsinline": true,
Expand All @@ -96,7 +102,7 @@ const Preview = () => {
airplay: true,
}

const subtitle = objStore.related.find((obj) => {
const subtitle = objStore.related.filter((obj) => {
for (const ext of [".srt", ".ass", ".vtt"]) {
if (obj.name.endsWith(ext)) {
return true
Expand All @@ -112,14 +118,120 @@ const Preview = () => {
}
return false
})
if (subtitle) {
option.subtitle = {
url: proxyLink(subtitle, true),
type: ext(subtitle.name) as any,

// TODO: add a switch in manage panel to choose whether to enable `libass-wasm`
const enableEnhanceAss = true

if (subtitle.length != 0) {
let isEnhanceAssMode = false

// set default subtitle
const defaultSubtitle = subtitle[0]
if (enableEnhanceAss && ext(defaultSubtitle.name).toLowerCase() === "ass") {
isEnhanceAssMode = true
option.plugins?.push(
artplayerPluginAss({
// debug: true,
subUrl: proxyLink(defaultSubtitle, true),
}),
)
} else {
option.subtitle = {
url: proxyLink(defaultSubtitle, true),
type: ext(defaultSubtitle.name),
}
}

// render subtitle toggle menu
const innerMenu: Setting[] = [
{
id: "setting_subtitle_display",
html: "Display",
tooltip: "Show",
switch: true,
onSwitch: function (item: Setting) {
item.tooltip = item.switch ? "Hide" : "Show"
setSubtitleVisible(!item.switch)

// sync menu subtitle tooltip
const menu_sub = option.settings?.find(
(_) => _.id === "setting_subtitle",
)
menu_sub && (menu_sub.tooltip = item.tooltip)

return !item.switch
},
},
]
subtitle.forEach((item, i) => {
innerMenu.push({
default: i === 0,
html: (
<span
title={item.name}
style={{
display: "inline-block",
"max-width": "15em",
"text-overflow": "ellipsis",
overflow: "hidden",
}}
>
{item.name}
</span>
) as HTMLElement,
name: item.name,
url: proxyLink(item, true),
})
})

option.settings?.push({
id: "setting_subtitle",
html: "Subtitle",
tooltip: "Show",
icon: ArtPlayerIconsSubtitle({ size: 24 }) as HTMLElement,
selector: innerMenu,
onSelect: function (item: Setting) {
if (enableEnhanceAss && ext(item.name).toLowerCase() === "ass") {
isEnhanceAssMode = true
this.emit("artplayer-plugin-ass:switch" as keyof Events, item.url)
setSubtitleVisible(true)
} else {
isEnhanceAssMode = false
this.subtitle.switch(item.url, { name: item.name })
this.once("subtitleLoad", setSubtitleVisible.bind(this, true))
}

const switcher = innerMenu.find(
(_) => _.id === "setting_subtitle_display",
)

if (switcher && !switcher.switch) switcher.$html?.click?.()

// sync from display switcher
return switcher?.tooltip
},
})

function setSubtitleVisible(visible: boolean) {
const type = isEnhanceAssMode ? "ass" : "webvtt"

switch (type) {
case "ass":
player.subtitle.show = false
player.emit("artplayer-plugin-ass:visible" as keyof Events, visible)
break

case "webvtt":
default:
player.subtitle.show = visible
player.emit("artplayer-plugin-ass:visible" as keyof Events, false)
break
}
}
}

if (danmu) {
option.plugins = [
option.plugins?.push(
artplayerPluginDanmuku({
danmuku: proxyLink(danmu, true),
speed: 5,
Expand All @@ -137,7 +249,7 @@ const Preview = () => {
maxWidth: 400,
theme: "dark",
}),
]
)
}
const [loading, post] = useFetch(
(): PResp<Data> =>
Expand Down Expand Up @@ -174,12 +286,6 @@ const Preview = () => {
replace(videos[index + 1].name)
}
})
// Fixed subtitle loss when switching videos with different resolutions
if (subtitle) {
player.on("video:play", (_url) => {
player.subtitle.url = proxyLink(subtitle, true)
})
}
interval = window.setInterval(resetPlayUrl, 1000 * 60 * 14)
})
})
Expand All @@ -203,6 +309,7 @@ const Preview = () => {
default: i === list.length - 1,
}
})
option.quality = quality
player.quality = quality
curSeek = player.currentTime
await player.switchUrl(quality[quality.length - 1].url)
Expand Down

0 comments on commit ca02608

Please sign in to comment.