mirror of
https://github.com/lanyeeee/bilibili-video-downloader.git
synced 2026-09-05 07:27:42 +08:00
feat: 后端支持获取视频的画质和音质
This commit is contained in:
@@ -9,11 +9,13 @@ use crate::{
|
||||
extensions::AppHandleExt,
|
||||
logger,
|
||||
types::{
|
||||
available_media_formats::AvailableMediaFormats,
|
||||
bangumi_follow_info::BangumiFollowInfo,
|
||||
bangumi_info::{BangumiInfo, EpInBangumi},
|
||||
create_download_task_params::CreateDownloadTaskParams,
|
||||
fav_folders::FavFolders,
|
||||
fav_info::FavInfo,
|
||||
get_available_media_formats_params::GetAvailableMediaFormatsParams,
|
||||
get_bangumi_follow_info_params::GetBangumiFollowInfoParams,
|
||||
get_bangumi_info_params::GetBangumiInfoParams,
|
||||
get_cheese_info_params::GetCheeseInfoParams,
|
||||
@@ -402,3 +404,40 @@ pub async fn get_skip_segments(
|
||||
.map_err(|err| CommandError::from("获取跳过片段失败", err))?;
|
||||
Ok(skip_segments)
|
||||
}
|
||||
|
||||
#[tauri::command(async)]
|
||||
#[specta::specta]
|
||||
pub async fn get_available_media_formats(
|
||||
app: AppHandle,
|
||||
params: GetAvailableMediaFormatsParams,
|
||||
) -> CommandResult<AvailableMediaFormats> {
|
||||
let bili_client = app.get_bili_client();
|
||||
let result = match params {
|
||||
GetAvailableMediaFormatsParams::Normal(params) => {
|
||||
let media_url = bili_client
|
||||
.get_normal_url(¶ms.bvid, params.cid)
|
||||
.await
|
||||
.map_err(|err| CommandError::from("获取普通视频可用格式失败", err))?;
|
||||
|
||||
media_url.to_get_available_media_formats_result()
|
||||
}
|
||||
GetAvailableMediaFormatsParams::Bangumi(params) => {
|
||||
let media_url = bili_client
|
||||
.get_bangumi_url(params.cid)
|
||||
.await
|
||||
.map_err(|err| CommandError::from("获取番剧视频可用格式失败", err))?;
|
||||
|
||||
media_url.to_get_available_media_formats_result()
|
||||
}
|
||||
GetAvailableMediaFormatsParams::Cheese(params) => {
|
||||
let media_url = bili_client
|
||||
.get_cheese_url(params.ep_id)
|
||||
.await
|
||||
.map_err(|err| CommandError::from("获取课程视频可用格式失败", err))?;
|
||||
|
||||
media_url.to_get_available_media_formats_result()
|
||||
}
|
||||
};
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ pub fn run() {
|
||||
get_logs_dir_size,
|
||||
show_path_in_file_manager,
|
||||
get_skip_segments,
|
||||
get_available_media_formats,
|
||||
])
|
||||
.events(tauri_specta::collect_events![LogEvent, DownloadEvent]);
|
||||
|
||||
|
||||
@@ -22,10 +22,13 @@ pub enum AudioQuality {
|
||||
Unknown = -1,
|
||||
|
||||
#[serde(rename = "64K")]
|
||||
#[num_enum(alternatives = [100008])]
|
||||
Audio64K = 30216,
|
||||
#[serde(rename = "132K")]
|
||||
#[num_enum(alternatives = [100009])]
|
||||
Audio132K = 30232,
|
||||
#[serde(rename = "192K")]
|
||||
#[num_enum(alternatives = [100010])]
|
||||
Audio192K = 30280,
|
||||
#[serde(rename = "Dolby")]
|
||||
AudioDolby = 30250,
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specta::Type;
|
||||
|
||||
use crate::types::{
|
||||
audio_quality::AudioQuality, codec_type::CodecType, video_quality::VideoQuality,
|
||||
};
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
|
||||
pub struct AvailableMediaFormats {
|
||||
pub video_qualities_and_codec_types: Vec<VideoQualityAndCodecType>,
|
||||
pub audio_qualities: Vec<AudioQuality>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
|
||||
pub struct VideoQualityAndCodecType {
|
||||
pub video_quality: VideoQuality,
|
||||
pub codec_type: CodecType,
|
||||
}
|
||||
@@ -1,6 +1,11 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specta::Type;
|
||||
|
||||
use crate::types::{
|
||||
audio_quality::AudioQuality,
|
||||
available_media_formats::{AvailableMediaFormats, VideoQualityAndCodecType},
|
||||
};
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
|
||||
#[serde(default)]
|
||||
pub struct BangumiMediaUrl {
|
||||
@@ -130,3 +135,43 @@ pub struct DurlDetailInBangumi {
|
||||
pub order: i64,
|
||||
pub md5: String,
|
||||
}
|
||||
|
||||
impl BangumiMediaUrl {
|
||||
pub fn to_get_available_media_formats_result(&self) -> AvailableMediaFormats {
|
||||
let mut video_qualities_and_codec_types: Vec<VideoQualityAndCodecType> = Vec::new();
|
||||
let mut audio_qualities: Vec<AudioQuality> = Vec::new();
|
||||
|
||||
if let Some(dash) = &self.dash {
|
||||
for media in &dash.video {
|
||||
let video_qualities_and_codec_type = VideoQualityAndCodecType {
|
||||
video_quality: media.id.into(),
|
||||
codec_type: media.codecid.into(),
|
||||
};
|
||||
|
||||
video_qualities_and_codec_types.push(video_qualities_and_codec_type);
|
||||
}
|
||||
}
|
||||
|
||||
for durl in &self.durls {
|
||||
if !durl.durl.is_empty() {
|
||||
let video_qualities_and_codec_type = VideoQualityAndCodecType {
|
||||
video_quality: durl.quality.into(),
|
||||
codec_type: self.video_codecid.into(),
|
||||
};
|
||||
|
||||
video_qualities_and_codec_types.push(video_qualities_and_codec_type);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(medias) = self.dash.as_ref().and_then(|dash| dash.audio.as_ref()) {
|
||||
for media in medias {
|
||||
audio_qualities.push(media.id.into());
|
||||
}
|
||||
}
|
||||
|
||||
AvailableMediaFormats {
|
||||
video_qualities_and_codec_types,
|
||||
audio_qualities,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specta::Type;
|
||||
|
||||
use crate::types::{
|
||||
audio_quality::AudioQuality,
|
||||
available_media_formats::{AvailableMediaFormats, VideoQualityAndCodecType},
|
||||
};
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
|
||||
#[serde(default)]
|
||||
pub struct CheeseMediaUrl {
|
||||
@@ -122,3 +127,43 @@ pub struct DurlDetailInCheese {
|
||||
pub order: i64,
|
||||
pub md5: String,
|
||||
}
|
||||
|
||||
impl CheeseMediaUrl {
|
||||
pub fn to_get_available_media_formats_result(&self) -> AvailableMediaFormats {
|
||||
let mut video_qualities_and_codec_types: Vec<VideoQualityAndCodecType> = Vec::new();
|
||||
let mut audio_qualities: Vec<AudioQuality> = Vec::new();
|
||||
|
||||
if let Some(dash) = &self.dash {
|
||||
for media in &dash.video {
|
||||
let video_qualities_and_codec_type = VideoQualityAndCodecType {
|
||||
video_quality: media.id.into(),
|
||||
codec_type: media.codecid.into(),
|
||||
};
|
||||
|
||||
video_qualities_and_codec_types.push(video_qualities_and_codec_type);
|
||||
}
|
||||
}
|
||||
|
||||
for durl in &self.durls {
|
||||
if !durl.durl.is_empty() {
|
||||
let video_qualities_and_codec_type = VideoQualityAndCodecType {
|
||||
video_quality: durl.quality.into(),
|
||||
codec_type: self.video_codecid.into(),
|
||||
};
|
||||
|
||||
video_qualities_and_codec_types.push(video_qualities_and_codec_type);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(medias) = self.dash.as_ref().and_then(|dash| dash.audio.as_ref()) {
|
||||
for media in medias {
|
||||
audio_qualities.push(media.id.into());
|
||||
}
|
||||
}
|
||||
|
||||
AvailableMediaFormats {
|
||||
video_qualities_and_codec_types,
|
||||
audio_qualities,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specta::Type;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
|
||||
pub enum GetAvailableMediaFormatsParams {
|
||||
Normal(GetNormalAvailableMediaFormatsParams),
|
||||
Bangumi(GetBangumiAvailableMediaFormatsParams),
|
||||
Cheese(GetCheeseAvailableMediaFormatsParams),
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
|
||||
pub struct GetNormalAvailableMediaFormatsParams {
|
||||
pub bvid: String,
|
||||
pub cid: i64,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
|
||||
pub struct GetBangumiAvailableMediaFormatsParams {
|
||||
pub cid: i64,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
|
||||
pub struct GetCheeseAvailableMediaFormatsParams {
|
||||
pub ep_id: i64,
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
pub mod audio_quality;
|
||||
pub mod available_media_formats;
|
||||
pub mod bangumi_follow_info;
|
||||
pub mod bangumi_info;
|
||||
pub mod bangumi_media_url;
|
||||
@@ -8,6 +9,7 @@ pub mod codec_type;
|
||||
pub mod create_download_task_params;
|
||||
pub mod fav_folders;
|
||||
pub mod fav_info;
|
||||
pub mod get_available_media_formats_params;
|
||||
pub mod get_bangumi_follow_info_params;
|
||||
pub mod get_bangumi_info_params;
|
||||
pub mod get_cheese_info_params;
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specta::Type;
|
||||
|
||||
use crate::types::{
|
||||
audio_quality::AudioQuality,
|
||||
available_media_formats::{AvailableMediaFormats, VideoQualityAndCodecType},
|
||||
};
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
|
||||
#[serde(default)]
|
||||
pub struct NormalMediaUrl {
|
||||
@@ -103,3 +108,50 @@ pub struct SupportFormatInNormal {
|
||||
pub struct PlayConf {
|
||||
pub is_new_description: bool,
|
||||
}
|
||||
|
||||
impl NormalMediaUrl {
|
||||
pub fn to_get_available_media_formats_result(&self) -> AvailableMediaFormats {
|
||||
let mut video_qualities_and_codec_types: Vec<VideoQualityAndCodecType> = Vec::new();
|
||||
let mut audio_qualities: Vec<AudioQuality> = Vec::new();
|
||||
|
||||
for media in &self.dash.video {
|
||||
let video_qualities_and_codec = VideoQualityAndCodecType {
|
||||
video_quality: media.id.into(),
|
||||
codec_type: media.codecid.into(),
|
||||
};
|
||||
|
||||
video_qualities_and_codec_types.push(video_qualities_and_codec);
|
||||
}
|
||||
|
||||
if !self.durl.is_empty() {
|
||||
let video_qualities_and_codec = VideoQualityAndCodecType {
|
||||
video_quality: self.quality.into(),
|
||||
codec_type: self.video_codecid.into(),
|
||||
};
|
||||
|
||||
video_qualities_and_codec_types.push(video_qualities_and_codec);
|
||||
}
|
||||
|
||||
if let Some(medias) = &self.dash.audio {
|
||||
for media in medias {
|
||||
audio_qualities.push(media.id.into());
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(medias) = &self.dash.dolby.audio {
|
||||
for media in medias {
|
||||
audio_qualities.push(media.id.into());
|
||||
}
|
||||
}
|
||||
|
||||
let flac = self.dash.flac.as_ref();
|
||||
if let Some(media) = flac.and_then(|flac| flac.audio.as_ref()) {
|
||||
audio_qualities.push(media.id.into());
|
||||
}
|
||||
|
||||
AvailableMediaFormats {
|
||||
video_qualities_and_codec_types,
|
||||
audio_qualities,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user