bpi_rs/video/info/
pagelist.rs

1//! 查询视频分P列表 (avid/bvid 转 cid)
2//!
3//! 文档: https://github.com/SocialSisterYi/bilibili-API-collect/tree/master/docs/video
4//!
5//! 文档:https://socialsisteryi.github.io/bilibili-API-collect/docs/video/video.html#查询视频分p列表
6
7use crate::{ BilibiliRequest, BpiClient, BpiError, BpiResponse };
8use serde::{ Deserialize, Serialize };
9
10/// 分P分辨率信息
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct PageDimension {
13    /// 宽度
14    pub width: u32,
15    /// 高度
16    pub height: u32,
17    /// 是否将宽高对换,0: 正常,1: 对换
18    pub rotate: u8,
19}
20
21/// 分P信息
22#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct PageItem {
24    /// 当前分P cid
25    pub cid: u64,
26    /// 当前分P页码
27    pub page: u32,
28    /// 视频来源:vupload/芒果TV/腾讯
29    pub from: String,
30    /// 当前分P标题
31    pub part: String,
32    /// 当前分P持续时间(秒)
33    pub duration: u32,
34    /// 站外视频 vid
35    pub vid: String,
36    /// 站外跳转 URL
37    pub weblink: String,
38    /// 分辨率信息,部分视频可能不存在
39    pub dimension: Option<PageDimension>,
40    /// 分P封面
41    pub first_frame: Option<String>,
42
43    pub ctime: u64,
44}
45
46/// 分P列表响应
47type PageListResponse = BpiResponse<Vec<PageItem>>;
48impl BpiClient {
49    /// 查询视频分P列表 获取视频cid
50    ///
51    /// 文档: https://socialsisteryi.github.io/bilibili-API-collect/docs/video/video.html#查询视频分p列表
52    ///
53    /// # 参数
54    /// | 名称   | 类型         | 说明                 |
55    /// | ------ | ------------| -------------------- |
56    /// | `aid`  | Option<u64> | 稿件 avid,可选      |
57    /// | `bvid` | Option<&str>| 稿件 bvid,可选      |
58    ///
59    /// 两者任选一个
60    pub async fn video_pagelist(
61        &self,
62        aid: Option<u64>,
63        bvid: Option<&str>
64    ) -> Result<PageListResponse, BpiError> {
65        let aid = aid.map(|v| v.to_string());
66        let bvid = bvid.map(|v| v.to_string());
67        self
68            .get("https://api.bilibili.com/x/player/pagelist")
69            .query(
70                &[
71                    ("aid", aid),
72                    ("bvid", bvid),
73                ]
74            )
75            .send_bpi("查询视频分P列表").await
76    }
77}
78
79#[cfg(test)]
80mod tests {
81    use super::*;
82
83    #[tokio::test]
84    async fn test_video_pagelist() {
85        let bpi = BpiClient::new();
86
87        match bpi.video_pagelist(Some(10001), None).await {
88            Ok(resp) => {
89                if resp.code == 0 {
90                    for item in resp.data.unwrap() {
91                        tracing::info!(
92                            "P{}: {}, cid={}, duration={}秒",
93                            item.page,
94                            item.part,
95                            item.cid,
96                            item.duration
97                        );
98                        if let Some(dim) = item.dimension {
99                            tracing::info!(
100                                "分辨率: {}x{}, rotate={}",
101                                dim.width,
102                                dim.height,
103                                dim.rotate
104                            );
105                        }
106                    }
107                } else {
108                    tracing::info!("请求失败: code={}, message={}", resp.code, resp.message);
109                }
110            }
111            Err(err) => {
112                panic!("请求出错: {}", err);
113            }
114        }
115    }
116}