use crate::{ BilibiliRequest, BpiClient, BpiError, BpiResponse };
use serde::{ Deserialize, Serialize };
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PageDimension {
pub width: u32,
pub height: u32,
pub rotate: u8,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PageItem {
pub cid: u64,
pub page: u32,
pub from: String,
pub part: String,
pub duration: u32,
pub vid: String,
pub weblink: String,
pub dimension: Option<PageDimension>,
pub first_frame: Option<String>,
pub ctime: u64,
}
type PageListResponse = BpiResponse<Vec<PageItem>>;
impl BpiClient {
pub async fn video_pagelist(
&self,
aid: Option<u64>,
bvid: Option<&str>
) -> Result<PageListResponse, BpiError> {
let aid = aid.map(|v| v.to_string());
let bvid = bvid.map(|v| v.to_string());
self
.get("https://api.bilibili.com/x/player/pagelist")
.query(
&[
("aid", aid),
("bvid", bvid),
]
)
.send_bpi("查询视频分P列表").await
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_video_pagelist() {
let bpi = BpiClient::new();
match bpi.video_pagelist(Some(10001), None).await {
Ok(resp) => {
if resp.code == 0 {
for item in resp.data.unwrap() {
tracing::info!(
"P{}: {}, cid={}, duration={}秒",
item.page,
item.part,
item.cid,
item.duration
);
if let Some(dim) = item.dimension {
tracing::info!(
"分辨率: {}x{}, rotate={}",
dim.width,
dim.height,
dim.rotate
);
}
}
} else {
tracing::info!("请求失败: code={}, message={}", resp.code, resp.message);
}
}
Err(err) => {
panic!("请求出错: {}", err);
}
}
}
}