Skip to main content

bpi_rs/creativecenter/
videos.rs

1//! 创作中心视频管理 API
2//!
3//! [参考文档](https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/creativecenter/videos.md)
4
5use serde::{ Deserialize, Serialize };
6
7use crate::{ BilibiliRequest, BpiClient, BpiError, BpiResponse };
8
9/// 稿件统计信息
10#[derive(Debug, Serialize, Clone, Deserialize)]
11pub struct ArchiveStat {
12    pub aid: i64,
13    pub view: i64,
14    pub danmaku: i64,
15    pub reply: i64,
16    pub favorite: i64,
17    pub coin: i64,
18    pub share: i64,
19    pub now_rank: i64,
20    pub his_rank: i64,
21    pub like: i64,
22    pub dislike: i64,
23    pub vt: i64,
24    pub vv: i64,
25}
26
27/// 稿件基本信息
28#[derive(Debug, Serialize, Clone, Deserialize)]
29pub struct Archive {
30    pub aid: i64,
31    pub bvid: String,
32    pub title: String,
33    pub cover: String,
34    pub duration: i64,
35    pub desc: String,
36}
37
38/// 稿件列表项
39#[derive(Debug, Serialize, Clone, Deserialize)]
40pub struct ArcAudit {
41    #[serde(rename = "Archive")]
42    pub archive: Option<Archive>,
43    #[serde(rename = "Videos")]
44    pub videos: Option<serde_json::Value>,
45    pub stat: ArchiveStat,
46    pub state_panel: i64,
47    pub parent_tname: Option<String>,
48    pub typename: Option<String>,
49    pub open_appeal: i64,
50    pub activity: Option<serde_json::Value>,
51    pub season_add_state: i64,
52}
53
54/// 分页信息
55#[derive(Debug, Serialize, Clone, Deserialize)]
56pub struct PageInfo {
57    pub pn: i64,
58    pub ps: i64,
59    pub count: i64,
60}
61
62/// 稿件列表数据
63#[derive(Debug, Serialize, Clone, Deserialize)]
64pub struct SpArchivesData {
65    pub arc_audits: Vec<ArcAudit>,
66    pub page: PageInfo,
67    pub play_type: i64,
68}
69
70/// 分P 视频信息
71#[derive(Debug, Serialize, Clone, Deserialize)]
72pub struct VideoPart {
73    /// 分P cid
74    pub cid: i64,
75    /// 分P 序号
76    pub index: i64,
77    /// 分P 标题
78    pub title: String,
79    /// 视频时长(秒)
80    pub duration: i64,
81}
82
83/// 稿件信息
84#[derive(Debug, Serialize, Clone, Deserialize)]
85pub struct ArchiveInfo {
86    /// av号
87    pub aid: i64,
88    /// bvid
89    pub bvid: String,
90    /// 标题
91    pub title: String,
92}
93
94/// 视频基础信息数据
95#[derive(Debug, Serialize, Clone, Deserialize)]
96pub struct ArchiveVideosData {
97    /// 稿件信息
98    pub archive: ArchiveInfo,
99    /// 分P 视频列表
100    pub videos: Vec<VideoPart>,
101}
102
103impl BpiClient {
104    /// 获取稿件列表
105    ///
106    /// 获取 UP 主的稿件列表,支持分页查询。
107    ///
108    /// # 参数
109    /// | 名称 | 类型 | 说明 |
110    /// | ---- | ---- | ---- |
111    /// | `pn` | i64 | 页码 |
112    /// | `ps` | `Option<i64>` | 每页数量,可选 |
113    ///
114    /// # 文档
115    /// [获取稿件列表](https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/creativecenter/videos.md#获取稿件列表)
116    pub async fn up_archives_list(
117        &self,
118        pn: i64,
119        ps: Option<i64>
120    ) -> Result<BpiResponse<SpArchivesData>, BpiError> {
121        let mut req = self
122            .get("https://member.bilibili.com/x2/creative/web/archives/sp")
123            .query(&[("pn", pn)]);
124        if let Some(ps) = ps {
125            req = req.query(&[("ps", ps)]);
126        }
127        req.send_bpi("获取稿件列表").await
128    }
129
130    /// 获取视频基础信息
131    ///
132    /// 获取指定视频的基础信息,包括分P列表等。
133    ///
134    /// # 参数
135    /// | 名称 | 类型 | 说明 |
136    /// | ---- | ---- | ---- |
137    /// | `aid` | i64 | 视频 av 号 |
138    ///
139    /// # 文档
140    /// [获取视频基础信息](https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/creativecenter/videos.md#获取视频基础信息)
141    pub async fn up_archive_videos(
142        &self,
143        aid: i64
144    ) -> Result<BpiResponse<ArchiveVideosData>, BpiError> {
145        self
146            .get("https://member.bilibili.com/x/web/archive/videos")
147            .query(&[("aid", aid)])
148            .send_bpi("获取视频基础信息").await
149    }
150}
151
152#[cfg(test)]
153mod tests {
154    use super::*;
155    use tracing::info;
156
157    const TEST_AID: i64 = 113602455409683;
158
159    #[tokio::test]
160    async fn test_archives_list() -> Result<(), Box<BpiError>> {
161        let bpi = BpiClient::new();
162        let data = bpi.up_archives_list(1, Some(10)).await?.into_data()?;
163        info!("稿件列表: {:?}", data);
164        Ok(())
165    }
166
167    #[tokio::test]
168    async fn test_archive_videos() -> Result<(), Box<BpiError>> {
169        let bpi = BpiClient::new();
170        let data = bpi.up_archive_videos(TEST_AID).await?.into_data()?;
171        info!("视频基础信息: {:?}", data);
172        Ok(())
173    }
174}