feat: 后端支持获取番剧视频url

This commit is contained in:
lanyeeee
2025-07-17 05:09:12 +08:00
parent ec80b830ac
commit 87003c3715
6 changed files with 198 additions and 2 deletions
+44 -1
View File
@@ -15,7 +15,7 @@ use tauri::{
use crate::{
extensions::AppHandleExt,
types::{
bangumi_info::BangumiInfo, cheese_info::CheeseInfo,
bangumi_info::BangumiInfo, bangumi_media_url::BangumiMediaUrl, cheese_info::CheeseInfo,
get_bangumi_info_params::GetBangumiInfoParams, get_cheese_info_params::GetCheeseInfoParams,
get_normal_info_params::GetNormalInfoParams, normal_info::NormalInfo,
normal_media_url::NormalMediaUrl, qrcode_data::QrcodeData, qrcode_status::QrcodeStatus,
@@ -302,6 +302,49 @@ impl BiliClient {
Ok(media_url)
}
pub async fn get_bangumi_url(&self, cid: i64) -> anyhow::Result<BangumiMediaUrl> {
let params = json!({
"cid": cid,
"qn": 127,
"fnval": 4048,
});
// 发送获取番剧url的请求
let request = self
.api_client
.read()
.get("https://api.bilibili.com/pgc/player/web/playurl")
.query(&params)
.header("cookie", self.get_cookie());
let http_resp = request.send().await?;
// 检查http响应状态码
let status = http_resp.status();
let body = http_resp.text().await?;
if status != StatusCode::OK {
return Err(anyhow!("预料之外的状态码({status}): {body}"));
}
// 尝试将body解析为BiliResp
let bili_resp: BiliResp =
serde_json::from_str(&body).context(format!("将body解析为BiliResp失败: {body}"))?;
// 检查BiliResp的code字段
if bili_resp.code == -10403 {
return Err(anyhow!(
"地区限制,请使用代理或切换线路后重试: {bili_resp:?}"
));
} else if bili_resp.code != 0 {
return Err(anyhow!("预料之外的code: {bili_resp:?}"));
}
// 检查BiliResp的data是否存在
let Some(data) = bili_resp.data else {
return Err(anyhow!("BiliResp中不存在data字段: {bili_resp:?}"));
};
// 尝试将data解析为BangumiMediaUrl
let data_str = data.to_string();
let media_url: BangumiMediaUrl = serde_json::from_str(&data_str)
.context(format!("将data解析为BangumiMediaUrl失败: {data_str}"))?;
Ok(media_url)
}
fn get_cookie(&self) -> String {
let sessdata = self.app.get_config().read().sessdata.clone();
format!("SESSDATA={sessdata}")
+12 -1
View File
@@ -7,7 +7,7 @@ use crate::{
extensions::AppHandleExt,
logger,
types::{
bangumi_info::BangumiInfo, cheese_info::CheeseInfo,
bangumi_info::BangumiInfo, bangumi_media_url::BangumiMediaUrl, cheese_info::CheeseInfo,
get_bangumi_info_params::GetBangumiInfoParams, get_cheese_info_params::GetCheeseInfoParams,
get_normal_info_params::GetNormalInfoParams, normal_info::NormalInfo,
normal_media_url::NormalMediaUrl, qrcode_data::QrcodeData, qrcode_status::QrcodeStatus,
@@ -154,3 +154,14 @@ pub async fn get_normal_url(
.map_err(|err| CommandError::from("获取普通视频url失败", err))?;
Ok(media_url)
}
#[tauri::command(async)]
#[specta::specta]
pub async fn get_bangumi_url(app: AppHandle, cid: i64) -> CommandResult<BangumiMediaUrl> {
let bili_client = app.get_bili_client();
let media_url = bili_client
.get_bangumi_url(cid)
.await
.map_err(|err| CommandError::from("获取番剧视频url失败", err))?;
Ok(media_url)
}
+1
View File
@@ -34,6 +34,7 @@ pub fn run() {
get_bangumi_info,
get_cheese_info,
get_normal_url,
get_bangumi_url,
])
.events(tauri_specta::collect_events![LogEvent]);
+123
View File
@@ -0,0 +1,123 @@
use serde::{Deserialize, Serialize};
use specta::Type;
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
pub struct BangumiMediaUrl {
pub accept_format: String,
pub code: i64,
pub seek_param: String,
pub is_preview: i64,
pub fnval: i64,
pub video_project: bool,
pub fnver: i64,
#[serde(rename = "type")]
pub type_field: String,
pub bp: i64,
pub seek_type: String,
pub result: String,
pub vip_type: Option<i64>,
pub from: String,
pub video_codecid: i64,
pub record_info: Option<RecordInfo>,
pub is_drm: bool,
pub no_rexcode: i64,
pub format: String,
pub support_formats: Vec<SupportFormatInBangumi>,
pub message: String,
pub accept_quality: Vec<i64>,
pub quality: i64,
pub timelength: i64,
pub durls: Vec<DurlInBangumi>,
pub has_paid: bool,
pub vip_status: Option<i64>,
pub error_code: i64,
pub dash: Option<DashInBangumi>,
pub clip_info_list: Vec<ClipInfoList>,
pub accept_description: Vec<String>,
pub status: i64,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
pub struct RecordInfo {
pub record_icon: String,
pub record: String,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
pub struct SupportFormatInBangumi {
pub display_desc: String,
pub has_preview: bool,
pub sub_description: String,
pub superscript: String,
pub need_login: Option<bool>,
pub codecs: Vec<String>,
pub format: String,
pub description: String,
pub need_vip: Option<bool>,
pub attribute: i64,
pub quality: i64,
pub new_description: String,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
pub struct DashInBangumi {
pub duration: u64,
pub min_buffer_time: f64,
pub video: Vec<MediaInBangumi>,
pub audio: Option<Vec<MediaInBangumi>>,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
pub struct MediaInBangumi {
pub start_with_sap: i64,
pub bandwidth: i64,
pub sar: String,
pub backup_url: Vec<String>,
pub codecs: String,
pub base_url: String,
pub segment_base: SegmentBaseInBangumi,
pub mime_type: String,
pub frame_rate: String,
pub codecid: i64,
pub size: i64,
pub width: i64,
pub id: i64,
pub height: i64,
pub md5: String,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
pub struct SegmentBaseInBangumi {
pub initialization: String,
pub index_range: String,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
pub struct ClipInfoList {
#[serde(rename = "materialNo")]
pub material_no: i64,
pub start: i64,
pub end: i64,
#[serde(rename = "toastText")]
pub toast_text: String,
#[serde(rename = "clipType")]
pub clip_type: String,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
pub struct DurlInBangumi {
pub durl: Vec<DurlDetailInBangumi>,
pub quality: i64,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
pub struct DurlDetailInBangumi {
pub size: i64,
pub ahead: String,
pub length: i64,
pub vhead: String,
pub backup_url: Vec<String>,
pub url: String,
pub order: i64,
pub md5: String,
}
+1
View File
@@ -1,4 +1,5 @@
pub mod bangumi_info;
pub mod bangumi_media_url;
pub mod cheese_info;
pub mod get_bangumi_info_params;
pub mod get_cheese_info_params;