Skip to main content

bpi_rs/video/info/
pagelist.rs

1//! 查询视频分P列表 (avid/bvid 转 cid)
2//!
3//! [查看 API 文档](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    /// # 文档
52    /// [查看API文档](https://socialsisteryi.github.io/bilibili-API-collect/docs/video/video.html#查询视频分p列表)
53    ///
54    /// # 参数
55    /// | 名称   | 类型         | 说明                 |
56    /// | ------ | ------------| -------------------- |
57    /// | `aid`  | `Option<u64>` | 稿件 avid,可选      |
58    /// | `bvid` | `Option<&str>`| 稿件 bvid,可选      |
59    ///
60    /// 两者任选一个
61    pub async fn video_pagelist(
62        &self,
63        aid: Option<u64>,
64        bvid: Option<&str>
65    ) -> Result<PageListResponse, BpiError> {
66        let aid = aid.map(|v| v.to_string());
67        let bvid = bvid.map(|v| v.to_string());
68        self
69            .get("https://api.bilibili.com/x/player/pagelist")
70            .query(
71                &[
72                    ("aid", aid),
73                    ("bvid", bvid),
74                ]
75            )
76            .send_bpi("查询视频分P列表").await
77    }
78}
79
80#[cfg(test)]
81mod tests {
82    use super::*;
83
84    #[tokio::test]
85    async fn test_video_pagelist() {
86        let bpi = BpiClient::new();
87
88        match bpi.video_pagelist(Some(10001), None).await {
89            Ok(resp) => {
90                if resp.code == 0 {
91                    for item in resp.data.unwrap() {
92                        tracing::info!(
93                            "P{}: {}, cid={}, duration={}秒",
94                            item.page,
95                            item.part,
96                            item.cid,
97                            item.duration
98                        );
99                        if let Some(dim) = item.dimension {
100                            tracing::info!(
101                                "分辨率: {}x{}, rotate={}",
102                                dim.width,
103                                dim.height,
104                                dim.rotate
105                            );
106                        }
107                    }
108                } else {
109                    tracing::info!("请求失败: code={}, message={}", resp.code, resp.message);
110                }
111            }
112            Err(err) => {
113                panic!("请求出错: {}", err);
114            }
115        }
116    }
117}