mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-13 09:28:14 +08:00
💩 尝试获取视频播放链接
This commit is contained in:
@@ -14,17 +14,30 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<TpVideo :data="mock" />
|
<!-- <TpVideo :data="mock" />-->
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import TpVideo from "../../components/post/tp-video.vue";
|
import { onMounted } from "vue";
|
||||||
|
|
||||||
|
import Bili from "../../plugins/Bili";
|
||||||
|
// import TpVideo from "../../components/post/TpVideo.vue";
|
||||||
|
|
||||||
const mock = {
|
const mock = {
|
||||||
insert: {
|
insert: {
|
||||||
// todo:数据也可能是 BV1qb4y1L7mD,缺乏数据来源
|
video: "https://player.bilibili.com/player.html?aid=540893019&autoplay=false&bvid=BV1ri4y1s7sY",
|
||||||
video: "https://www.bilibili.com/video/BV1qb4y1L7mD",
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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>
|
</script>
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
.test-box {
|
.test-box {
|
||||||
|
|||||||
@@ -4,11 +4,13 @@
|
|||||||
* @since Beta v0.4.0
|
* @since Beta v0.4.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import getVideoUrl from "./request/getVideoUrl";
|
||||||
import getVideoView from "./request/getVideoView";
|
import getVideoView from "./request/getVideoView";
|
||||||
|
|
||||||
const Bili = {
|
const Bili = {
|
||||||
video: {
|
video: {
|
||||||
view: getVideoView,
|
view: getVideoView,
|
||||||
|
url: getVideoUrl,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
21
src/plugins/Bili/request/getNav.ts
Normal file
21
src/plugins/Bili/request/getNav.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* @file plugins/Bili/request/getNav.ts
|
||||||
|
* @description Bili 插件导航请求文件
|
||||||
|
* @since Beta v0.4.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { http } from "@tauri-apps/api";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Bili 插件导航请求
|
||||||
|
* @since Beta v0.4.0
|
||||||
|
* @return {Promise<TGApp.Plugins.Bili.Nav.NavData>} Bili 插件导航请求返回
|
||||||
|
*/
|
||||||
|
async function getNav(): Promise<TGApp.Plugins.Bili.Nav.NavData> {
|
||||||
|
const url = "https://api.bilibili.com/x/web-interface/nav";
|
||||||
|
return await http.fetch<TGApp.Plugins.Bili.Nav.NavResponse>(url).then((res) => {
|
||||||
|
return res.data.data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default getNav;
|
||||||
57
src/plugins/Bili/request/getVideoUrl.ts
Normal file
57
src/plugins/Bili/request/getVideoUrl.ts
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
* @file plugins/Bili/request/getVideoUrl.ts
|
||||||
|
* @description Bili 插件视频请求文件
|
||||||
|
* @since Beta v0.4.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { http } from "@tauri-apps/api";
|
||||||
|
|
||||||
|
import getWrid from "../utils/getWrid";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取视频播放地址
|
||||||
|
* @since Beta v0.4.0
|
||||||
|
* @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 {number} cid 视频分P号
|
||||||
|
* @returns {Promise<string>} 视频播放地址
|
||||||
|
*/
|
||||||
|
async function getVideoUrl(cid: number, aid?: string, bvid?: string): Promise<unknown> {
|
||||||
|
const url = "https://api.bilibili.com/x/player/wbi/playurl";
|
||||||
|
let params: Record<string, string> = {
|
||||||
|
cid: cid.toString(),
|
||||||
|
platform: "html5",
|
||||||
|
high_quality: "1",
|
||||||
|
};
|
||||||
|
if (aid) {
|
||||||
|
params = {
|
||||||
|
aid,
|
||||||
|
...params,
|
||||||
|
};
|
||||||
|
} else if (bvid) {
|
||||||
|
params = {
|
||||||
|
bvid,
|
||||||
|
...params,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
throw new Error("参数错误");
|
||||||
|
}
|
||||||
|
const wrid = await getWrid(params);
|
||||||
|
params = {
|
||||||
|
...params,
|
||||||
|
wts: wrid[0].toString(),
|
||||||
|
wrid: wrid[1],
|
||||||
|
};
|
||||||
|
console.log("params", params);
|
||||||
|
return await http
|
||||||
|
.fetch<TGApp.Plugins.Bili.Video.UrlResponse>(url, {
|
||||||
|
method: "GET",
|
||||||
|
query: params,
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
return res.data.data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default getVideoUrl;
|
||||||
42
src/plugins/Bili/types/Nav.d.ts
vendored
Normal file
42
src/plugins/Bili/types/Nav.d.ts
vendored
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* @file plugins/Bili/types/Nav.d.ts
|
||||||
|
* @description Bili 插件导航类型定义文件
|
||||||
|
* @since Beta v0.4.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Bili 插件导航类型
|
||||||
|
* @since Beta v0.4.0
|
||||||
|
* @namespace Nav
|
||||||
|
* @memberof TGApp.Plugins.Bili
|
||||||
|
*/
|
||||||
|
declare namespace TGApp.Plugins.Bili.Nav {
|
||||||
|
/**
|
||||||
|
* @description Bili 导航基本信息返回
|
||||||
|
* @since Beta v0.4.0
|
||||||
|
* @interface NavResponse
|
||||||
|
* @extends {TGApp.Plugins.Bili.Base.Response}
|
||||||
|
* @property {NavData} data 导航基本信息
|
||||||
|
* @return NavResponse
|
||||||
|
*/
|
||||||
|
interface NavResponse extends TGApp.Plugins.Bili.Base.Response {
|
||||||
|
data: NavData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Bili 导航基本信息
|
||||||
|
* @since Beta v0.4.0
|
||||||
|
* @interface NavData
|
||||||
|
* @see https://api.bilibili.com/x/web-interface/nav
|
||||||
|
* @desc 只写了用到的部分
|
||||||
|
* @property {string} wbi_img.img_url 网站图标
|
||||||
|
* @property {string} wbi_img.sub_url 网站图标(小)
|
||||||
|
* @return NavData
|
||||||
|
*/
|
||||||
|
interface NavData {
|
||||||
|
wbi_img: {
|
||||||
|
img_url: string;
|
||||||
|
sub_url: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/plugins/Bili/types/Video.d.ts
vendored
15
src/plugins/Bili/types/Video.d.ts
vendored
@@ -94,6 +94,7 @@ declare namespace TGApp.Plugins.Bili.Video {
|
|||||||
videos: number;
|
videos: number;
|
||||||
tid: number;
|
tid: number;
|
||||||
tname: string;
|
tname: string;
|
||||||
|
copyright: number;
|
||||||
pic: string;
|
pic: string;
|
||||||
title: string;
|
title: string;
|
||||||
pubdate: string;
|
pubdate: string;
|
||||||
@@ -155,4 +156,18 @@ declare namespace TGApp.Plugins.Bili.Video {
|
|||||||
disable_show_up_info: boolean;
|
disable_show_up_info: boolean;
|
||||||
is_story_play: boolean;
|
is_story_play: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Bili 视频链接返回
|
||||||
|
* @since Beta v0.4.0
|
||||||
|
* @interface UrlResponse
|
||||||
|
* @extends {TGApp.Plugins.Bili.Base.Response}
|
||||||
|
* @property {UrlData} data 视频链接
|
||||||
|
* @return UrlResponse
|
||||||
|
*/
|
||||||
|
interface UrlResponse extends TGApp.Plugins.Bili.Base.Response {
|
||||||
|
data: UrlData;
|
||||||
|
}
|
||||||
|
|
||||||
|
type UrlData = unknown;
|
||||||
}
|
}
|
||||||
|
|||||||
80
src/plugins/Bili/utils/getWrid.ts
Normal file
80
src/plugins/Bili/utils/getWrid.ts
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
/**
|
||||||
|
* @file plugins/Bili/utils/getWrid.ts
|
||||||
|
* @description Bili 插件获取 wrid 工具函数
|
||||||
|
* @since Beta v0.4.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import md5 from "js-md5";
|
||||||
|
|
||||||
|
import getNav from "../request/getNav";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取 key 值
|
||||||
|
* @since Beta v0.4.0
|
||||||
|
* @param {string} key key 名称
|
||||||
|
* @return {string} key 值
|
||||||
|
*/
|
||||||
|
function getKeyVal(key: string): string {
|
||||||
|
return key.split("/").pop()?.split(".")[0] ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取 mixin_key
|
||||||
|
* @since Beta v0.4.0
|
||||||
|
* @return {Promise<string>} mixin_key
|
||||||
|
*/
|
||||||
|
async function getMixinKey(): Promise<string> {
|
||||||
|
const nav = await getNav();
|
||||||
|
const key1 = getKeyVal(nav.wbi_img.img_url);
|
||||||
|
const key2 = getKeyVal(nav.wbi_img.sub_url);
|
||||||
|
const key = key1 + key2;
|
||||||
|
const MIXIN_KEY_ENC_TAB = [
|
||||||
|
46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49, 33, 9, 42, 19, 29,
|
||||||
|
28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40, 61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25,
|
||||||
|
54, 21, 56, 59, 6, 63, 57, 62, 11, 36, 20, 34, 44, 52,
|
||||||
|
];
|
||||||
|
const res = [];
|
||||||
|
for (const i of MIXIN_KEY_ENC_TAB) {
|
||||||
|
if (key.length < i) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
res.push(key[i]);
|
||||||
|
}
|
||||||
|
// 截取 res 的前 32 位
|
||||||
|
return res.join("").slice(0, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取 wrid
|
||||||
|
* @since Beta v0.4.0
|
||||||
|
* @param {Record<string,string|number>} params 请求参数
|
||||||
|
* @param {number} nts 时间戳(秒)
|
||||||
|
* @returns {Promise<string>} wrid
|
||||||
|
*/
|
||||||
|
async function getWrid(
|
||||||
|
params: Record<string, string | number>,
|
||||||
|
nts?: number,
|
||||||
|
): Promise<[number, string]> {
|
||||||
|
const mixin_key = await getMixinKey();
|
||||||
|
let wts: number;
|
||||||
|
if (!nts) {
|
||||||
|
wts = Math.floor(Date.now() / 1000);
|
||||||
|
} else {
|
||||||
|
wts = nts;
|
||||||
|
}
|
||||||
|
const obj: Record<string, unknown> = {
|
||||||
|
...params,
|
||||||
|
wts,
|
||||||
|
};
|
||||||
|
const keys = Object.keys(obj).sort();
|
||||||
|
let md5Str = "";
|
||||||
|
for (const key of keys) {
|
||||||
|
md5Str += `${key}=${obj[key]}&`;
|
||||||
|
}
|
||||||
|
md5Str = md5Str.slice(0, -1);
|
||||||
|
md5Str += mixin_key;
|
||||||
|
const wrid = md5.md5(md5Str);
|
||||||
|
return [wts, wrid];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default getWrid;
|
||||||
Reference in New Issue
Block a user