Merge branch 'preview-fixes' into preview-features

This commit is contained in:
the1812 2022-01-27 13:30:13 +08:00
commit 4a1417b082
8 changed files with 82 additions and 42 deletions

File diff suppressed because one or more lines are too long

View File

@ -144,7 +144,7 @@ import {
videoDashAvc, videoDashAvc,
videoDashHevc, videoDashHevc,
videoDashAv1, videoDashAv1,
audioDash, videoAudioDash,
} from './apis/dash' } from './apis/dash'
import { videoFlv } from './apis/flv' import { videoFlv } from './apis/flv'
import { toastOutput } from './outputs/toast' import { toastOutput } from './outputs/toast'
@ -170,7 +170,7 @@ const [apis] = registerAndGetData(
videoDashAvc, videoDashAvc,
videoDashHevc, videoDashHevc,
videoDashAv1, videoDashAv1,
audioDash, videoAudioDash,
] as DownloadVideoApi[], ] as DownloadVideoApi[],
) )
const [assets] = registerAndGetData( const [assets] = registerAndGetData(
@ -188,7 +188,7 @@ const { basicConfig } = getComponentSettings('downloadVideo').options as {
output: string output: string
} }
} }
const filterData = (items: { match?: TestPattern }[]) => { const filterData = <T extends { match?: TestPattern }> (items: T[]) => {
const matchedItems = items.filter(it => it.match?.some(p => matchUrlPattern(p)) ?? true) const matchedItems = items.filter(it => it.match?.some(p => matchUrlPattern(p)) ?? true)
return matchedItems return matchedItems
} }
@ -208,7 +208,6 @@ export default Vue.extend({
}, },
}, },
data() { data() {
const lastApi = basicConfig.api
const lastOutput = basicConfig.output const lastOutput = basicConfig.output
return { return {
open: false, open: false,
@ -225,8 +224,8 @@ export default Vue.extend({
selectedQuality: undefined, selectedQuality: undefined,
inputs: [], inputs: [],
selectedInput: undefined, selectedInput: undefined,
apis, apis: [],
selectedApi: apis.find(it => it.name === lastApi) || apis[0], selectedApi: undefined,
outputs, outputs,
selectedOutput: outputs.find(it => it.name === lastOutput) || outputs[0], selectedOutput: outputs.find(it => it.name === lastOutput) || outputs[0],
} }
@ -278,6 +277,14 @@ export default Vue.extend({
const matchedInputs = filterData(inputs) const matchedInputs = filterData(inputs)
this.inputs = matchedInputs this.inputs = matchedInputs
this.selectedInput = matchedInputs[0] this.selectedInput = matchedInputs[0]
const matchedApis = filterData(apis)
this.apis = matchedApis
const lastApi = matchedApis.find(api => api.name === basicConfig.api)
if (lastApi) {
this.selectedApi = lastApi
} else {
this.selectedApi = matchedApis[0]
}
}) })
}, },
methods: { methods: {
@ -297,7 +304,7 @@ export default Vue.extend({
return videoItems return videoItems
}, },
async updateTestVideoInfo() { async updateTestVideoInfo() {
if (!this.selectedInput) { if (!this.selectedInput || !this.selectedApi) {
return return
} }
this.testData.videoInfo = null this.testData.videoInfo = null

View File

@ -1,13 +1,13 @@
import { bilibiliApi, getJsonWithCredentials } from '@/core/ajax' import { bilibiliApi, getJsonWithCredentials } from '@/core/ajax'
import { formData } from '@/core/utils' import { formData, matchUrlPattern } from '@/core/utils'
import { ascendingSort, descendingSort } from '@/core/utils/sort' import { ascendingSort, descendingSort } from '@/core/utils/sort'
import { allQualities, VideoQuality } from '@/components/video/video-quality' import { allQualities, VideoQuality } from '@/components/video/video-quality'
import { bangumiUrls } from '@/core/utils/urls'
import { compareQuality } from '../error' import { compareQuality } from '../error'
import { import {
DownloadVideoApi, DownloadVideoFragment, DownloadVideoInfo, DownloadVideoInputItem, DownloadVideoApi, DownloadVideoFragment, DownloadVideoInfo, DownloadVideoInputItem,
} from '../types' } from '../types'
import { bangumiApi, videoApi } from './url'
/* spell-checker: disable */
/** dash 格式更明确的扩展名 */ /** dash 格式更明确的扩展名 */
export const DashExtensions = { export const DashExtensions = {
@ -79,12 +79,14 @@ export const dashToFragments = (info: {
} }
return results return results
} }
/* spell-checker: disable */
const downloadDash = async ( const downloadDash = async (
input: DownloadVideoInputItem, input: DownloadVideoInputItem,
config: { config: {
codec?: DashCodec codec?: DashCodec
filters?: DashFilters filters?: DashFilters
}, } = {},
) => { ) => {
const { codec = DashCodec.Avc, filters } = config const { codec = DashCodec.Avc, filters } = config
const dashFilters = { const dashFilters = {
@ -102,7 +104,8 @@ const downloadDash = async (
fnver: 0, fnver: 0,
fnval: 4048, fnval: 4048,
} }
const api = `https://api.bilibili.com/x/player/playurl?${formData(params)}` const isBanugmi = bangumiUrls.some(url => matchUrlPattern(url))
const api = isBanugmi ? bangumiApi(formData(params)) : videoApi(formData(params))
const data = await bilibiliApi( const data = await bilibiliApi(
getJsonWithCredentials(api), getJsonWithCredentials(api),
'获取视频链接失败', '获取视频链接失败',
@ -208,7 +211,7 @@ export const videoDashAv1: DownloadVideoApi = {
description: '音画分离的 mp4 格式, 编码为 AV1, 体积较小, 兼容性较差. 下载后可以合并为单个 mp4 文件.', description: '音画分离的 mp4 格式, 编码为 AV1, 体积较小, 兼容性较差. 下载后可以合并为单个 mp4 文件.',
downloadVideoInfo: async input => downloadDash(input, { codec: DashCodec.Av1 }), downloadVideoInfo: async input => downloadDash(input, { codec: DashCodec.Av1 }),
} }
export const audioDash: DownloadVideoApi = { export const videoAudioDash: DownloadVideoApi = {
name: 'video.dash.audio', name: 'video.dash.audio',
displayName: 'dash (仅音频)', displayName: 'dash (仅音频)',
description: '仅下载视频中的音频轨道.', description: '仅下载视频中的音频轨道.',

View File

@ -1,12 +1,15 @@
import { bilibiliApi, getJsonWithCredentials } from '@/core/ajax' import { bilibiliApi, getJsonWithCredentials } from '@/core/ajax'
import { formData } from '@/core/utils' import { formData, matchUrlPattern } from '@/core/utils'
import { allQualities } from '@/components/video/video-quality' import { allQualities } from '@/components/video/video-quality'
import { bangumiUrls } from '@/core/utils/urls'
import { compareQuality } from '../error' import { compareQuality } from '../error'
import { import {
DownloadVideoApi, DownloadVideoApi,
DownloadVideoFragment, DownloadVideoFragment,
DownloadVideoInfo, DownloadVideoInfo,
DownloadVideoInputItem,
} from '../types' } from '../types'
import { bangumiApi, videoApi } from './url'
const parseInfoFromJson = (data: any, extensions: string[]) => { const parseInfoFromJson = (data: any, extensions: string[]) => {
const getExtension = (index: number) => { const getExtension = (index: number) => {
@ -32,33 +35,39 @@ const parseInfoFromJson = (data: any, extensions: string[]) => {
currentQuality, currentQuality,
} }
} }
/* spell-checker: disable */ /* spell-checker: disable */
const downloadFlv = async (
input: DownloadVideoInputItem,
) => {
const { aid, cid, quality } = input
const params = {
avid: aid,
cid,
qn: quality?.value ?? '',
otype: 'json',
fourk: 1,
fnver: 0,
fnval: 0,
}
const isBanugmi = bangumiUrls.some(url => matchUrlPattern(url))
const api = isBanugmi ? bangumiApi(formData(params)) : videoApi(formData(params))
const data = await bilibiliApi(
getJsonWithCredentials(api),
'获取视频链接失败',
)
const info = new DownloadVideoInfo({
input,
jsonData: data,
...parseInfoFromJson(data, ['.flv']),
})
compareQuality(input, info)
return info
}
export const videoFlv: DownloadVideoApi = { export const videoFlv: DownloadVideoApi = {
name: 'video.flv', name: 'video.flv',
displayName: 'flv', displayName: 'flv',
description: '使用 flv 格式下载, 兼容 H.264 编码.', description: '使用 flv 格式下载, 兼容 H.264 编码.',
downloadVideoInfo: async input => { downloadVideoInfo: input => downloadFlv(input),
const { aid, cid, quality } = input
const params = {
avid: aid,
cid,
qn: quality?.value ?? '',
otype: 'json',
fourk: 1,
fnver: 0,
fnval: 0,
}
const api = `https://api.bilibili.com/x/player/playurl?${formData(params)}`
const data = await bilibiliApi(
getJsonWithCredentials(api),
'获取视频链接失败',
)
const info = new DownloadVideoInfo({
input,
jsonData: data,
...parseInfoFromJson(data, ['.flv']),
})
compareQuality(input, info)
return info
},
} }

View File

@ -0,0 +1,2 @@
export const videoApi = (params: string) => `https://api.bilibili.com/x/player/playurl?${params}`
export const bangumiApi = (params: string) => `https://api.bilibili.com/pgc/player/web/playurl?${params}`

View File

@ -72,6 +72,8 @@ export class DownloadVideoInfo {
export interface DownloadVideoApi extends WithName { export interface DownloadVideoApi extends WithName {
downloadVideoInfo: (input: DownloadVideoInputItem) => Promise<DownloadVideoInfo> downloadVideoInfo: (input: DownloadVideoInputItem) => Promise<DownloadVideoInfo>
description?: string description?: string
/** 网址匹配规则 */
match?: TestPattern
} }
/** 表示下载时额外附带的产物, 如弹幕 / 字幕等 */ /** 表示下载时额外附带的产物, 如弹幕 / 字幕等 */
export interface DownloadVideoAssets<AssetsParameter = any> extends VueInstanceInput, WithName { export interface DownloadVideoAssets<AssetsParameter = any> extends VueInstanceInput, WithName {

View File

@ -88,6 +88,11 @@ export async function getWatchlaterList(): Promise<number[]>
export async function getWatchlaterList(raw: true): Promise<RawWatchlaterItem[]> export async function getWatchlaterList(raw: true): Promise<RawWatchlaterItem[]>
export async function getWatchlaterList(raw: false): Promise<number[]> export async function getWatchlaterList(raw: false): Promise<number[]>
export async function getWatchlaterList(raw = false): Promise<number[] | RawWatchlaterItem[]> { export async function getWatchlaterList(raw = false): Promise<number[] | RawWatchlaterItem[]> {
const { getUID } = await import('@/core/utils')
if (!getUID()) {
console.warn('[稍后再看列表] 账号未登录')
return []
}
const api = 'https://api.bilibili.com/x/v2/history/toview/web' const api = 'https://api.bilibili.com/x/v2/history/toview/web'
const { getJsonWithCredentials } = await import('@/core/ajax') const { getJsonWithCredentials } = await import('@/core/ajax')
const response = await getJsonWithCredentials(api) const response = await getJsonWithCredentials(api)

View File

@ -234,6 +234,7 @@ export interface BilibiliApiResponse {
msg?: string msg?: string
ttl: number ttl: number
data: any data: any
result?: any
} }
/** /**
* bilibili API * bilibili API
@ -252,5 +253,5 @@ export const bilibiliApi = async <T = any>(
logError(error) logError(error)
throw error throw error
} }
return (json.data || {}) as T return (json.data || json.result || {}) as T
} }