mirror of
https://github.com/the1812/Bilibili-Evolved.git
synced 2025-11-04 21:22:45 +08:00
feat: wasm-output plugin supports multiple pages
Co-authored-by: lainio24 <lainio24@outlook.com>
This commit is contained in:
parent
0b3dfac457
commit
4979500d2c
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -62,6 +62,7 @@
|
||||
"linebreak",
|
||||
"Liveroom",
|
||||
"materialdesignicons",
|
||||
"matroska",
|
||||
"medialist",
|
||||
"mimetype",
|
||||
"minmax",
|
||||
@ -133,6 +134,6 @@
|
||||
"*.tsx": "${capture}.ts",
|
||||
"tsconfig.json": "tsconfig.*.json",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,17 @@
|
||||
import { DownloadPackage } from '@/core/download'
|
||||
import { meta } from '@/core/meta'
|
||||
import { getComponentSettings } from '@/core/settings'
|
||||
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 { getCacheOrGet, httpGet, toastProgress, toBlobUrl } from './utils'
|
||||
|
||||
const ffmpeg = new FFmpeg()
|
||||
|
||||
async function load(toast: Toast) {
|
||||
async function loadFFmpeg() {
|
||||
const toast = Toast.info('初始化', pluginTitle)
|
||||
await ffmpeg.load({
|
||||
workerLoadURL: toBlobUrl(
|
||||
await getCacheOrGet(
|
||||
@ -33,24 +38,26 @@ async function load(toast: Toast) {
|
||||
'application/wasm',
|
||||
),
|
||||
})
|
||||
toast.message = '完成!'
|
||||
toast.close()
|
||||
}
|
||||
export async function run(
|
||||
|
||||
async function single(
|
||||
name: string,
|
||||
toast: Toast,
|
||||
videoUrl: string,
|
||||
audioUrl: string,
|
||||
isFlac: boolean,
|
||||
pageIndex = 1,
|
||||
totalPages = 1,
|
||||
) {
|
||||
if (!ffmpeg.loaded) {
|
||||
await load(toast)
|
||||
}
|
||||
const toast = Toast.info('', `${pluginTitle} - ${pageIndex} / ${totalPages}`)
|
||||
|
||||
ffmpeg.writeFile('video', await httpGet(videoUrl, toastProgress(toast, '正在下载视频流')))
|
||||
ffmpeg.writeFile('audio', await httpGet(audioUrl, toastProgress(toast, '正在下载音频流')))
|
||||
toast.message = '混流中……'
|
||||
|
||||
toast.message = '混流中……'
|
||||
const outputExt = isFlac ? 'mkv' : 'mp4'
|
||||
name = isFlac ? name.replace(/.[^/.]+$/, `.${outputExt}`) : name
|
||||
name = name.replace(/.[^/.]+$/, `.${outputExt}`)
|
||||
await ffmpeg.exec([
|
||||
'-i',
|
||||
'video',
|
||||
@ -59,7 +66,7 @@ export async function run(
|
||||
'-c:v',
|
||||
'copy',
|
||||
'-c:a',
|
||||
isFlac ? 'flac' : 'copy',
|
||||
'copy',
|
||||
'-f',
|
||||
isFlac ? 'matroska' : 'mp4',
|
||||
`output.${outputExt}`,
|
||||
@ -71,7 +78,44 @@ export async function run(
|
||||
})
|
||||
|
||||
toast.message = '完成!'
|
||||
toast.duration = 1500
|
||||
toast.duration = 1000
|
||||
|
||||
await DownloadPackage.single(name, outputBlob)
|
||||
}
|
||||
|
||||
export async function run(action: DownloadVideoAction) {
|
||||
if (!ffmpeg.loaded) {
|
||||
await loadFFmpeg()
|
||||
}
|
||||
|
||||
const pages = lodash.chunk(
|
||||
action.infos.flatMap(it => it.titledFragments),
|
||||
2,
|
||||
)
|
||||
|
||||
const { dashAudioExtension, dashFlacAudioExtension, dashVideoExtension } =
|
||||
getComponentSettings<Options>('downloadVideo').options
|
||||
|
||||
for (let i = 0; i < pages.length; i++) {
|
||||
const page = pages[i]
|
||||
const [video, audio] = page
|
||||
if (
|
||||
!(
|
||||
page.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,11 +1,9 @@
|
||||
import { Toast, ToastType } from '@/core/toast'
|
||||
import { Toast } from '@/core/toast'
|
||||
import { PluginMetadata } from '@/plugins/plugin'
|
||||
import { DownloadVideoOutput } from '../../../../components/video/download/types'
|
||||
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 在浏览器中下载并合并音视频'
|
||||
|
||||
export const plugin: PluginMetadata = {
|
||||
@ -23,41 +21,11 @@ export const plugin: PluginMetadata = {
|
||||
displayName: 'WASM',
|
||||
description: `${desc},运行过程中请勿关闭页面,初次使用或清除缓存后需要加载约 30 MB 的 WASM 文件`,
|
||||
runAction: async action => {
|
||||
const fragments = action.infos.flatMap(it => it.titledFragments)
|
||||
const { dashAudioExtension, dashFlacAudioExtension, dashVideoExtension } =
|
||||
getComponentSettings<Options>('downloadVideo').options
|
||||
|
||||
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
|
||||
}
|
||||
await run(action)
|
||||
} catch (error) {
|
||||
toast.close()
|
||||
Toast.error(String(error), title)
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
Loading…
Reference in New Issue
Block a user