feat: 后端支持获取跳过片段

This commit is contained in:
lanyeeee
2025-09-01 06:44:47 +08:00
parent 387d50030d
commit f86c882d3d
6 changed files with 86 additions and 2 deletions
+37 -2
View File
@@ -29,8 +29,8 @@ use crate::{
get_fav_info_params::GetFavInfoParams, get_normal_info_params::GetNormalInfoParams,
get_user_video_info_params::GetUserVideoInfoParams, normal_info::NormalInfo,
normal_media_url::NormalMediaUrl, player_info::PlayerInfo, qrcode_data::QrcodeData,
qrcode_status::QrcodeStatus, subtitle::Subtitle, tags::Tags, user_info::UserInfo,
user_video_info::UserVideoInfo, watch_later_info::WatchLaterInfo,
qrcode_status::QrcodeStatus, skip_segments::SkipSegments, subtitle::Subtitle, tags::Tags,
user_info::UserInfo, user_video_info::UserVideoInfo, watch_later_info::WatchLaterInfo,
},
};
@@ -869,6 +869,41 @@ impl BiliClient {
Ok(tags)
}
pub async fn get_skip_segments(
&self,
bvid: &str,
cid: Option<i64>,
) -> anyhow::Result<SkipSegments> {
// 发送获取跳过片段的请求
let mut params = json!({
"videoID": bvid,
"actionType": "skip",
});
if let Some(cid) = cid {
params["cid"] = cid.into();
}
let request = self
.api_client
.read()
.get("https://bsbsb.top/api/skipSegments")
.query(&params);
let http_resp = request.send().await?;
// 检查http响应状态码
let status = http_resp.status();
let body = http_resp.text().await?;
if status == StatusCode::NOT_FOUND {
return Ok(SkipSegments(Vec::new()));
} else if status != StatusCode::OK {
return Err(anyhow!("预料之外的状态码({status}): {body}"));
}
// 尝试将body解析为SkipSegments
let skip_segments: SkipSegments =
serde_json::from_str(&body).context(format!("将body解析为SkipSegments失败: {body}"))?;
Ok(skip_segments)
}
pub fn get_cookie(&self) -> String {
let sessdata = self.app.get_config().read().sessdata.clone();
format!("SESSDATA={sessdata}")
+16
View File
@@ -28,6 +28,7 @@ use crate::{
BangumiSearchResult, CheeseSearchResult, FavSearchResult, NormalSearchResult,
SearchResult, UserVideoSearchResult,
},
skip_segments::SkipSegments,
user_info::UserInfo,
user_video_info::UserVideoInfo,
watch_later_info::WatchLaterInfo,
@@ -361,3 +362,18 @@ pub fn show_path_in_file_manager(app: AppHandle, path: &str) -> CommandResult<()
.map_err(|err| CommandError::from("在文件管理器中打开失败", err))?;
Ok(())
}
#[tauri::command(async)]
#[specta::specta]
pub async fn get_skip_segments(
app: AppHandle,
bvid: String,
cid: Option<i64>,
) -> CommandResult<SkipSegments> {
let bili_client = app.get_bili_client();
let skip_segments = bili_client
.get_skip_segments(&bvid, cid)
.await
.map_err(|err| CommandError::from("获取跳过片段失败", err))?;
Ok(skip_segments)
}
+1
View File
@@ -55,6 +55,7 @@ pub fn run() {
search,
get_logs_dir_size,
show_path_in_file_manager,
get_skip_segments,
])
.events(tauri_specta::collect_events![LogEvent, DownloadEvent]);
+1
View File
@@ -22,6 +22,7 @@ pub mod qrcode_data;
pub mod qrcode_status;
pub mod search_params;
pub mod search_result;
pub mod skip_segments;
pub mod subtitle;
pub mod tags;
pub mod user_info;
+21
View File
@@ -0,0 +1,21 @@
use serde::{Deserialize, Serialize};
use specta::Type;
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
pub struct SkipSegments(pub Vec<SkipSegment>);
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
pub struct SkipSegment {
pub cid: String,
pub category: String,
#[serde(rename = "actionType")]
pub action_type: String,
pub segment: Vec<f64>,
#[serde(rename = "UUID")]
pub uuid: String,
#[serde(rename = "videoDuration")]
pub video_duration: i64,
pub locked: i64,
pub votes: i64,
pub description: String,
}
+10
View File
@@ -142,6 +142,14 @@ async showPathInFileManager(path: string) : Promise<Result<null, CommandError>>
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async getSkipSegments(bvid: string, cid: number | null) : Promise<Result<SkipSegments, CommandError>> {
try {
return { status: "ok", data: await TAURI_INVOKE("get_skip_segments", { bvid, cid }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
}
}
@@ -357,6 +365,8 @@ export type SeriesInBangumi = { display_type: number; series_id: number; series_
export type SeriesInBangumiFollow = { series_id: number | null; title: string | null; season_count: number | null; new_season_id: number | null; series_ord: number | null }
export type Show = { wide_screen: number }
export type Skip = { ed: Ed; op: Op }
export type SkipSegment = { cid: string; category: string; actionType: string; segment: number[]; UUID: string; videoDuration: number; locked: number; votes: number; description: string }
export type SkipSegments = SkipSegment[]
export type Staff = { mid: number; title: string; name: string; face: string; follower: number; label_style: number }
export type StatInBangumi = { coins: number; danmakus: number; favorite: number; favorites: number; follow_text: string; likes: number; reply: number; share: number; views: number; vt: number }
export type StatInBangumiFollow = { follow: number; view: number; danmaku: number; reply: number; coin: number; series_follow: number | null; series_view: number | null; likes: number; favorite: number }