mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-14 09:38:13 +08:00
🐛 修复视频地址获取失败
This commit is contained in:
@@ -14,31 +14,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <TpVideo :data="mock" />-->
|
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup></script>
|
||||||
import { onMounted } from "vue";
|
|
||||||
|
|
||||||
import Bili from "../../plugins/Bili";
|
|
||||||
// import TpVideo from "../../components/post/TpVideo.vue";
|
|
||||||
|
|
||||||
const mock = {
|
|
||||||
insert: {
|
|
||||||
video: "https://player.bilibili.com/player.html?aid=540893019&autoplay=false&bvid=BV1ri4y1s7sY",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(async () => {
|
|
||||||
const url = new URL(mock.insert.video);
|
|
||||||
const aid = url.searchParams.get("aid") ?? undefined;
|
|
||||||
const bvid = url.searchParams.get("bvid") ?? undefined;
|
|
||||||
const baseData = await Bili.video.view(aid, bvid);
|
|
||||||
console.log("baseData", baseData);
|
|
||||||
const cid = baseData.cid;
|
|
||||||
const urlData = await Bili.video.url(cid, undefined, bvid);
|
|
||||||
console.log("urlData", urlData);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
.test-box {
|
.test-box {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file plugins/Bili/request/getVideoUrl.ts
|
* @file plugins/Bili/request/getVideoUrl.ts
|
||||||
* @description Bili 插件视频请求文件
|
* @description Bili 插件视频请求文件
|
||||||
* @since Beta v0.4.0
|
* @since Beta v0.4.1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { http } from "@tauri-apps/api";
|
import { http } from "@tauri-apps/api";
|
||||||
@@ -10,44 +10,33 @@ import getWrid from "../utils/getWrid";
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 获取视频播放地址
|
* @description 获取视频播放地址
|
||||||
* @since Beta v0.4.0
|
* @since Beta v0.4.1
|
||||||
* @see https://socialsisteryi.github.io/bilibili-API-collect/docs/video/videostream_url.html#dash%E6%A0%BC%E5%BC%8F
|
* @see https://socialsisteryi.github.io/bilibili-API-collect/docs/video/videostream_url.html#dash%E6%A0%BC%E5%BC%8F
|
||||||
* @param {string} [aid] 视频AV号
|
* @param {string} bvid 视频BV号
|
||||||
* @param {string} [bvid] 视频BV号
|
|
||||||
* @param {number} cid 视频分P号
|
* @param {number} cid 视频分P号
|
||||||
* @returns {Promise<string>} 视频播放地址
|
* @returns {Promise<TGApp.Plugins.Bili.Video.UrlData>} 视频播放地址
|
||||||
*/
|
*/
|
||||||
async function getVideoUrl(cid: number, aid?: string, bvid?: string): Promise<unknown> {
|
async function getVideoUrl(cid: number, bvid: string): Promise<TGApp.Plugins.Bili.Video.UrlData> {
|
||||||
const url = "https://api.bilibili.com/x/player/wbi/playurl";
|
const url = "https://api.bilibili.com/x/player/playurl";
|
||||||
let params: Record<string, string> = {
|
let params: Record<string, string> = {
|
||||||
|
bvid,
|
||||||
cid: cid.toString(),
|
cid: cid.toString(),
|
||||||
platform: "html5",
|
fnval: "16",
|
||||||
high_quality: "1",
|
platform: "pc",
|
||||||
};
|
};
|
||||||
if (aid) {
|
const wridRes = await getWrid(params);
|
||||||
params = {
|
|
||||||
aid,
|
|
||||||
...params,
|
|
||||||
};
|
|
||||||
} else if (bvid) {
|
|
||||||
params = {
|
|
||||||
bvid,
|
|
||||||
...params,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
throw new Error("参数错误");
|
|
||||||
}
|
|
||||||
const wrid = await getWrid(params);
|
|
||||||
params = {
|
params = {
|
||||||
...params,
|
...params,
|
||||||
wts: wrid[0].toString(),
|
wts: wridRes[0],
|
||||||
wrid: wrid[1],
|
wrid: wridRes[1],
|
||||||
};
|
};
|
||||||
console.log("params", params);
|
|
||||||
return await http
|
return await http
|
||||||
.fetch<TGApp.Plugins.Bili.Video.UrlResponse>(url, {
|
.fetch<TGApp.Plugins.Bili.Video.UrlResponse>(url, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
query: params,
|
query: params,
|
||||||
|
headers: {
|
||||||
|
referer: "https://www.bilibili.com/",
|
||||||
|
},
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
return res.data.data;
|
return res.data.data;
|
||||||
|
|||||||
91
src/plugins/Bili/types/Video.d.ts
vendored
91
src/plugins/Bili/types/Video.d.ts
vendored
@@ -1,12 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
* @file plugins/Bili/types/Video.d.ts
|
* @file plugins/Bili/types/Video.d.ts
|
||||||
* @description Bili 插件视频类型定义文件
|
* @description Bili 插件视频类型定义文件
|
||||||
* @since Beta v0.4.0
|
* @since Beta v0.4.1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Bili 插件视频类型
|
* @description Bili 插件视频类型
|
||||||
* @since Beta v0.4.0
|
* @since Beta v0.4.1
|
||||||
* @namespace Video
|
* @namespace Video
|
||||||
* @memberof TGApp.Plugins.Bili
|
* @memberof TGApp.Plugins.Bili
|
||||||
*/
|
*/
|
||||||
@@ -169,5 +169,90 @@ declare namespace TGApp.Plugins.Bili.Video {
|
|||||||
data: UrlData;
|
data: UrlData;
|
||||||
}
|
}
|
||||||
|
|
||||||
type UrlData = unknown;
|
/**
|
||||||
|
* @description Bili 视频播放地址返回数据
|
||||||
|
* @since Beta v0.4.1
|
||||||
|
* @interface UrlData
|
||||||
|
* @property {string} from 视频来源
|
||||||
|
* @property {string} result 视频播放地址
|
||||||
|
* @property {string} message 视频播放地址
|
||||||
|
* @property {number} quality 视频清晰度
|
||||||
|
* @property {string} format 视频格式
|
||||||
|
* @property {number} timelength 视频时长 (ms)
|
||||||
|
* @property {string} accept_format 视频支持格式
|
||||||
|
* @property {string[]} accept_description 视频支持格式描述
|
||||||
|
* @property {number[]} accept_quality 视频支持清晰度
|
||||||
|
* @property {number} video_codecid 视频编码ID
|
||||||
|
* @property {string} seek_param 视频跳转参数
|
||||||
|
* @property {string} seek_type 视频跳转类型
|
||||||
|
* @property {UrlDurl[]} durl 视频播放地址
|
||||||
|
* @property {UrlFormats} support_formats 视频支持格式
|
||||||
|
* @property {unknown} high_format 视频高清格式
|
||||||
|
* @property {number} last_play_time 视频上次播放时间
|
||||||
|
* @property {number} last_play_cid 视频上次播放分P号
|
||||||
|
* @return UrlData
|
||||||
|
*/
|
||||||
|
interface UrlData {
|
||||||
|
from: string;
|
||||||
|
result: string;
|
||||||
|
message: string;
|
||||||
|
quality: number;
|
||||||
|
format: string;
|
||||||
|
timelength: number;
|
||||||
|
accept_format: string;
|
||||||
|
accept_description: string[];
|
||||||
|
accept_quality: number[];
|
||||||
|
video_codecid: number;
|
||||||
|
seek_param: string;
|
||||||
|
seek_type: string;
|
||||||
|
durl: UrlDurl[];
|
||||||
|
support_formats: UrlFormats;
|
||||||
|
high_format: unknown;
|
||||||
|
last_play_time: number;
|
||||||
|
last_play_cid: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Bili 视频播放地址
|
||||||
|
* @since Beta v0.4.1
|
||||||
|
* @interface UrlDurl
|
||||||
|
* @property {number} order 视频播放地址序号
|
||||||
|
* @property {number} length 视频播放地址长度
|
||||||
|
* @property {number} size 视频播放地址大小
|
||||||
|
* @property {string} ahead 视频播放地址
|
||||||
|
* @property {string} vhead 视频播放地址
|
||||||
|
* @property {string} url 视频播放地址
|
||||||
|
* @property {unknown} backup_url 视频备用播放地址
|
||||||
|
* @return UrlDurl
|
||||||
|
*/
|
||||||
|
interface UrlDurl {
|
||||||
|
order: number;
|
||||||
|
length: number;
|
||||||
|
size: number;
|
||||||
|
ahead: string;
|
||||||
|
vhead: string;
|
||||||
|
url: string;
|
||||||
|
backup_url: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Bili 视频支持格式
|
||||||
|
* @since Beta v0.4.1
|
||||||
|
* @interface UrlFormats
|
||||||
|
* @property {number} quality 视频清晰度
|
||||||
|
* @property {string} format 视频格式
|
||||||
|
* @property {string} new_description 视频格式描述
|
||||||
|
* @property {string} display_desc 视频格式描述
|
||||||
|
* @property {string} superscript 视频格式描述
|
||||||
|
* @property {unknown} codecs 视频编码
|
||||||
|
* @return UrlFormats
|
||||||
|
*/
|
||||||
|
interface UrlFormats {
|
||||||
|
quality: number;
|
||||||
|
format: string;
|
||||||
|
new_description: string;
|
||||||
|
display_desc: string;
|
||||||
|
superscript: string;
|
||||||
|
codecs: unknown;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ function getKeyVal(key: string): string {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 获取 mixin_key
|
* @description 获取 mixin_key
|
||||||
* @since Beta v0.4.0
|
* @since Beta v0.4.1
|
||||||
* @return {Promise<string>} mixin_key
|
* @return {Promise<string>} mixin_key
|
||||||
*/
|
*/
|
||||||
async function getMixinKey(): Promise<string> {
|
async function getMixinKey(): Promise<string> {
|
||||||
@@ -35,12 +35,8 @@ async function getMixinKey(): Promise<string> {
|
|||||||
];
|
];
|
||||||
const res = [];
|
const res = [];
|
||||||
for (const i of MIXIN_KEY_ENC_TAB) {
|
for (const i of MIXIN_KEY_ENC_TAB) {
|
||||||
if (key.length < i) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
res.push(key[i]);
|
res.push(key[i]);
|
||||||
}
|
}
|
||||||
// 截取 res 的前 32 位
|
|
||||||
return res.join("").slice(0, 32);
|
return res.join("").slice(0, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,33 +44,27 @@ async function getMixinKey(): Promise<string> {
|
|||||||
* @description 获取 wrid
|
* @description 获取 wrid
|
||||||
* @since Beta v0.4.1
|
* @since Beta v0.4.1
|
||||||
* @param {Record<string,string|number>} params 请求参数
|
* @param {Record<string,string|number>} params 请求参数
|
||||||
* @param {number} nts 时间戳(秒)
|
* @returns {Promise<[string|string]>} wrid
|
||||||
* @returns {Promise<string>} wrid
|
|
||||||
*/
|
*/
|
||||||
async function getWrid(
|
async function getWrid(params: Record<string, string | number>): Promise<[string, string]> {
|
||||||
params: Record<string, string | number>,
|
|
||||||
nts?: number,
|
|
||||||
): Promise<[number, string]> {
|
|
||||||
const mixin_key = await getMixinKey();
|
const mixin_key = await getMixinKey();
|
||||||
let wts: number;
|
const wts = Math.floor(Date.now() / 1000);
|
||||||
if (!nts) {
|
|
||||||
wts = Math.floor(Date.now() / 1000);
|
|
||||||
} else {
|
|
||||||
wts = nts;
|
|
||||||
}
|
|
||||||
const obj: Record<string, string | number> = {
|
const obj: Record<string, string | number> = {
|
||||||
...params,
|
...params,
|
||||||
wts,
|
wts,
|
||||||
};
|
};
|
||||||
const keys = Object.keys(obj).sort();
|
const keys = Object.keys(obj).sort();
|
||||||
let md5Str = "";
|
let md5Str = "";
|
||||||
for (const key of keys) {
|
for (let i = 0; i < keys.length; i++) {
|
||||||
md5Str += `${key}=${obj[key]}&`;
|
const key = keys[i];
|
||||||
|
if (i === keys.length - 1) {
|
||||||
|
md5Str += `${key}=${obj[key]}`;
|
||||||
|
} else {
|
||||||
|
md5Str += `${key}=${obj[key]}&`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
md5Str = md5Str.slice(0, -1);
|
const wrid = md5.md5(`${md5Str}${mixin_key}`);
|
||||||
md5Str += mixin_key;
|
return [wts.toString(), wrid];
|
||||||
const wrid = md5.md5(md5Str);
|
|
||||||
return [wts, wrid];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default getWrid;
|
export default getWrid;
|
||||||
|
|||||||
Reference in New Issue
Block a user