mirror of
https://github.com/lanyeeee/bilibili-video-downloader.git
synced 2026-09-06 08:07:26 +08:00
feat: 后端支持修改下载内容
This commit is contained in:
@@ -25,6 +25,7 @@ use crate::{
|
||||
normal_info::NormalInfo,
|
||||
qrcode_data::QrcodeData,
|
||||
qrcode_status::QrcodeStatus,
|
||||
restart_download_task_params::RestartDownloadTaskParams,
|
||||
search_params::SearchParams,
|
||||
search_result::{
|
||||
BangumiSearchResult, CheeseSearchResult, FavSearchResult, NormalSearchResult,
|
||||
@@ -267,6 +268,14 @@ pub fn restart_download_tasks(app: AppHandle, task_ids: Vec<String>) {
|
||||
download_manager.restart_download_tasks(&task_ids);
|
||||
}
|
||||
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
#[tauri::command(async)]
|
||||
#[specta::specta]
|
||||
pub fn restart_download_task(app: AppHandle, params: RestartDownloadTaskParams) {
|
||||
let download_manager = app.get_download_manager();
|
||||
download_manager.restart_download_task(¶ms);
|
||||
}
|
||||
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
#[tauri::command(async)]
|
||||
#[specta::specta]
|
||||
|
||||
@@ -17,7 +17,10 @@ use tokio::sync::Semaphore;
|
||||
use crate::{
|
||||
events::DownloadEvent,
|
||||
extensions::{AnyhowErrorToStringChain, AppHandleExt},
|
||||
types::create_download_task_params::CreateDownloadTaskParams,
|
||||
types::{
|
||||
create_download_task_params::CreateDownloadTaskParams,
|
||||
restart_download_task_params::RestartDownloadTaskParams,
|
||||
},
|
||||
};
|
||||
|
||||
use super::{
|
||||
@@ -182,6 +185,49 @@ impl DownloadManager {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn restart_download_task(&self, params: &RestartDownloadTaskParams) {
|
||||
let task_id = ¶ms.task_id;
|
||||
|
||||
let tasks = self.download_tasks.read();
|
||||
let Some(task) = tasks.get(task_id) else {
|
||||
let err_title = "重来下载任务失败";
|
||||
let err_msg = format!("未找到ID为`{task_id}`的下载任务");
|
||||
tracing::error!(err_title, message = err_msg);
|
||||
return;
|
||||
};
|
||||
|
||||
{
|
||||
let mut progress = task.progress.write();
|
||||
|
||||
progress.video_task.selected = params.video_task_selected;
|
||||
progress.audio_task.selected = params.audio_task_selected;
|
||||
progress.video_process_task.merge_selected = params.merge_selected;
|
||||
progress.video_process_task.embed_chapter_selected = params.embed_chapter_selected;
|
||||
progress.video_process_task.embed_skip_selected = params.embed_skip_selected;
|
||||
progress.subtitle_task.selected = params.subtitle_task_selected;
|
||||
progress.danmaku_task.xml_selected = params.xml_danmaku_selected;
|
||||
progress.danmaku_task.ass_selected = params.ass_danmaku_selected;
|
||||
progress.danmaku_task.json_selected = params.json_danmaku_selected;
|
||||
progress.cover_task.selected = params.cover_task_selected;
|
||||
progress.nfo_task.selected = params.nfo_task_selected;
|
||||
progress.json_task.selected = params.json_task_selected;
|
||||
|
||||
progress.video_task.video_quality = params.video_quality;
|
||||
progress.video_task.codec_type = params.codec_type;
|
||||
progress.audio_task.audio_quality = params.audio_quality;
|
||||
}
|
||||
|
||||
if let Err(err) = task.restart_sender.send(()).map_err(anyhow::Error::from) {
|
||||
let err_title = "重来下载任务失败";
|
||||
let err = err.context(format!("通知ID为`{task_id}`的下载任务重来失败"));
|
||||
let string_chain = err.to_string_chain();
|
||||
tracing::error!(err_title, message = string_chain);
|
||||
return;
|
||||
}
|
||||
|
||||
tracing::debug!("已通知ID为`{task_id}`的下载任务重来");
|
||||
}
|
||||
|
||||
async fn emit_download_speed_loop(app: AppHandle, byte_per_sec: Arc<AtomicU64>) {
|
||||
let mut interval = tokio::time::interval(Duration::from_secs(1));
|
||||
|
||||
|
||||
@@ -296,6 +296,7 @@ impl AudioTask {
|
||||
!self.selected || self.completed
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub async fn process(
|
||||
&self,
|
||||
download_task: &Arc<DownloadTask>,
|
||||
@@ -325,14 +326,19 @@ impl AudioTask {
|
||||
"{filename}.m4a.com.lanyeeee.bilibili-video-downloader"
|
||||
));
|
||||
|
||||
let file = if temp_file_path.exists() {
|
||||
// 如果文件已存在,则打开它
|
||||
let should_reuse_temp_file = temp_file_path
|
||||
.metadata()
|
||||
.map(|m| m.len() == audio_task.content_length)
|
||||
.unwrap_or(false);
|
||||
|
||||
let file = if should_reuse_temp_file {
|
||||
// 如果临时文件可以重用,则直接打开它
|
||||
OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.open(&temp_file_path)?
|
||||
} else {
|
||||
// 如果文件不存在,创建它并预分配空间
|
||||
// 如果临时文件不能重用,则创建个新的
|
||||
let file = File::create(&temp_file_path)?;
|
||||
file.allocate(audio_task.content_length)?;
|
||||
file
|
||||
|
||||
@@ -337,14 +337,19 @@ impl VideoTask {
|
||||
"{filename}.mp4.com.lanyeeee.bilibili-video-downloader"
|
||||
));
|
||||
|
||||
let file = if temp_file_path.exists() {
|
||||
// 如果临时文件已存在,则打开它
|
||||
let should_reuse_temp_file = temp_file_path
|
||||
.metadata()
|
||||
.map(|m| m.len() == video_task.content_length)
|
||||
.unwrap_or(false);
|
||||
|
||||
let file = if should_reuse_temp_file {
|
||||
// 如果临时文件可以重用,则直接打开它
|
||||
OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.open(&temp_file_path)?
|
||||
} else {
|
||||
// 如果临时文件不存在,创建它并预分配空间
|
||||
// 如果临时文件不能重用,则创建个新的
|
||||
let file = File::create(&temp_file_path)?;
|
||||
file.allocate(video_task.content_length)?;
|
||||
file
|
||||
|
||||
@@ -53,6 +53,7 @@ pub fn run() {
|
||||
resume_download_tasks,
|
||||
delete_download_tasks,
|
||||
restart_download_tasks,
|
||||
restart_download_task,
|
||||
restore_download_tasks,
|
||||
search,
|
||||
get_logs_dir_size,
|
||||
|
||||
@@ -22,6 +22,7 @@ pub mod normal_media_url;
|
||||
pub mod player_info;
|
||||
pub mod qrcode_data;
|
||||
pub mod qrcode_status;
|
||||
pub mod restart_download_task_params;
|
||||
pub mod search_params;
|
||||
pub mod search_result;
|
||||
pub mod skip_segments;
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
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)]
|
||||
#[serde(default)]
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
pub struct RestartDownloadTaskParams {
|
||||
pub task_id: String,
|
||||
|
||||
pub video_task_selected: bool,
|
||||
pub audio_task_selected: bool,
|
||||
pub merge_selected: bool,
|
||||
pub embed_chapter_selected: bool,
|
||||
pub embed_skip_selected: bool,
|
||||
pub subtitle_task_selected: bool,
|
||||
pub xml_danmaku_selected: bool,
|
||||
pub ass_danmaku_selected: bool,
|
||||
pub json_danmaku_selected: bool,
|
||||
pub cover_task_selected: bool,
|
||||
pub nfo_task_selected: bool,
|
||||
pub json_task_selected: bool,
|
||||
|
||||
pub video_quality: VideoQuality,
|
||||
pub codec_type: CodecType,
|
||||
pub audio_quality: AudioQuality,
|
||||
}
|
||||
@@ -119,6 +119,9 @@ async deleteDownloadTasks(taskIds: string[]) : Promise<void> {
|
||||
async restartDownloadTasks(taskIds: string[]) : Promise<void> {
|
||||
await TAURI_INVOKE("restart_download_tasks", { taskIds });
|
||||
},
|
||||
async restartDownloadTask(params: RestartDownloadTaskParams) : Promise<void> {
|
||||
await TAURI_INVOKE("restart_download_task", { params });
|
||||
},
|
||||
async restoreDownloadTasks() : Promise<Result<null, CommandError>> {
|
||||
try {
|
||||
return { status: "ok", data: await TAURI_INVOKE("restore_download_tasks") };
|
||||
@@ -359,6 +362,7 @@ export type QrcodeStatus = { url: string; refresh_token: string; timestamp: numb
|
||||
export type RatingInBangumi = { count: number; score: number }
|
||||
export type RatingInBangumiFollow = { score: number; count: number }
|
||||
export type RecommendSeason = { cover: string; ep_count: string; id: number; season_url: string; subtitle: string; title: string; view: number }
|
||||
export type RestartDownloadTaskParams = { task_id: string; video_task_selected: boolean; audio_task_selected: boolean; merge_selected: boolean; embed_chapter_selected: boolean; embed_skip_selected: boolean; subtitle_task_selected: boolean; xml_danmaku_selected: boolean; ass_danmaku_selected: boolean; json_danmaku_selected: boolean; cover_task_selected: boolean; nfo_task_selected: boolean; json_task_selected: boolean; video_quality: VideoQuality; codec_type: CodecType; audio_quality: AudioQuality }
|
||||
export type Rights = { bp: number; elec: number; download: number; movie: number; pay: number; hd5: number; no_reprint: number; autoplay: number; ugc_pay: number; is_cooperation: number; ugc_pay_preview: number; no_background: number; clean_mode: number; is_stein_gate: number; is_360: number; no_share: number; arc_pay: number; free_watch: number }
|
||||
export type RightsInBangumi = { allow_bp: number; allow_bp_rank: number; allow_download: number; allow_review: number; area_limit: number; ban_area_show: number; can_watch: number; copyright: string; forbid_pre: number; freya_white: number; is_cover_show: number; is_preview: number; only_vip_download: number; resource: string; watch_platform: number }
|
||||
export type RightsInBangumiEp = { allow_dm: number; allow_download: number; area_limit: number }
|
||||
|
||||
Reference in New Issue
Block a user