use crate::{ BilibiliRequest, BpiClient, BpiError, BpiResponse };
use serde::{ Deserialize, Serialize };
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct AiSummaryPartOutline {
pub timestamp: u64,
pub content: String,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct AiSummaryOutline {
pub title: String,
pub part_outline: Vec<AiSummaryPartOutline>,
pub timestamp: u64,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct AiSummaryModelResult {
pub result_type: u8,
pub summary: String,
pub outline: Option<Vec<AiSummaryOutline>>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct AiSummaryResponseData {
pub code: i8,
pub model_result: Option<AiSummaryModelResult>,
pub stid: Option<String>,
pub status: Option<u8>,
pub like_num: u64,
pub dislike_num: u64,
}
impl BpiClient {
pub async fn video_ai_summary(
&self,
aid: Option<u64>,
bvid: Option<&str>,
cid: u64,
up_mid: u64
) -> Result<BpiResponse<AiSummaryResponseData>, BpiError> {
if aid.is_none() && bvid.is_none() {
return Err(BpiError::parse("必须提供 aid 或 bvid"));
}
let mut params = vec![("cid", cid.to_string()), ("up_mid", up_mid.to_string())];
if let Some(a) = aid {
params.push(("aid", a.to_string()));
}
if let Some(b) = bvid {
params.push(("bvid", b.to_string()));
}
let wbi_params = self.get_wbi_sign2(params).await?;
let req = self
.get("https://api.bilibili.com/x/web-interface/view/conclusion/get")
.query(&wbi_params);
req.send_bpi("获取视频 AI 总结内容").await
}
}
#[cfg(test)]
mod tests {
use super::*;
use tracing::info;
const TEST_AID: u64 = 10001;
const TEST_CID: u64 = 16546;
const TEST_UP_MID: u64 = 34893;
#[tokio::test]
async fn test_video_ai_summary_by_aid() -> Result<(), BpiError> {
let bpi = BpiClient::new();
let resp = bpi.video_ai_summary(Some(TEST_AID), None, TEST_CID, TEST_UP_MID).await?;
let data = resp.into_data()?;
info!("视频 AI 总结: {:?}", data);
if data.code == 0 {
assert!(data.model_result.is_some());
}
Ok(())
}
}