Skip to content

Commit

Permalink
Merge pull request #4798 from oxygenkun/preview-features
Browse files Browse the repository at this point in the history
[组件-下载视频][插件-下载视频 - aria2 输出支持][组件-查看封面] 为aria2提供可下载封面的功能
  • Loading branch information
the1812 authored Jul 24, 2024
2 parents c6449e8 + 593ee5e commit eb6a9db
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 37 deletions.
22 changes: 21 additions & 1 deletion registry/lib/components/utils/view-cover/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { defineComponentMetadata } from '@/components/define'
import { getBlobByAid } from '@/components/video/video-cover'
import { getVideoCoverUrlByAid, getBlobByAid } from '@/components/video/video-cover'
import { PackageEntry } from '@/core/download'
import { videoAndBangumiUrls } from '@/core/utils/urls'
import { Toast } from '@/core/toast'
Expand Down Expand Up @@ -55,6 +55,26 @@ export const component = defineComponentMetadata({
toast.message = `获取完成. 成功 ${success.length} 个, 失败 ${fail.length} 个.`
return success.map(it => it.value)
},
getUrls: async (
infos,
instance: {
type: CoverDownloadType
enabled: boolean
},
) => {
const { type, enabled } = instance
if (!enabled) {
return []
}
return Promise.all(
infos.map(async info => {
return {
name: `${info.input.title}.${type}`,
url: await getVideoCoverUrlByAid(info.input.aid),
}
}),
)
},
component: () => import('./Plugin.vue').then(m => m.default),
})
})
Expand Down
20 changes: 8 additions & 12 deletions registry/lib/components/video/download/DownloadVideo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -330,19 +330,15 @@ export default Vue.extend({
})
}
const action = new DownloadVideoAction(videoInfos)
const extraAssets = (
await Promise.all(
assets.map(a =>
a.getAssets(
videoInfos,
this.$refs.assetsOptions.find((c: any) => c.$attrs.name === a.name),
),
),
)
).flat()
action.extraAssets.push(...extraAssets)
await action.downloadExtraAssets()
assets.forEach(a => {
const assetsType = a?.getUrls ? action.extraOnlineAssets : action.extraAssets
assetsType.push({
asset: a,
instance: this.$refs.assetsOptions.find((c: any) => c.$attrs.name === a.name),
})
})
await output.runAction(action, instance)
await action.downloadExtraAssets()
} catch (error) {
logError(error)
} finally {
Expand Down
22 changes: 19 additions & 3 deletions registry/lib/components/video/download/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,19 @@ export interface DownloadVideoApi extends WithName {
/** 表示下载时额外附带的产物, 如弹幕 / 字幕等 */
export interface DownloadVideoAssets<AssetsParameter = any> extends VueInstanceInput, WithName {
getAssets: (infos: DownloadVideoInfo[], instance: AssetsParameter) => Promise<PackageEntry[]>
/** 获取可直接下载的链接 */
getUrls?: (
infos: DownloadVideoInfo[],
instance: AssetsParameter,
) => Promise<{ name: string; url: string }[]>
}
/** 表示视频的下载信息以及携带的额外产物 */
export class DownloadVideoAction {
export class DownloadVideoAction<AssetsParameter = any> {
readonly inputs: DownloadVideoInputItem[] = []
extraAssets: PackageEntry[] = []
/** 可调用处理的asset和对应的参数 */
extraAssets: { asset: DownloadVideoAssets; instance: AssetsParameter }[] = []
/** 可直接下载的asset和对应的参数 */
extraOnlineAssets: { asset: DownloadVideoAssets; instance: AssetsParameter }[] = []

constructor(public infos: DownloadVideoInfo[]) {
this.inputs = infos.map(it => it.input)
Expand All @@ -92,7 +100,15 @@ export class DownloadVideoAction {
async downloadExtraAssets() {
console.log('[downloadExtraAssets]', this.extraAssets)
const filename = `${getFriendlyTitle(false)}.zip`
await new DownloadPackage(this.extraAssets).emit(filename)
const { infos } = this
const extraAssetsBlob = (
await Promise.all(
[...this.extraAssets, ...this.extraOnlineAssets].map(({ asset, instance }) =>
asset.getAssets(infos, instance),
),
)
).flat()
await new DownloadPackage(extraAssetsBlob).emit(filename)
}
}
/** 下载视频的最终输出处理 */
Expand Down
11 changes: 10 additions & 1 deletion registry/lib/plugins/video/download/aria2-output/RpcConfig.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<template>
<div class="rpc-config download-video-config-section">
<div>
<div>aria2下载附属资源(若支持):</div>
<SwitchBox v-model="isPluginDownloadAssets" @change="saveSettings" />
</div>
<div v-if="isRenaming" class="profile-select">
<div class="profile-item-name">重命名 RPC 预设:</div>
<TextBox ref="renameInput" v-model="profileRename" />
Expand Down Expand Up @@ -69,17 +73,19 @@
<script lang="ts">
import { getComponentSettings } from '@/core/settings'
import { Toast } from '@/core/toast'
import { TextBox, VButton, VIcon, VDropdown, TextArea } from '@/ui'
import { TextBox, VButton, VIcon, VDropdown, TextArea, SwitchBox } from '@/ui'
import { Aria2RpcProfile, defaultProfile } from './rpc-profiles'
interface Options {
rpcProfiles: Aria2RpcProfile[]
selectedRpcProfileName: string
isPluginDownloadAssets: boolean
}
const { options: storedOptions } = getComponentSettings('downloadVideo')
const defaultOptions: Options = {
rpcProfiles: [defaultProfile],
selectedRpcProfileName: defaultProfile.name,
isPluginDownloadAssets: false,
}
const options = { ...defaultOptions, ...storedOptions }
const handleMissingProfile = () => {
Expand All @@ -99,19 +105,22 @@ export default Vue.extend({
VIcon,
VDropdown,
TextArea,
SwitchBox,
},
data() {
return {
isRenaming: false,
profileRename: '',
rpcProfiles: options.rpcProfiles,
selectedRpcProfile: lastSelectedProfile,
isPluginDownloadAssets: options.isPluginDownloadAssets,
}
},
methods: {
saveSettings() {
options.selectedRpcProfileName = this.selectedRpcProfile.name
options.rpcProfiles = this.rpcProfiles
options.isPluginDownloadAssets = this.isPluginDownloadAssets
Object.assign(storedOptions, options)
},
async startRename() {
Expand Down
64 changes: 44 additions & 20 deletions registry/lib/plugins/video/download/aria2-output/aria2-rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,35 +131,59 @@ export const aria2Rpc: DownloadVideoOutput = {
action,
instance: Vue & {
selectedRpcProfile: Aria2RpcProfile
isPluginDownloadAssets?: boolean
},
) => {
const { infos } = action
const { selectedRpcProfile } = instance
const { infos, extraOnlineAssets } = action
const { selectedRpcProfile, isPluginDownloadAssets } = instance
const { secretKey, dir, other } = selectedRpcProfile
const referer = document.URL.replace(window.location.search, '')
const totalParams = infos
const ariaParamsGenerator = (url: string, title: string) => {
const singleInfoParams = []
if (secretKey) {
singleInfoParams.push(`token:${secretKey}`)
}
singleInfoParams.push([url])
singleInfoParams.push({
referer,
'user-agent': UserAgent,
out: title,
dir: dir || undefined,
...parseRpcOptions(other),
})
const id = encodeURIComponent(title)
return {
params: singleInfoParams,
id,
}
}

// handle video params
const videoParams = infos
.map(info =>
info.titledFragments.map(fragment => {
const singleInfoParams = []
if (secretKey) {
singleInfoParams.push(`token:${secretKey}`)
}
singleInfoParams.push([fragment.url])
singleInfoParams.push({
referer,
'user-agent': UserAgent,
out: fragment.title,
dir: dir || undefined,
...parseRpcOptions(other),
})
const id = encodeURIComponent(fragment.title)
return {
params: singleInfoParams,
id,
}
const { url, title } = fragment
return ariaParamsGenerator(url, title)
}),
)
.flat()

// handle assets
const assetsAriaParams = []
const extraAssetsForBrowerDownload = []
for (const { asset, instance: assetInstance } of extraOnlineAssets) {
if (isPluginDownloadAssets && 'getUrls' in asset) {
// get asset from aria2
const results = await asset.getUrls(infos, assetInstance)
assetsAriaParams.push(...results.map(({ name, url }) => ariaParamsGenerator(url, name)))
} else {
// remain asset in `extraOnlineAssets`
extraAssetsForBrowerDownload.push({ asset, instance: assetInstance })
}
}
action.extraOnlineAssets = extraAssetsForBrowerDownload

const totalParams = [...videoParams, ...assetsAriaParams]
const results = await sendRpc(selectedRpcProfile, totalParams)
console.table(results)
if (results.length === 1) {
Expand Down

0 comments on commit eb6a9db

Please sign in to comment.