Skip to content

Commit

Permalink
Add 'download cover' option in 'downloadVideo' component
Browse files Browse the repository at this point in the history
- add a plugin in utils/view-cover components for downloadVideo
- reconstruct codes for getting video cover url.
  • Loading branch information
oxygenkun committed Oct 6, 2023
1 parent 62b149a commit e6dece0
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 20 deletions.
51 changes: 51 additions & 0 deletions registry/lib/components/utils/view-cover/Plugin.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<template>
<div class="download-cover-config download-video-config-section">
<div class="download-video-config-item">
<div class="download-video-config-title">封面:</div>
<VDropdown v-model="type" :items="items">
<template #item="{ item }">
{{ item }}
</template>
</VDropdown>
</div>
</div>
</template>
<script lang="ts">
import { getComponentSettings } from '@/core/settings'
import { VDropdown } from '@/ui'
import { CoverDownloadType } from './utils'
interface Options {
CoverType: CoverDownloadType | ''
}
const options = getComponentSettings('downloadVideo').options as Options
export default Vue.extend({
components: {
VDropdown,
},
data() {
return {
type: options.CoverType ?? '',
items: ['', 'jpg'],
}
},
computed: {
enabled() {
return this.type !== ''
},
},
watch: {
type(newValue: CoverDownloadType) {
options.CoverType = newValue
},
},
})
</script>
<style lang="scss">
.download-cover-config.download-video-config-section {
.be-dropdown {
text-transform: uppercase;
}
}
</style>
12 changes: 2 additions & 10 deletions registry/lib/components/utils/view-cover/ViewCover.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@
import { getJson } from '@/core/ajax'
import { videoChange } from '@/core/observer'
import { select } from '@/core/spin-query'
import { logError } from '@/core/utils/log'
import { showImage, DefaultWidget } from '@/ui'
import { VideoInfo } from '@/components/video/video-info'
import { getVideoCoverUrlByAid } from './utils'
export default Vue.extend({
components: {
Expand All @@ -29,14 +28,7 @@ export default Vue.extend({
if (!document.URL.includes('live.bilibili.com')) {
videoChange(async () => {
const { aid } = unsafeWindow
const videoInfo = new VideoInfo(aid)
try {
await videoInfo.fetchInfo()
} catch (error) {
logError(error)
throw error
}
this.imageUrl = videoInfo.coverUrl.replace('http:', 'https:')
this.imageUrl = await getVideoCoverUrlByAid(aid)
})
} else {
const spaceElementSelector = '.header-info-ctnr .room-cover, .header-info-ctnr .avatar'
Expand Down
47 changes: 47 additions & 0 deletions registry/lib/components/utils/view-cover/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { defineComponentMetadata } from '@/components/define'
import { PackageEntry } from '@/core/download'
import { videoAndBangumiUrls } from '@/core/utils/urls'
import { Toast } from '@/core/toast'
import { DownloadVideoAssets } from '../../video/download/types'
import { CoverDownloadType, getBlobByAid } from './utils'

export const component = defineComponentMetadata({
name: 'viewCover',
Expand All @@ -12,6 +16,49 @@ export const component = defineComponentMetadata({
entry: none,
reload: none,
unload: none,
plugin: {
displayName: '下载视频 - 下载封面支持',
setup: ({ addData }) => {
addData('downloadVideo.assets', async (assets: DownloadVideoAssets[]) => {
assets.push({
name: 'downloadCover',
displayName: '下载封面',
getAssets: async (
infos,
instance: {
type: CoverDownloadType
enabled: boolean
},
) => {
const { type, enabled } = instance
if (!enabled) {
return []
}
const toast = Toast.info('获取封面中...', '下载封面')
let downloadedItemCount = 0
const results = await Promise.allSettled(
infos.map(async info => {
const blob = await getBlobByAid(info.input.aid)
downloadedItemCount++
toast.message = `获取封面中... (${downloadedItemCount}/${infos.length})`
return {
name: `${info.input.title}.${type}`,
data: blob,
}
}),
)
const success = results.filter(
it => it.status === 'fulfilled',
) as PromiseFulfilledResult<PackageEntry>[]
const fail = results.filter(it => it.status === 'rejected') as PromiseRejectedResult[]
toast.message = `获取完成. 成功 ${success.length} 个, 失败 ${fail.length} 个.`
return success.map(it => it.value)
},
component: () => import('./Plugin.vue').then(m => m.default),
})
})
},
},
widget: {
component: () => import('./ViewCover.vue').then(m => m.default),
},
Expand Down
22 changes: 22 additions & 0 deletions registry/lib/components/utils/view-cover/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { logError } from '@/core/utils/log'
import { VideoInfo } from '@/components/video/video-info'

export type CoverDownloadType = 'jpg'

export const getVideoCoverUrlByAid = async (aid: string) => {
const videoInfo = new VideoInfo(aid)
try {
await videoInfo.fetchInfo()
} catch (error) {
logError(error)
throw error
}
return videoInfo.coverUrl.replace('http:', 'https:')
}

export const getBlobByAid = async (aid: string) => {
const url = await getVideoCoverUrlByAid(aid)
const response = await fetch(url)
const blob = await response.blob()
return blob
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
</template>
<script lang="ts">
import { videoChange } from '@/core/observer'
import { logError } from '@/core/utils/log'
import { VideoInfo } from '@/components/video/video-info'
import { getVideoCoverUrlByAid } from '../../../../utils/view-cover/utils'
export default Vue.extend({
data() {
Expand All @@ -18,14 +17,7 @@ export default Vue.extend({
created() {
videoChange(async () => {
const { aid } = unsafeWindow
const videoInfo = new VideoInfo(aid)
try {
await videoInfo.fetchInfo()
} catch (error) {
logError(error)
throw error
}
this.imageUrl = videoInfo.coverUrl.replace('http:', 'https:')
this.imageUrl = await getVideoCoverUrlByAid(aid)
})
},
})
Expand Down

0 comments on commit e6dece0

Please sign in to comment.