style: 将最大行宽设置为 120

This commit is contained in:
amtoaer
2024-03-30 01:52:16 +08:00
parent fadb122ec8
commit 89a76fcd52
11 changed files with 67 additions and 223 deletions

View File

@@ -102,10 +102,7 @@ impl Stream {
/// 2. 视频、音频分离,作为 VideoAudio 返回,其中音频流可能不存在(对于无声视频,如 BV1J7411H7KQ
#[derive(Debug)]
pub enum BestStream {
VideoAudio {
video: Stream,
audio: Option<Stream>,
},
VideoAudio { video: Stream, audio: Option<Stream> },
Mixed(Stream),
}
@@ -158,12 +155,10 @@ impl PageAnalyzer {
let dolby_data = self.info["dash"]["dolby"].take();
for video_data in videos_data.as_array().unwrap().iter() {
let video_stream_url = video_data["baseUrl"].as_str().unwrap().to_string();
let video_stream_quality =
VideoQuality::from_repr(video_data["id"].as_u64().unwrap() as usize)
.ok_or("invalid video stream quality")?;
let video_stream_quality = VideoQuality::from_repr(video_data["id"].as_u64().unwrap() as usize)
.ok_or("invalid video stream quality")?;
if (video_stream_quality == VideoQuality::QualityHdr && filter_option.no_hdr)
|| (video_stream_quality == VideoQuality::QualityDolby
&& filter_option.no_dolby_video)
|| (video_stream_quality == VideoQuality::QualityDolby && filter_option.no_dolby_video)
|| (video_stream_quality != VideoQuality::QualityDolby
&& video_stream_quality != VideoQuality::QualityHdr
&& (video_stream_quality < filter_option.video_min_quality
@@ -197,8 +192,7 @@ impl PageAnalyzer {
if audios_data.is_array() {
for audio_data in audios_data.as_array().unwrap().iter() {
let audio_stream_url = audio_data["baseUrl"].as_str().unwrap().to_string();
let audio_stream_quality =
AudioQuality::from_repr(audio_data["id"].as_u64().unwrap() as usize);
let audio_stream_quality = AudioQuality::from_repr(audio_data["id"].as_u64().unwrap() as usize);
let Some(audio_stream_quality) = audio_stream_quality else {
continue;
};
@@ -217,8 +211,7 @@ impl PageAnalyzer {
// 允许 hires 且存在 flac 音频流才会进来
let flac_stream_url = flac_data["audio"]["baseUrl"].as_str().unwrap().to_string();
let flac_stream_quality =
AudioQuality::from_repr(flac_data["audio"]["id"].as_u64().unwrap() as usize)
.unwrap();
AudioQuality::from_repr(flac_data["audio"]["id"].as_u64().unwrap() as usize).unwrap();
streams.push(Stream::DashAudio {
url: flac_stream_url,
quality: flac_stream_quality,
@@ -231,8 +224,7 @@ impl PageAnalyzer {
let dolby_stream_data = dolby_stream_data.unwrap();
let dolby_stream_url = dolby_stream_data["baseUrl"].as_str().unwrap().to_string();
let dolby_stream_quality =
AudioQuality::from_repr(dolby_stream_data["id"].as_u64().unwrap() as usize)
.unwrap();
AudioQuality::from_repr(dolby_stream_data["id"].as_u64().unwrap() as usize).unwrap();
streams.push(Stream::DashAudio {
url: dolby_stream_url,
quality: dolby_stream_quality,
@@ -249,9 +241,8 @@ impl PageAnalyzer {
return Ok(BestStream::Mixed(streams.into_iter().next().unwrap()));
}
// 将视频流和音频流拆分,分别做排序
let (mut video_streams, mut audio_streams): (Vec<_>, Vec<_>) = streams
.into_iter()
.partition(|s| matches!(s, Stream::DashVideo { .. }));
let (mut video_streams, mut audio_streams): (Vec<_>, Vec<_>) =
streams.into_iter().partition(|s| matches!(s, Stream::DashVideo { .. }));
// 因为该处的排序与筛选选项有关,因此不能在外面实现 PartialOrd trait只能在这里写闭包
video_streams.sort_by(|a, b| match (a, b) {
(
@@ -291,14 +282,7 @@ impl PageAnalyzer {
_ => unreachable!(),
});
audio_streams.sort_by(|a, b| match (a, b) {
(
Stream::DashAudio {
quality: a_quality, ..
},
Stream::DashAudio {
quality: b_quality, ..
},
) => {
(Stream::DashAudio { quality: a_quality, .. }, Stream::DashAudio { quality: b_quality, .. }) => {
if a_quality == &AudioQuality::QualityDolby && !filter_option.no_dolby_audio {
return std::cmp::Ordering::Greater;
}

View File

@@ -11,27 +11,20 @@ impl Client {
// 正常访问 api 所必须的 header作为默认 header 添加到每个请求中
let mut headers = header::HeaderMap::new();
headers.insert(
header::USER_AGENT,
header::HeaderValue::from_static("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.54"));
header::USER_AGENT,
header::HeaderValue::from_static(
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.54",
),
);
headers.insert(
header::REFERER,
header::HeaderValue::from_static("https://www.bilibili.com"),
);
Self(
reqwest::Client::builder()
.default_headers(headers)
.build()
.unwrap(),
)
Self(reqwest::Client::builder().default_headers(headers).build().unwrap())
}
// a wrapper of reqwest::Client::request to add credential to the request
pub fn request(
&self,
method: Method,
url: &str,
credential: Option<&Credential>,
) -> reqwest::RequestBuilder {
pub fn request(&self, method: Method, url: &str, credential: Option<&Credential>) -> reqwest::RequestBuilder {
let mut req = self.0.request(method, url);
// 如果有 credential会将其转换成 cookie 添加到请求的 header 中
if let Some(credential) = credential {
@@ -39,14 +32,8 @@ impl Client {
.header(header::COOKIE, format!("SESSDATA={}", credential.sessdata))
.header(header::COOKIE, format!("bili_jct={}", credential.bili_jct))
.header(header::COOKIE, format!("buvid3={}", credential.buvid3))
.header(
header::COOKIE,
format!("DedeUserID={}", credential.dedeuserid),
)
.header(
header::COOKIE,
format!("ac_time_value={}", credential.ac_time_value),
);
.header(header::COOKIE, format!("DedeUserID={}", credential.dedeuserid))
.header(header::COOKIE, format!("ac_time_value={}", credential.ac_time_value));
}
req
}

View File

@@ -21,13 +21,7 @@ pub struct Credential {
}
impl Credential {
pub fn new(
sessdata: String,
bili_jct: String,
buvid3: String,
dedeuserid: String,
ac_time_value: String,
) -> Self {
pub fn new(sessdata: String, bili_jct: String, buvid3: String, dedeuserid: String, ac_time_value: String) -> Self {
Self {
sessdata,
bili_jct,
@@ -49,9 +43,7 @@ impl Credential {
.await?
.json::<serde_json::Value>()
.await?;
res["refresh"]
.as_bool()
.ok_or("check refresh failed".into())
res["refresh"].as_bool().ok_or("check refresh failed".into())
}
pub async fn refresh(&mut self, client: &Client) -> Result<()> {
@@ -74,10 +66,7 @@ impl Credential {
-----END PUBLIC KEY-----",
)
.unwrap();
let ts = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_millis();
let ts = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis();
let data = format!("refresh_{}", ts).into_bytes();
let mut rng = rand::rngs::OsRng;
let encrypted = key.encrypt(&mut rng, Oaep::new::<Sha256>(), &data).unwrap();
@@ -100,10 +89,7 @@ impl Credential {
_ => Err("get csrf failed".into()),
};
}
regex_find(
r#"<div id="1-name">(.+?)</div>"#,
res.text().await?.as_str(),
)
regex_find(r#"<div id="1-name">(.+?)</div>"#, res.text().await?.as_str())
}
async fn get_new_credential(&self, client: &Client, csrf: &str) -> Result<Credential> {
@@ -134,10 +120,7 @@ impl Credential {
};
let required_cookies = HashSet::from(["SESSDATA", "bili_jct", "DedeUserID"]);
let cookies: Vec<Cookie> = Cookie::split_parse_encoded(set_cookie)
.filter(|x| {
x.as_ref()
.is_ok_and(|x| required_cookies.contains(x.name()))
})
.filter(|x| x.as_ref().is_ok_and(|x| required_cookies.contains(x.name())))
.map(|x| x.unwrap())
.collect();
if cookies.len() != required_cookies.len() {

View File

@@ -49,10 +49,7 @@ impl<'a> FavoriteList<'a> {
pub async fn get_info(&self) -> Result<FavoriteListInfo> {
let mut res = self
.client
.request(
reqwest::Method::GET,
"https://api.bilibili.com/x/v3/fav/folder/info",
)
.request(reqwest::Method::GET, "https://api.bilibili.com/x/v3/fav/folder/info")
.query(&[("media_id", &self.fid)])
.send()
.await?
@@ -64,10 +61,7 @@ impl<'a> FavoriteList<'a> {
async fn get_videos(&self, page: u32) -> Result<Value> {
let res = self
.client
.request(
reqwest::Method::GET,
"https://api.bilibili.com/x/v3/fav/resource/list",
)
.request(reqwest::Method::GET, "https://api.bilibili.com/x/v3/fav/resource/list")
.query(&[
("media_id", self.fid.as_str()),
("pn", &page.to_string()),

View File

@@ -4,9 +4,7 @@ mod credential;
mod favorite_list;
mod video;
pub use analyzer::{
AudioQuality, BestStream, FilterOption, PageAnalyzer, VideoCodecs, VideoQuality,
};
pub use analyzer::{AudioQuality, BestStream, FilterOption, PageAnalyzer, VideoCodecs, VideoQuality};
pub use client::{BiliClient, Client};
pub use credential::Credential;
pub use favorite_list::{FavoriteList, FavoriteListInfo, VideoInfo};

View File

@@ -8,10 +8,9 @@ static MASK_CODE: u64 = 2251799813685247;
static XOR_CODE: u64 = 23442827791579;
static BASE: u64 = 58;
static DATA: &[char] = &[
'F', 'c', 'w', 'A', 'P', 'N', 'K', 'T', 'M', 'u', 'g', '3', 'G', 'V', '5', 'L', 'j', '7', 'E',
'J', 'n', 'H', 'p', 'W', 's', 'x', '4', 't', 'b', '8', 'h', 'a', 'Y', 'e', 'v', 'i', 'q', 'B',
'z', '6', 'r', 'k', 'C', 'y', '1', '2', 'm', 'U', 'S', 'D', 'Q', 'X', '9', 'R', 'd', 'o', 'Z',
'f',
'F', 'c', 'w', 'A', 'P', 'N', 'K', 'T', 'M', 'u', 'g', '3', 'G', 'V', '5', 'L', 'j', '7', 'E', 'J', 'n', 'H', 'p',
'W', 's', 'x', '4', 't', 'b', '8', 'h', 'a', 'Y', 'e', 'v', 'i', 'q', 'B', 'z', '6', 'r', 'k', 'C', 'y', '1', '2',
'm', 'U', 'S', 'D', 'Q', 'X', '9', 'R', 'd', 'o', 'Z', 'f',
];
pub struct Video<'a> {
@@ -64,10 +63,7 @@ impl<'a> Video<'a> {
pub async fn get_tags(&self) -> Result<Vec<Tag>> {
let mut res = self
.client
.request(
Method::GET,
"https://api.bilibili.com/x/web-interface/view/detail/tag",
)
.request(Method::GET, "https://api.bilibili.com/x/web-interface/view/detail/tag")
.query(&[("aid", &self.aid), ("bvid", &self.bvid)])
.send()
.await?