mirror of
https://github.com/the1812/Bilibili-Evolved.git
synced 2025-11-04 21:22:45 +08:00
Merge tag 'v2.8.12-preview' into preview-fixes
This commit is contained in:
commit
c740f16208
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -62,6 +62,7 @@
|
|||||||
"linebreak",
|
"linebreak",
|
||||||
"Liveroom",
|
"Liveroom",
|
||||||
"materialdesignicons",
|
"materialdesignicons",
|
||||||
|
"matroska",
|
||||||
"medialist",
|
"medialist",
|
||||||
"mimetype",
|
"mimetype",
|
||||||
"minmax",
|
"minmax",
|
||||||
@ -133,6 +134,6 @@
|
|||||||
"*.tsx": "${capture}.ts",
|
"*.tsx": "${capture}.ts",
|
||||||
"tsconfig.json": "tsconfig.*.json",
|
"tsconfig.json": "tsconfig.*.json",
|
||||||
"package.json": "package-lock.json, yarn.lock, pnpm-lock.yaml, .*",
|
"package.json": "package-lock.json, yarn.lock, pnpm-lock.yaml, .*",
|
||||||
"index.ts": "index.*.ts, index.md, index.*.md",
|
"index.ts": "index.*.ts, index.md, index.*.md"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,7 +27,7 @@
|
|||||||
"type": "component",
|
"type": "component",
|
||||||
"name": "feedsFilter",
|
"name": "feedsFilter",
|
||||||
"displayName": "动态过滤器",
|
"displayName": "动态过滤器",
|
||||||
"description": "按照类型或者关键词过滤动态首页的内容, 也可以移除动态页的一些侧边卡片. 详细设置请前往[动态首页](https://t.bilibili.com/)查看.\r\n",
|
"description": "按照类型或者关键词过滤动态首页的内容, 也可以移除动态页的一些侧边卡片. 详细设置请前往[动态首页](https://t.bilibili.com/)查看.\r\n\r\n> 侧边卡片的 `正在直播` 指原版的板块, 如果你使用了 `直播信息扩充`, 则需要关闭该功能才能生效.\r\n",
|
||||||
"fullRelativePath": "../../registry/dist/components/feeds/filter.js",
|
"fullRelativePath": "../../registry/dist/components/feeds/filter.js",
|
||||||
"fullAbsolutePath": "registry/dist/components/feeds/filter.js"
|
"fullAbsolutePath": "registry/dist/components/feeds/filter.js"
|
||||||
},
|
},
|
||||||
@ -1116,7 +1116,7 @@
|
|||||||
"type": "plugin",
|
"type": "plugin",
|
||||||
"name": "downloadVideo.outputs.wasm",
|
"name": "downloadVideo.outputs.wasm",
|
||||||
"displayName": "下载视频 - WASM 混流输出",
|
"displayName": "下载视频 - WASM 混流输出",
|
||||||
"description": "by [@WakelessSloth56](https://github.com/WakelessSloth56)\n\n使用 WASM 在浏览器中下载并合并音视频",
|
"description": "by [@WakelessSloth56](https://github.com/WakelessSloth56)\n\n使用 WASM 在浏览器中下载并合并音视频, 支持批量下载",
|
||||||
"fullRelativePath": "../../registry/dist/plugins/video/download/wasm-output.js",
|
"fullRelativePath": "../../registry/dist/plugins/video/download/wasm-output.js",
|
||||||
"fullAbsolutePath": "registry/dist/plugins/video/download/wasm-output.js"
|
"fullAbsolutePath": "registry/dist/plugins/video/download/wasm-output.js"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -38,6 +38,8 @@
|
|||||||
|
|
||||||
按照类型或者关键词过滤动态首页的内容, 也可以移除动态页的一些侧边卡片. 详细设置请前往[动态首页](https://t.bilibili.com/)查看.
|
按照类型或者关键词过滤动态首页的内容, 也可以移除动态页的一些侧边卡片. 详细设置请前往[动态首页](https://t.bilibili.com/)查看.
|
||||||
|
|
||||||
|
> 侧边卡片的 `正在直播` 指原版的板块, 如果你使用了 `直播信息扩充`, 则需要关闭该功能才能生效.
|
||||||
|
|
||||||
### [强制固定动态侧栏](../../registry/dist/components/feeds/fixed-sidebars.js)
|
### [强制固定动态侧栏](../../registry/dist/components/feeds/fixed-sidebars.js)
|
||||||
`fixedFeedsSidebars`
|
`fixedFeedsSidebars`
|
||||||
|
|
||||||
@ -1493,7 +1495,7 @@ by [@diannaojiang](https://github.com/diannaojiang)
|
|||||||
|
|
||||||
by [@WakelessSloth56](https://github.com/WakelessSloth56)
|
by [@WakelessSloth56](https://github.com/WakelessSloth56)
|
||||||
|
|
||||||
使用 WASM 在浏览器中下载并合并音视频
|
使用 WASM 在浏览器中下载并合并音视频, 支持批量下载
|
||||||
|
|
||||||
### [快捷键扩展 - 视频倍速](../../registry/dist/plugins/video/player/speed.js)
|
### [快捷键扩展 - 视频倍速](../../registry/dist/plugins/video/player/speed.js)
|
||||||
`speed.keymap`
|
`speed.keymap`
|
||||||
|
|||||||
@ -99,6 +99,9 @@ const sideCards: { [id: number]: SideCardType } = {
|
|||||||
displayName: '发布动态',
|
displayName: '发布动态',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
if (getComponentSettings('extendFeedsLive').enabled) {
|
||||||
|
delete sideCards[3]
|
||||||
|
}
|
||||||
let cardsManager: typeof import('@/components/feeds/api').feedsCardsManager
|
let cardsManager: typeof import('@/components/feeds/api').feedsCardsManager
|
||||||
const sideBlock = 'feeds-filter-side-block-'
|
const sideBlock = 'feeds-filter-side-block-'
|
||||||
|
|
||||||
|
|||||||
@ -1 +1,3 @@
|
|||||||
按照类型或者关键词过滤动态首页的内容, 也可以移除动态页的一些侧边卡片. 详细设置请前往[动态首页](https://t.bilibili.com/)查看.
|
按照类型或者关键词过滤动态首页的内容, 也可以移除动态页的一些侧边卡片. 详细设置请前往[动态首页](https://t.bilibili.com/)查看.
|
||||||
|
|
||||||
|
> 侧边卡片的 `正在直播` 指原版的板块, 如果你使用了 `直播信息扩充`, 则需要关闭该功能才能生效.
|
||||||
|
|||||||
@ -6,27 +6,38 @@ const darkMetaColor = '#111'
|
|||||||
const add = async () => {
|
const add = async () => {
|
||||||
document.body.classList.add('dark')
|
document.body.classList.add('dark')
|
||||||
localStorage.setItem('pbp_theme_v4', 'b')
|
localStorage.setItem('pbp_theme_v4', 'b')
|
||||||
const meta = dq('meta[name="theme-color"]') as HTMLMetaElement
|
|
||||||
if (!meta) {
|
const themeColorMeta = dq('meta[name="theme-color"]') as HTMLMetaElement
|
||||||
|
if (!themeColorMeta) {
|
||||||
document.head.insertAdjacentHTML(
|
document.head.insertAdjacentHTML(
|
||||||
'beforeend',
|
'beforeend',
|
||||||
`<meta name="theme-color" content="${darkMetaColor}">`,
|
`<meta name="theme-color" content="${darkMetaColor}">`,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
meta.dataset.light = meta.content
|
themeColorMeta.dataset.light = themeColorMeta.content
|
||||||
meta.content = darkMetaColor
|
themeColorMeta.content = darkMetaColor
|
||||||
|
}
|
||||||
|
|
||||||
|
const colorSchemeMeta = dq('meta[name="color-scheme"]') as HTMLMetaElement
|
||||||
|
if (!colorSchemeMeta) {
|
||||||
|
document.head.insertAdjacentHTML('beforeend', `<meta name="color-scheme" content="dark">`)
|
||||||
|
} else {
|
||||||
|
colorSchemeMeta.content = 'dark'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const remove = async () => {
|
const remove = async () => {
|
||||||
document.body.classList.remove('dark')
|
document.body.classList.remove('dark')
|
||||||
const meta = dq('meta[name="theme-color"]') as HTMLMetaElement
|
|
||||||
if (!meta) {
|
const themeColorMeta = dq('meta[name="theme-color"]') as HTMLMetaElement
|
||||||
return
|
if (themeColorMeta?.dataset.light) {
|
||||||
}
|
themeColorMeta.content = themeColorMeta.dataset.light
|
||||||
if (meta.dataset.light) {
|
|
||||||
meta.content = meta.dataset.light
|
|
||||||
} else {
|
} else {
|
||||||
meta.remove()
|
themeColorMeta?.remove()
|
||||||
|
}
|
||||||
|
|
||||||
|
const colorSchemeMeta = dq('meta[name="color-scheme"]') as HTMLMetaElement
|
||||||
|
if (colorSchemeMeta) {
|
||||||
|
colorSchemeMeta.content = 'light'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,8 @@ const getIpLocation = (item: CommentReplyItem) => {
|
|||||||
let version = 2
|
let version = 2
|
||||||
let bbComment: any
|
let bbComment: any
|
||||||
|
|
||||||
|
const marginLeft = 15
|
||||||
|
|
||||||
// 带IP属地显示的评论创建
|
// 带IP属地显示的评论创建
|
||||||
const createListCon = function listCon(item, i, pos) {
|
const createListCon = function listCon(item, i, pos) {
|
||||||
const blCon = this._parentBlacklistDom(item, i, pos)
|
const blCon = this._parentBlacklistDom(item, i, pos)
|
||||||
@ -28,7 +30,9 @@ const createListCon = function listCon(item, i, pos) {
|
|||||||
'<span class="time-location">',
|
'<span class="time-location">',
|
||||||
'<span class="reply-time">'.concat(this._formateTime(item.ctime), '</span>'),
|
'<span class="reply-time">'.concat(this._formateTime(item.ctime), '</span>'),
|
||||||
item?.reply_control?.location
|
item?.reply_control?.location
|
||||||
? `<span class="reply-location">${item?.reply_control?.location || ''}</span>`
|
? `<span class="reply-location" style="margin-left:${marginLeft}px;">${
|
||||||
|
item?.reply_control?.location || ''
|
||||||
|
}</span>`
|
||||||
: '',
|
: '',
|
||||||
'</span>',
|
'</span>',
|
||||||
item.lottery_id
|
item.lottery_id
|
||||||
@ -89,7 +93,9 @@ const createSubReplyItem = function subReply(item, i) {
|
|||||||
'<span class="time-location">',
|
'<span class="time-location">',
|
||||||
'<span class="reply-time">'.concat(this._formateTime(item.ctime), '</span>'),
|
'<span class="reply-time">'.concat(this._formateTime(item.ctime), '</span>'),
|
||||||
item?.reply_control?.location
|
item?.reply_control?.location
|
||||||
? `<span class="reply-location">${item?.reply_control?.location || ''}</span>`
|
? `<span class="reply-location" style="margin-left:${marginLeft}px;">${
|
||||||
|
item?.reply_control?.location || ''
|
||||||
|
}</span>`
|
||||||
: '',
|
: '',
|
||||||
'</span>',
|
'</span>',
|
||||||
`<span class="like ${item.action === 1 ? 'liked' : ''}"><i></i><span>${
|
`<span class="like ${item.action === 1 ? 'liked' : ''}"><i></i><span>${
|
||||||
@ -134,7 +140,7 @@ const blackroomCreateListCon = function listCon(e, n, t) {
|
|||||||
this._createPlatformDom(e.content.plat),
|
this._createPlatformDom(e.content.plat),
|
||||||
`<span class="time">${this._formateTime(e.ctime)}</span>`,
|
`<span class="time">${this._formateTime(e.ctime)}</span>`,
|
||||||
e?.reply_control?.location
|
e?.reply_control?.location
|
||||||
? `<span style="margin-left:-15px;">${e?.reply_control?.location || ''}</span>`
|
? `<span style="margin-left:${marginLeft - 15}px;">${e?.reply_control?.location || ''}</span>`
|
||||||
: '',
|
: '',
|
||||||
e.lottery_id
|
e.lottery_id
|
||||||
? ''
|
? ''
|
||||||
@ -196,7 +202,7 @@ const blackroomCreateSubReplyItem = function subReply(e, n) {
|
|||||||
'<div class="info">',
|
'<div class="info">',
|
||||||
`<span class="time">${this._formateTime(e.ctime)}</span>`,
|
`<span class="time">${this._formateTime(e.ctime)}</span>`,
|
||||||
e?.reply_control?.location
|
e?.reply_control?.location
|
||||||
? `<span style="margin-left:-15px;">${e?.reply_control?.location || ''}</span>`
|
? `<span style="margin-left:${marginLeft - 15}px;">${e?.reply_control?.location || ''}</span>`
|
||||||
: '',
|
: '',
|
||||||
`<span class="like ${1 === e.action ? 'liked' : ''}"><i></i><span>${
|
`<span class="like ${1 === e.action ? 'liked' : ''}"><i></i><span>${
|
||||||
e.like || ''
|
e.like || ''
|
||||||
@ -275,7 +281,7 @@ const processItems = (items: CommentReplyItem[]) => {
|
|||||||
if (replyTime.childElementCount === 0) {
|
if (replyTime.childElementCount === 0) {
|
||||||
// 避免在评论更新的情况下重复添加
|
// 避免在评论更新的情况下重复添加
|
||||||
const replyLocation = document.createElement('span')
|
const replyLocation = document.createElement('span')
|
||||||
replyLocation.style.marginLeft = '5px'
|
replyLocation.style.marginLeft = `${marginLeft}px`
|
||||||
replyLocation.innerText = location
|
replyLocation.innerText = location
|
||||||
replyTime.appendChild(replyLocation)
|
replyTime.appendChild(replyLocation)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ export const storeNames = {
|
|||||||
} as const
|
} as const
|
||||||
|
|
||||||
async function database() {
|
async function database() {
|
||||||
return new Promise((reslove: (db: IDBDatabase) => void, reject) => {
|
return new Promise((resolve: (db: IDBDatabase) => void, reject) => {
|
||||||
const req = unsafeWindow.indexedDB.open(DB_NAME, DB_VERSION)
|
const req = unsafeWindow.indexedDB.open(DB_NAME, DB_VERSION)
|
||||||
req.onerror = reject
|
req.onerror = reject
|
||||||
req.onupgradeneeded = () => {
|
req.onupgradeneeded = () => {
|
||||||
@ -18,34 +18,34 @@ async function database() {
|
|||||||
db.createObjectStore(v)
|
db.createObjectStore(v)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
req.onsuccess = () => reslove(req.result)
|
req.onsuccess = () => resolve(req.result)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function objectStore(name: string, mode?: IDBTransactionMode) {
|
async function objectStore(name: string, mode?: IDBTransactionMode) {
|
||||||
return database().then(
|
return database().then(
|
||||||
db =>
|
db =>
|
||||||
new Promise((reslove: (db: IDBObjectStore) => void, reject) => {
|
new Promise((resolve: (db: IDBObjectStore) => void, reject) => {
|
||||||
const tr = db.transaction(name, mode)
|
const tr = db.transaction(name, mode)
|
||||||
reslove(tr.objectStore(name))
|
resolve(tr.objectStore(name))
|
||||||
tr.onerror = reject
|
tr.onerror = reject
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function get(store: IDBObjectStore, key: IDBValidKey | IDBKeyRange) {
|
async function get(store: IDBObjectStore, key: IDBValidKey | IDBKeyRange) {
|
||||||
return new Promise((reslove: (db: any) => void, reject) => {
|
return new Promise((resolve: (db: any) => void, reject) => {
|
||||||
const res = store.get(key)
|
const res = store.get(key)
|
||||||
res.onerror = reject
|
res.onerror = reject
|
||||||
res.onsuccess = () => reslove(res.result)
|
res.onsuccess = () => resolve(res.result)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function put(store: IDBObjectStore, value: any, key?: IDBValidKey) {
|
async function put(store: IDBObjectStore, value: any, key?: IDBValidKey) {
|
||||||
return new Promise((reslove: (db: IDBValidKey) => void, reject) => {
|
return new Promise((resolve: (db: IDBValidKey) => void, reject) => {
|
||||||
const res = store.put(value, key)
|
const res = store.put(value, key)
|
||||||
res.onerror = reject
|
res.onerror = reject
|
||||||
res.onsuccess = () => reslove(res.result)
|
res.onsuccess = () => resolve(res.result)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,17 @@
|
|||||||
import { DownloadPackage } from '@/core/download'
|
import { DownloadPackage } from '@/core/download'
|
||||||
import { meta } from '@/core/meta'
|
import { meta } from '@/core/meta'
|
||||||
|
import { getComponentSettings } from '@/core/settings'
|
||||||
import { Toast } from '@/core/toast'
|
import { Toast } from '@/core/toast'
|
||||||
|
import { title as pluginTitle } from '.'
|
||||||
|
import type { Options } from '../../../../components/video/download'
|
||||||
|
import { DownloadVideoAction } from '../../../../components/video/download/types'
|
||||||
import { FFmpeg } from './ffmpeg'
|
import { FFmpeg } from './ffmpeg'
|
||||||
import { getCacheOrGet, httpGet, toastProgress, toBlobUrl } from './utils'
|
import { getCacheOrGet, httpGet, toastProgress, toBlobUrl } from './utils'
|
||||||
|
|
||||||
const ffmpeg = new FFmpeg()
|
const ffmpeg = new FFmpeg()
|
||||||
|
|
||||||
async function load(toast: Toast) {
|
async function loadFFmpeg() {
|
||||||
|
const toast = Toast.info('正在加载 FFmpeg', `${pluginTitle} - 初始化`)
|
||||||
await ffmpeg.load({
|
await ffmpeg.load({
|
||||||
workerLoadURL: toBlobUrl(
|
workerLoadURL: toBlobUrl(
|
||||||
await getCacheOrGet(
|
await getCacheOrGet(
|
||||||
@ -33,24 +38,26 @@ async function load(toast: Toast) {
|
|||||||
'application/wasm',
|
'application/wasm',
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
|
toast.message = '完成!'
|
||||||
|
toast.close()
|
||||||
}
|
}
|
||||||
export async function run(
|
|
||||||
|
async function single(
|
||||||
name: string,
|
name: string,
|
||||||
toast: Toast,
|
|
||||||
videoUrl: string,
|
videoUrl: string,
|
||||||
audioUrl: string,
|
audioUrl: string,
|
||||||
isFlac: boolean,
|
isFlac: boolean,
|
||||||
|
pageIndex = 1,
|
||||||
|
totalPages = 1,
|
||||||
) {
|
) {
|
||||||
if (!ffmpeg.loaded) {
|
const toast = Toast.info('', `${pluginTitle} - ${pageIndex} / ${totalPages}`)
|
||||||
await load(toast)
|
|
||||||
}
|
|
||||||
|
|
||||||
ffmpeg.writeFile('video', await httpGet(videoUrl, toastProgress(toast, '正在下载视频流')))
|
ffmpeg.writeFile('video', await httpGet(videoUrl, toastProgress(toast, '正在下载视频流')))
|
||||||
ffmpeg.writeFile('audio', await httpGet(audioUrl, toastProgress(toast, '正在下载音频流')))
|
ffmpeg.writeFile('audio', await httpGet(audioUrl, toastProgress(toast, '正在下载音频流')))
|
||||||
toast.message = '混流中……'
|
|
||||||
|
|
||||||
|
toast.message = '混流中……'
|
||||||
const outputExt = isFlac ? 'mkv' : 'mp4'
|
const outputExt = isFlac ? 'mkv' : 'mp4'
|
||||||
name = isFlac ? name.replace(/.[^/.]+$/, `.${outputExt}`) : name
|
name = name.replace(/.[^/.]+$/, `.${outputExt}`)
|
||||||
await ffmpeg.exec([
|
await ffmpeg.exec([
|
||||||
'-i',
|
'-i',
|
||||||
'video',
|
'video',
|
||||||
@ -59,7 +66,7 @@ export async function run(
|
|||||||
'-c:v',
|
'-c:v',
|
||||||
'copy',
|
'copy',
|
||||||
'-c:a',
|
'-c:a',
|
||||||
isFlac ? 'flac' : 'copy',
|
'copy',
|
||||||
'-f',
|
'-f',
|
||||||
isFlac ? 'matroska' : 'mp4',
|
isFlac ? 'matroska' : 'mp4',
|
||||||
`output.${outputExt}`,
|
`output.${outputExt}`,
|
||||||
@ -71,7 +78,40 @@ export async function run(
|
|||||||
})
|
})
|
||||||
|
|
||||||
toast.message = '完成!'
|
toast.message = '完成!'
|
||||||
toast.duration = 1500
|
toast.duration = 1000
|
||||||
|
|
||||||
await DownloadPackage.single(name, outputBlob)
|
await DownloadPackage.single(name, outputBlob)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function run(action: DownloadVideoAction) {
|
||||||
|
if (!ffmpeg.loaded) {
|
||||||
|
await loadFFmpeg()
|
||||||
|
}
|
||||||
|
|
||||||
|
const { dashAudioExtension, dashFlacAudioExtension, dashVideoExtension } =
|
||||||
|
getComponentSettings<Options>('downloadVideo').options
|
||||||
|
|
||||||
|
const pages = action.infos
|
||||||
|
for (let i = 0; i < pages.length; i++) {
|
||||||
|
const page = pages[i]
|
||||||
|
const [video, audio] = page.titledFragments
|
||||||
|
if (
|
||||||
|
!(
|
||||||
|
page.fragments.length === 2 &&
|
||||||
|
video.extension === dashVideoExtension &&
|
||||||
|
(audio.extension === dashAudioExtension || audio.extension === dashFlacAudioExtension)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
throw new Error('仅支持 DASH 格式视频和音频')
|
||||||
|
}
|
||||||
|
|
||||||
|
await single(
|
||||||
|
video.title,
|
||||||
|
video.url,
|
||||||
|
audio.url,
|
||||||
|
audio.extension === dashFlacAudioExtension,
|
||||||
|
i + 1,
|
||||||
|
pages.length,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
import { Toast, ToastType } from '@/core/toast'
|
import { Toast } from '@/core/toast'
|
||||||
import { PluginMetadata } from '@/plugins/plugin'
|
import { PluginMetadata } from '@/plugins/plugin'
|
||||||
import { DownloadVideoOutput } from '../../../../components/video/download/types'
|
import { DownloadVideoOutput } from '../../../../components/video/download/types'
|
||||||
import { run } from './handler'
|
import { run } from './handler'
|
||||||
import { getComponentSettings } from '@/core/settings'
|
|
||||||
import type { Options } from '../../../../components/video/download'
|
|
||||||
|
|
||||||
const title = 'WASM 混流输出'
|
export const title = 'WASM 混流输出'
|
||||||
const desc = '使用 WASM 在浏览器中下载并合并音视频'
|
const desc = '使用 WASM 在浏览器中下载并合并音视频, 支持批量下载'
|
||||||
|
|
||||||
export const plugin: PluginMetadata = {
|
export const plugin: PluginMetadata = {
|
||||||
name: 'downloadVideo.outputs.wasm',
|
name: 'downloadVideo.outputs.wasm',
|
||||||
@ -23,40 +21,10 @@ export const plugin: PluginMetadata = {
|
|||||||
displayName: 'WASM',
|
displayName: 'WASM',
|
||||||
description: `${desc},运行过程中请勿关闭页面,初次使用或清除缓存后需要加载约 30 MB 的 WASM 文件`,
|
description: `${desc},运行过程中请勿关闭页面,初次使用或清除缓存后需要加载约 30 MB 的 WASM 文件`,
|
||||||
runAction: async action => {
|
runAction: async action => {
|
||||||
const fragments = action.infos.flatMap(it => it.titledFragments)
|
try {
|
||||||
const { dashAudioExtension, dashFlacAudioExtension, dashVideoExtension } =
|
await run(action)
|
||||||
getComponentSettings<Options>('downloadVideo').options
|
} catch (error) {
|
||||||
|
Toast.error(String(error), title)
|
||||||
if (
|
|
||||||
fragments.length > 2 ||
|
|
||||||
(fragments.length === 2 &&
|
|
||||||
!(
|
|
||||||
fragments[0].extension === dashVideoExtension &&
|
|
||||||
(fragments[1].extension === dashAudioExtension ||
|
|
||||||
fragments[1].extension === dashFlacAudioExtension)
|
|
||||||
))
|
|
||||||
) {
|
|
||||||
Toast.error('仅支持单个视频下载', title).duration = 1500
|
|
||||||
} else {
|
|
||||||
const toast = Toast.info('正在加载', title)
|
|
||||||
try {
|
|
||||||
if (fragments.length === 2) {
|
|
||||||
await run(
|
|
||||||
fragments[0].title,
|
|
||||||
toast,
|
|
||||||
fragments[0].url,
|
|
||||||
fragments[1].url,
|
|
||||||
fragments[1].extension === dashFlacAudioExtension,
|
|
||||||
) // [dash]
|
|
||||||
} else {
|
|
||||||
toast.type = ToastType.Error
|
|
||||||
toast.message = '仅支持 dash 格式视频下载'
|
|
||||||
toast.duration = 1500
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
toast.close()
|
|
||||||
Toast.error(String(error), title)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user