Merge branch 'preview-fixes'

This commit is contained in:
the1812 2022-02-05 23:11:40 +08:00
commit c9432fc369
16 changed files with 96 additions and 59 deletions

View File

@ -4,12 +4,8 @@
- 需要安装 [Node.js](https://nodejs.org/en/download/) (>= 14.0), [Visual Studio Code](https://code.visualstudio.com/) 和 [yarn](https://yarnpkg.com/getting-started/install#global-install).
- 将项目 Fork 至自己账户后, 克隆至本地
```powershell
git clone https://github.com/{{your-name}}/Bilibili-Evolved.git -b preview --single-branch
cd Bilibili-Evolved
```
- 安装依赖
- 分支视情况切换或新建, 新功能以 `preview-features` 为基础分支, 功能修复以 `preview-fixes` 为基础分支.
- 安装依赖:
```powershell
yarn
@ -241,7 +237,7 @@ export const component: ComponentMetadata = {
commit message 只需写明改动点, 中英文随意, 也不强求类似 [commit-lint](https://github.com/conventional-changelog/commitlint) 的格式.
## 发起 PR (合并请求)
将你的分支往主仓库的 `preview` 分支合并就行.
将你的分支往主仓库的 `preview-features` (新增功能) 或 `preview-fixes` (功能修复) 分支合并就行.
## 自行保留
你可以选择不将功能代码合并到主仓库, 因此也没有 ESLint 的限制. PR 时仅添加指向你的仓库中的组件信息即可, 具体来说, 是在 `registry/lib/docs/third-party.ts` 中, 往对应数组中添加你的功能的相关信息, 当然别忘了把 `owner` 设为你的 GitHub 用户名.

File diff suppressed because one or more lines are too long

View File

@ -24,6 +24,7 @@ export const entry: ComponentEntry = async ({ metadata: { name } }) => {
const globalFixedExclude = [
'https://space.bilibili.com',
'https://www.bilibili.com/read',
'https://www.bilibili.com/account/history',
]
if (!globalFixedExclude.some(p => matchUrlPattern(p))) {
addComponentListener(`${name}.globalFixed`, value => {

View File

@ -13,7 +13,8 @@ li.nav-item[report-id="playpage_dynamic"] .i-frame,
.bili-header-m .head-banner .head-content .head-logo,
#biliMainHeader .mini-header,
#biliMainHeader .base-mini-header,
.bili-header__bar {
.bili-header__bar,
.z-top-container {
display: none !important;
}
.van-popover {

View File

@ -1,5 +1,5 @@
<template>
<div class="history-list">
<div class="custom-navbar-history-list">
<div class="header">
<div class="header-row">
<div class="search">
@ -217,7 +217,7 @@ export default Vue.extend({
@import "common";
@import "../popup";
.history-list {
.custom-navbar-history-list {
width: 350px;
@include navbar-popup-height();
font-size: 12px;

View File

@ -89,7 +89,7 @@ import {
VLoading,
} from '@/ui'
import { addComponentListener } from '@/core/settings'
import { dqa } from '@/core/utils'
import { deleteValue, dqa } from '@/core/utils'
import { SortableJSLibrary } from '@/core/runtime-library'
import { SortableEvent } from 'sortablejs'
import { getData } from '@/plugins/data'
@ -122,7 +122,7 @@ export default Vue.extend({
padding: navbarOptions.padding,
rendered,
// order: navbarOptions.order,
hidden: navbarOptions.hidden,
hidden: [...navbarOptions.hidden],
loaded: false,
}
},
@ -173,11 +173,13 @@ export default Vue.extend({
this.rendered.items = sortItems(rendered.items, ordersMap)
},
toggleVisible(item: CustomNavbarItem) {
if (navbarOptions.hidden.includes(item.name)) {
lodash.pull(navbarOptions.hidden, item.name)
if (this.hidden.includes(item.name)) {
deleteValue(this.hidden, it => it === item.name)
deleteValue(navbarOptions.hidden, it => it === item.name)
item.hidden = false
console.log('delete', item.name)
} else {
this.hidden.push(item.name)
navbarOptions.hidden.push(item.name)
item.hidden = true
console.log('add', item.name)

View File

@ -140,7 +140,11 @@ import { getFriendlyTitle } from '@/core/utils/title'
import { bangumiBatchInput } from './inputs/bangumi/batch'
import { videoBatchInput } from './inputs/video/batch'
import { videoSingleInput } from './inputs/video/input'
import { videoDashAVC, videoDashHEVC, audioDash } from './apis/dash'
import {
videoDashAVC,
videoDashHEVC,
videoAudioDash,
} from './apis/dash'
import { videoFlv } from './apis/flv'
import { toastOutput } from './outputs/toast'
import {
@ -164,7 +168,7 @@ const [apis] = registerAndGetData(
videoFlv,
videoDashAVC,
videoDashHEVC,
audioDash,
videoAudioDash,
] as DownloadVideoApi[],
)
const [assets] = registerAndGetData(
@ -182,7 +186,7 @@ const { basicConfig } = getComponentSettings('downloadVideo').options as {
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)
return matchedItems
}
@ -202,7 +206,6 @@ export default Vue.extend({
},
},
data() {
const lastApi = basicConfig.api
const lastOutput = basicConfig.output
return {
open: false,
@ -219,8 +222,8 @@ export default Vue.extend({
selectedQuality: undefined,
inputs: [],
selectedInput: undefined,
apis,
selectedApi: apis.find(it => it.name === lastApi) || apis[0],
apis: [],
selectedApi: undefined,
outputs,
selectedOutput: outputs.find(it => it.name === lastOutput) || outputs[0],
}
@ -269,9 +272,20 @@ export default Vue.extend({
},
mounted() {
coreApis.observer.videoChange(() => {
this.selectedInput = undefined
this.selectedApi = undefined
const matchedInputs = filterData(inputs)
this.inputs = matchedInputs
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: {
@ -291,7 +305,7 @@ export default Vue.extend({
return videoItems
},
async updateTestVideoInfo() {
if (!this.selectedInput) {
if (!this.selectedInput || !this.selectedApi) {
return
}
this.testData.videoInfo = null

View File

@ -1,13 +1,13 @@
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 { allQualities, VideoQuality } from '@/components/video/video-quality'
import { bangumiUrls } from '@/core/utils/urls'
import { compareQuality } from '../error'
import {
DownloadVideoApi, DownloadVideoFragment, DownloadVideoInfo, DownloadVideoInputItem,
} from '../types'
/* spell-checker: disable */
import { bangumiApi, videoApi } from './url'
/** dash 格式更明确的扩展名 */
export const DashExtensions = {
@ -75,12 +75,14 @@ export const dashToFragments = (info: {
}
return results
}
/* spell-checker: disable */
const downloadDash = async (
input: DownloadVideoInputItem,
config: {
codec?: DashCodec
filters?: DashFilters
},
} = {},
) => {
const { codec = 'AVC/H.264', filters } = config
const dashFilters = {
@ -98,7 +100,8 @@ const downloadDash = async (
fnver: 0,
fnval: 2000,
}
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(
getJsonWithCredentials(api),
'获取视频链接失败',
@ -184,6 +187,7 @@ const downloadDash = async (
compareQuality(input, info)
return info
}
export const videoDashAVC: DownloadVideoApi = {
name: 'video.dash.avc',
displayName: 'dash (AVC/H.264)',
@ -196,7 +200,7 @@ export const videoDashHEVC: DownloadVideoApi = {
description: '音画分离的 mp4 格式, 编码为 H.265, 体积较小, 兼容性较差. 下载后可以合并为单个 mp4 文件.',
downloadVideoInfo: async input => downloadDash(input, { codec: 'HEVC/H.265' }),
}
export const audioDash: DownloadVideoApi = {
export const videoAudioDash: DownloadVideoApi = {
name: 'video.dash.audio',
displayName: 'dash (仅音频)',
description: '仅下载视频中的音频轨道.',

View File

@ -1,12 +1,15 @@
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 { bangumiUrls } from '@/core/utils/urls'
import { compareQuality } from '../error'
import {
DownloadVideoApi,
DownloadVideoFragment,
DownloadVideoInfo,
DownloadVideoInputItem,
} from '../types'
import { bangumiApi, videoApi } from './url'
const parseInfoFromJson = (data: any, extensions: string[]) => {
const getExtension = (index: number) => {
@ -32,33 +35,39 @@ const parseInfoFromJson = (data: any, extensions: string[]) => {
currentQuality,
}
}
/* 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 = {
name: 'video.flv',
displayName: 'flv',
description: '使用 flv 格式下载, 兼容 H.264 编码.',
downloadVideoInfo: async 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
},
downloadVideoInfo: input => downloadFlv(input),
}

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

View File

@ -22,7 +22,7 @@
</div> -->
</div>
<div class="script-links">
<a target="_blank" href="https://github.com/the1812/Bilibili-Evolved/tree/v2/" class="homepage script-link">
<a target="_blank" href="https://github.com/the1812/Bilibili-Evolved" class="homepage script-link">
<VButton>
<VIcon icon="mdi-home-outline" :size="20" />
主页

View File

@ -172,7 +172,7 @@ export interface FunctionalMetadata {
/** 插件化数据定义 */
plugin?: Optional<PluginMinimalData, 'name'>
/** 额外想要展示在设置里的选项 UI */
extraOptions?: Executable<VueModule>
extraOptions?: () => Promise<VueModule>
/** 设置匹配的URL, 不匹配则不运行此组件 */
urlInclude?: TestPattern
/** 设置不匹配的URL, 不匹配则不运行此组件, 优先级高于`urlInclude` */

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: false): Promise<number[]>
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 { getJsonWithCredentials } = await import('@/core/ajax')
const response = await getJsonWithCredentials(api)

View File

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

View File

@ -17,6 +17,7 @@ export const mediaListUrls = [
/** 含有普通视频的页面 */
export const videoUrls = [
'//www.bilibili.com/video/',
/\/\/www\.bilibili\.com\/festival\/(\d+)bnj/,
...mediaListUrls,
]
/** 含有番剧的页面 */
@ -43,6 +44,7 @@ export const mainSiteUrls = [
/^https:\/\/www\.bilibili\.com\/$/,
/^https:\/\/www\.bilibili\.com\/([^\/]+)\.html$/,
/^https:\/\/www\.bilibili\.com\/watchlater\/#\/list$/,
'https://www.bilibili.com/account/',
]
/** 直播间页面 */
export const liveUrls = [