Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 43 additions & 1 deletion registry/lib/components/video/download/DownloadVideo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@
@change="saveSelectedQuality()"
/>
</div>
<div v-if="audioLanguages && audioLanguages.length > 0" class="download-video-config-item">
<div class="download-video-config-title">选择音轨:</div>
<VDropdown
v-model="selectedAudioTrack"
:items="audioTrackOptions"
@change="saveSelectedAudioTrack()"
/>
</div>
<template v-if="!testData.multiple && selectedQuality">
<div v-if="testData.videoInfo" class="download-video-config-description">
预计大小: {{ formatFileSize(testData.videoInfo.totalSize) }}
Expand Down Expand Up @@ -166,6 +174,8 @@ const getFallbackTestVideoInfo = () =>
title: getFriendlyTitle(true),
} as DownloadVideoInputItem)

const DEFAULT_AUDIO_TRACK = { name: '', displayName: '原声' }

export default Vue.extend({
components: {
VPopup,
Expand Down Expand Up @@ -199,6 +209,8 @@ export default Vue.extend({
assets,
qualities: [],
selectedQuality: undefined,
audioLanguages: [],
selectedAudioTrack: undefined,
inputs: [],
selectedInput: undefined,
apis: [],
Expand All @@ -220,12 +232,22 @@ export default Vue.extend({
}
return this.qualities
},
audioTrackOptions() {
const options = this.audioLanguages.map(item => ({
name: item.language,
displayName: item.title,
}))
if (options.length > 0) {
options.unshift(DEFAULT_AUDIO_TRACK)
}
return options
},
canStartDownload() {
if (this.busy || !this.open) {
return false
}
const isAnySelectionEmpty = Object.entries(this)
.filter(([key]) => key.startsWith('selected'))
.filter(([key]) => key.startsWith('selected') && key !== 'selectedAudioTrack')
.some(([, value]) => !value)
if (isAnySelectionEmpty) {
return false
Expand Down Expand Up @@ -289,6 +311,9 @@ export default Vue.extend({
basicConfig.quality = quality.value
this.updateTestVideoInfo()
},
saveSelectedAudioTrack() {
this.updateTestVideoInfo()
},
async getVideoItems() {
const input = this.selectedInput as DownloadVideoInput
const videoItems = await input.getInputs(this.$refs.inputOptions)
Expand All @@ -307,6 +332,8 @@ export default Vue.extend({
try {
const videoInfo = await api.downloadVideoInfo(testItem)
this.qualities = videoInfo.qualities
this.audioLanguages = videoInfo.audioLanguages || []

const isSelectedQualityOutdated =
!this.selectedQuality ||
!videoInfo.qualities.some(q => q.value === this.selectedQuality.value)
Expand All @@ -319,8 +346,22 @@ export default Vue.extend({
}
}
}

const isSelectedAudioTrackOutdated =
!this.selectedAudioTrack ||
(this.selectedAudioTrack.name !== '' &&
!this.audioLanguages.some(item => item.language === this.selectedAudioTrack.name))

if (isSelectedAudioTrackOutdated) {
if (this.audioLanguages.length > 0) {
this.selectedAudioTrack = DEFAULT_AUDIO_TRACK
} else {
this.selectedAudioTrack = undefined
}
}
// 填充 quality 后要再请求一次得到对应 quality 的统计数据
testItem.quality = this.selectedQuality
testItem.audioLanguage = this.selectedAudioTrack?.name
const qualityVideoInfo = await api.downloadVideoInfo(testItem)
this.testData.videoInfo = qualityVideoInfo
console.log('[qualityVideoInfo]', qualityVideoInfo)
Expand All @@ -341,6 +382,7 @@ export default Vue.extend({
}
videoInputs.forEach(item => {
item.quality = this.selectedQuality
item.audioLanguage = this.selectedAudioTrack?.name
})
const videoInfos = await Promise.all(videoInputs.map(i => api.downloadVideoInfo(i)))
if (videoInfos.length === 0 || lodash.sumBy(videoInfos, it => it.fragments.length) === 0) {
Expand Down
16 changes: 14 additions & 2 deletions registry/lib/components/video/download/apis/dash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Options } from '..'
import { compareQuality } from '../error'
import {
DownloadVideoApi,
DownloadVideoAudioLanguage,
DownloadVideoFragment,
DownloadVideoInfo,
DownloadVideoInputItem,
Expand Down Expand Up @@ -115,8 +116,8 @@ const downloadDash = async (
audio: () => true,
...filters,
}
const { aid, cid, quality } = input
const params = {
const { aid, cid, quality, audioLanguage } = input
const params: Record<string, string | number> = {
avid: aid,
cid,
qn: quality?.value ?? '',
Expand All @@ -125,6 +126,9 @@ const downloadDash = async (
fnver: 0,
fnval: 4048,
}
if (audioLanguage) {
params.cur_language = audioLanguage
}
const isBanugmi = bangumiUrls.some(url => matchUrlPattern(url))
const api = isBanugmi ? bangumiApi(formData(params)) : videoApi(formData(params))
const data = await bilibiliApi(getJsonWithCredentials(api), '获取视频链接失败')
Expand Down Expand Up @@ -219,6 +223,13 @@ const downloadDash = async (
})()
const currentCodec = fragments.find(x => x.type === 'video')?.codec
const currentBandWidth = fragments.reduce((p, c) => p + c.bandWidth, 0)
let audioLanguages: DownloadVideoAudioLanguage[] | undefined
if (data.language?.items?.length) {
audioLanguages = data.language.items.map((item: any) => ({
language: item.lang,
title: item.title,
}))
}
const info = new DownloadVideoInfo({
input,
jsonData: data,
Expand All @@ -227,6 +238,7 @@ const downloadDash = async (
currentQuality,
currentCodec,
currentBandWidth,
audioLanguages,
})
compareQuality(input, info)
return info
Expand Down
7 changes: 7 additions & 0 deletions registry/lib/components/video/download/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ export interface DownloadVideoInputItem {
quality?: VideoQuality
/** 是否允许画质回退, 当实际画质和期望画质不符时此项将决定是否抛出异常 */
allowQualityDrop?: boolean
/** 请求的音轨语言 */
audioLanguage?: string
}
export interface DownloadVideoAudioLanguage {
language: string
title: string
}
/** 页面数据提供者 */
export interface DownloadVideoInput<InputParameter = any> extends VueInstanceInput, WithName {
Expand Down Expand Up @@ -50,6 +56,7 @@ export class DownloadVideoInfo {
public currentQuality: VideoQuality
public currentCodec?: string
public currentBandWidth?: number
public audioLanguages?: DownloadVideoAudioLanguage[]
public jsonData: any
constructor(
parameters: Omit<DownloadVideoInfo, 'totalSize' | 'totalLength' | 'titledFragments'>,
Expand Down
12 changes: 10 additions & 2 deletions src/ui/VDropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ export default Vue.extend({
},
keyMapper: {
type: Function,
default: (item: any) => item.name,
default: (item: any) =>
item !== null && typeof item === 'object' && 'name' in item ? item.name : item,
},
round: {
type: Boolean,
Expand Down Expand Up @@ -118,7 +119,14 @@ export default Vue.extend({
},
methods: {
selectItem(item: any) {
if (item !== this.value) {
let isChanged = false
if (item && this.value && this.keyMapper) {
isChanged = this.keyMapper(item) !== this.keyMapper(this.value)
} else {
isChanged = item !== this.value
}

if (isChanged) {
this.$emit('change', item)
}
this.popupOpen = false
Expand Down
Loading