mirror of
https://github.com/lanyeeee/bilibili-video-downloader.git
synced 2026-09-08 00:56:51 +08:00
refactor: 把处理DownloadProgress的逻辑移到其内部
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
use std::{
|
use std::{
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
|
sync::Arc,
|
||||||
time::{SystemTime, UNIX_EPOCH},
|
time::{SystemTime, UNIX_EPOCH},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -7,15 +8,20 @@ use anyhow::{anyhow, Context};
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use specta::Type;
|
use specta::Type;
|
||||||
use tauri::{AppHandle, Manager};
|
use tauri::{AppHandle, Manager};
|
||||||
|
use tauri_specta::Event;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::Config,
|
config::Config,
|
||||||
downloader::tasks::{
|
downloader::{
|
||||||
audio_task::AudioTask, cover_task::CoverTask, danmaku_task::DanmakuTask,
|
download_task::DownloadTask,
|
||||||
json_task::JsonTask, nfo_task::NfoTask, subtitle_task::SubtitleTask,
|
tasks::{
|
||||||
video_process_task::VideoProcessTask, video_task::VideoTask,
|
audio_task::AudioTask, cover_task::CoverTask, danmaku_task::DanmakuTask,
|
||||||
|
json_task::JsonTask, nfo_task::NfoTask, subtitle_task::SubtitleTask,
|
||||||
|
video_process_task::VideoProcessTask, video_task::VideoTask,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
events::DownloadEvent,
|
||||||
extensions::AppHandleExt,
|
extensions::AppHandleExt,
|
||||||
types::{
|
types::{
|
||||||
audio_quality::AudioQuality,
|
audio_quality::AudioQuality,
|
||||||
@@ -184,7 +190,116 @@ impl DownloadProgress {
|
|||||||
Ok(progress)
|
Ok(progress)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn prepare(&mut self, app: &AppHandle) -> anyhow::Result<()> {
|
pub async fn process(&mut self, download_task: &Arc<DownloadTask>) -> anyhow::Result<()> {
|
||||||
|
let ids_string = self.get_ids_string();
|
||||||
|
|
||||||
|
let _ = DownloadEvent::ProgressPreparing {
|
||||||
|
task_id: self.task_id.clone(),
|
||||||
|
}
|
||||||
|
.emit(&download_task.app);
|
||||||
|
|
||||||
|
self.prepare(&download_task.app)
|
||||||
|
.await
|
||||||
|
.context("准备下载失败")?;
|
||||||
|
|
||||||
|
self.completed_ts = None; // 重置完成时间戳
|
||||||
|
download_task.update_progress(|p| *p = self.clone());
|
||||||
|
|
||||||
|
let (episode_dir, filename) = (&self.episode_dir, &self.filename);
|
||||||
|
|
||||||
|
std::fs::create_dir_all(episode_dir).context(format!(
|
||||||
|
"{ids_string} 创建目录`{}`失败",
|
||||||
|
episode_dir.display()
|
||||||
|
))?;
|
||||||
|
|
||||||
|
let video_task = &self.video_task;
|
||||||
|
let audio_task = &self.audio_task;
|
||||||
|
let video_process_task = &self.video_process_task;
|
||||||
|
let danmaku_task = &self.danmaku_task;
|
||||||
|
let subtitle_task = &self.subtitle_task;
|
||||||
|
let cover_task = &self.cover_task;
|
||||||
|
let nfo_task = &self.nfo_task;
|
||||||
|
let json_task = &self.json_task;
|
||||||
|
|
||||||
|
let mut player_info = None;
|
||||||
|
let mut episode_info = None;
|
||||||
|
|
||||||
|
if !video_task.is_completed() && video_task.content_length != 0 {
|
||||||
|
video_task
|
||||||
|
.process(download_task, self)
|
||||||
|
.await
|
||||||
|
.context(format!("{ids_string} `{filename}`下载视频文件失败"))?;
|
||||||
|
tracing::debug!("{ids_string} `{filename}`视频下载任务完成");
|
||||||
|
}
|
||||||
|
|
||||||
|
if !audio_task.is_completed() && audio_task.content_length != 0 {
|
||||||
|
audio_task
|
||||||
|
.process(download_task, self)
|
||||||
|
.await
|
||||||
|
.context(format!("{ids_string} `{filename}`下载音频文件失败"))?;
|
||||||
|
tracing::debug!("{ids_string} `{filename}`音频下载任务完成");
|
||||||
|
}
|
||||||
|
|
||||||
|
if !video_process_task.is_completed() {
|
||||||
|
video_process_task
|
||||||
|
.process(download_task, self, &mut player_info)
|
||||||
|
.await
|
||||||
|
.context(format!("{ids_string} `{filename}`视频处理失败"))?;
|
||||||
|
tracing::debug!("{ids_string} `{filename}`视频处理任务完成");
|
||||||
|
}
|
||||||
|
|
||||||
|
if !danmaku_task.is_completed() {
|
||||||
|
danmaku_task
|
||||||
|
.process(download_task, self)
|
||||||
|
.await
|
||||||
|
.context(format!("{ids_string} `{filename}`下载弹幕失败"))?;
|
||||||
|
tracing::debug!("{ids_string} `{filename}`弹幕下载任务完成");
|
||||||
|
}
|
||||||
|
|
||||||
|
if !subtitle_task.is_completed() {
|
||||||
|
subtitle_task
|
||||||
|
.process(download_task, self, &mut player_info)
|
||||||
|
.await
|
||||||
|
.context(format!("{ids_string} `{filename}`下载字幕失败"))?;
|
||||||
|
tracing::debug!("{ids_string} `{filename}`字幕下载任务完成");
|
||||||
|
}
|
||||||
|
|
||||||
|
if !cover_task.is_completed() {
|
||||||
|
cover_task
|
||||||
|
.process(download_task, self)
|
||||||
|
.await
|
||||||
|
.context(format!("{ids_string} `{filename}`下载封面失败"))?;
|
||||||
|
tracing::debug!("{ids_string} `{filename}`封面下载任务完成");
|
||||||
|
}
|
||||||
|
|
||||||
|
if !nfo_task.is_completed() {
|
||||||
|
nfo_task
|
||||||
|
.process(download_task, self, &mut episode_info)
|
||||||
|
.await
|
||||||
|
.context(format!("{ids_string} `{filename}`下载NFO失败"))?;
|
||||||
|
tracing::debug!("{ids_string} `{filename}`NFO下载任务完成");
|
||||||
|
}
|
||||||
|
|
||||||
|
if !json_task.is_completed() {
|
||||||
|
json_task
|
||||||
|
.process(download_task, self, &mut episode_info)
|
||||||
|
.await
|
||||||
|
.context(format!("{ids_string} `{filename}`下载JSON元数据失败"))?;
|
||||||
|
tracing::debug!("{ids_string} `{filename}`JSON元数据下载任务完成");
|
||||||
|
}
|
||||||
|
|
||||||
|
let completed_ts = SystemTime::now()
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.map(|d| d.as_secs())
|
||||||
|
.ok();
|
||||||
|
if completed_ts.is_some() {
|
||||||
|
download_task.update_progress(|p| p.completed_ts = completed_ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn prepare(&mut self, app: &AppHandle) -> anyhow::Result<()> {
|
||||||
let video_selected = self.video_task.selected;
|
let video_selected = self.video_task.selected;
|
||||||
let video_completed = self.video_task.completed;
|
let video_completed = self.video_task.completed;
|
||||||
let audio_selected = self.audio_task.selected;
|
let audio_selected = self.audio_task.selected;
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
use std::{
|
use std::{sync::Arc, time::Duration};
|
||||||
sync::Arc,
|
|
||||||
time::{Duration, SystemTime, UNIX_EPOCH},
|
|
||||||
};
|
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
@@ -233,28 +230,9 @@ impl DownloadTask {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tracing::debug!("{ids_string} 开始准备`{episode_title}`的下载");
|
|
||||||
let _ = DownloadEvent::ProgressPreparing {
|
|
||||||
task_id: self.task_id.clone(),
|
|
||||||
}
|
|
||||||
.emit(&self.app);
|
|
||||||
|
|
||||||
if let Err(err) = progress.prepare(&self.app).await {
|
|
||||||
let err_title = format!("{ids_string} `{episode_title}`准备下载失败");
|
|
||||||
let string_chain = err.to_string_chain();
|
|
||||||
tracing::error!(err_title, message = string_chain);
|
|
||||||
|
|
||||||
self.set_state(DownloadTaskState::Failed);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
progress.completed_ts = None; // 重置完成时间戳
|
|
||||||
self.update_progress(|p| *p = progress.clone());
|
|
||||||
|
|
||||||
tracing::debug!("{ids_string} 开始下载`{episode_title}`");
|
tracing::debug!("{ids_string} 开始下载`{episode_title}`");
|
||||||
if let Err(err) = self
|
if let Err(err) = progress
|
||||||
.handle_progress(progress)
|
.process(self)
|
||||||
.await
|
.await
|
||||||
.context("[继续]失败的任务可以断点续传")
|
.context("[继续]失败的任务可以断点续传")
|
||||||
{
|
{
|
||||||
@@ -273,102 +251,6 @@ impl DownloadTask {
|
|||||||
tracing::info!("{ids_string} `{episode_title}`下载完成");
|
tracing::info!("{ids_string} `{episode_title}`下载完成");
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_progress(self: &Arc<Self>, progress: DownloadProgress) -> anyhow::Result<()> {
|
|
||||||
let ids_string = progress.get_ids_string();
|
|
||||||
let (episode_dir, filename) = (&progress.episode_dir, &progress.filename);
|
|
||||||
|
|
||||||
std::fs::create_dir_all(episode_dir).context(format!(
|
|
||||||
"{ids_string} 创建目录`{}`失败",
|
|
||||||
episode_dir.display()
|
|
||||||
))?;
|
|
||||||
|
|
||||||
let video_task = &progress.video_task;
|
|
||||||
let audio_task = &progress.audio_task;
|
|
||||||
let video_process_task = &progress.video_process_task;
|
|
||||||
let danmaku_task = &progress.danmaku_task;
|
|
||||||
let subtitle_task = &progress.subtitle_task;
|
|
||||||
let cover_task = &progress.cover_task;
|
|
||||||
let nfo_task = &progress.nfo_task;
|
|
||||||
let json_task = &progress.json_task;
|
|
||||||
|
|
||||||
let mut player_info = None;
|
|
||||||
let mut episode_info = None;
|
|
||||||
|
|
||||||
if !video_task.is_completed() && video_task.content_length != 0 {
|
|
||||||
video_task
|
|
||||||
.process(self, &progress)
|
|
||||||
.await
|
|
||||||
.context(format!("{ids_string} `{filename}`下载视频文件失败"))?;
|
|
||||||
tracing::debug!("{ids_string} `{filename}`视频下载任务完成");
|
|
||||||
}
|
|
||||||
|
|
||||||
if !audio_task.is_completed() && audio_task.content_length != 0 {
|
|
||||||
audio_task
|
|
||||||
.process(self, &progress)
|
|
||||||
.await
|
|
||||||
.context(format!("{ids_string} `{filename}`下载音频文件失败"))?;
|
|
||||||
tracing::debug!("{ids_string} `{filename}`音频下载任务完成");
|
|
||||||
}
|
|
||||||
|
|
||||||
if !video_process_task.is_completed() {
|
|
||||||
video_process_task
|
|
||||||
.process(self, &progress, &mut player_info)
|
|
||||||
.await
|
|
||||||
.context(format!("{ids_string} `{filename}`视频处理失败"))?;
|
|
||||||
tracing::debug!("{ids_string} `{filename}`视频处理任务完成");
|
|
||||||
}
|
|
||||||
|
|
||||||
if !danmaku_task.is_completed() {
|
|
||||||
danmaku_task
|
|
||||||
.process(self, &progress)
|
|
||||||
.await
|
|
||||||
.context(format!("{ids_string} `{filename}`下载弹幕失败"))?;
|
|
||||||
tracing::debug!("{ids_string} `{filename}`弹幕下载任务完成");
|
|
||||||
}
|
|
||||||
|
|
||||||
if !subtitle_task.is_completed() {
|
|
||||||
subtitle_task
|
|
||||||
.process(self, &progress, &mut player_info)
|
|
||||||
.await
|
|
||||||
.context(format!("{ids_string} `{filename}`下载字幕失败"))?;
|
|
||||||
tracing::debug!("{ids_string} `{filename}`字幕下载任务完成");
|
|
||||||
}
|
|
||||||
|
|
||||||
if !cover_task.is_completed() {
|
|
||||||
cover_task
|
|
||||||
.process(self, &progress)
|
|
||||||
.await
|
|
||||||
.context(format!("{ids_string} `{filename}`下载封面失败"))?;
|
|
||||||
tracing::debug!("{ids_string} `{filename}`封面下载任务完成");
|
|
||||||
}
|
|
||||||
|
|
||||||
if !nfo_task.is_completed() {
|
|
||||||
nfo_task
|
|
||||||
.process(self, &progress, &mut episode_info)
|
|
||||||
.await
|
|
||||||
.context(format!("{ids_string} `{filename}`下载NFO失败"))?;
|
|
||||||
tracing::debug!("{ids_string} `{filename}`NFO下载任务完成");
|
|
||||||
}
|
|
||||||
|
|
||||||
if !json_task.is_completed() {
|
|
||||||
json_task
|
|
||||||
.process(self, &progress, &mut episode_info)
|
|
||||||
.await
|
|
||||||
.context(format!("{ids_string} `{filename}`下载JSON元数据失败"))?;
|
|
||||||
tracing::debug!("{ids_string} `{filename}`JSON元数据下载任务完成");
|
|
||||||
}
|
|
||||||
|
|
||||||
let completed_ts = SystemTime::now()
|
|
||||||
.duration_since(UNIX_EPOCH)
|
|
||||||
.map(|d| d.as_secs())
|
|
||||||
.ok();
|
|
||||||
if completed_ts.is_some() {
|
|
||||||
self.update_progress(|p| p.completed_ts = completed_ts);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn sleep_between_task(&self) {
|
async fn sleep_between_task(&self) {
|
||||||
let task_id = &self.task_id;
|
let task_id = &self.task_id;
|
||||||
let mut remaining_sec = self.app.get_config().read().task_download_interval_sec;
|
let mut remaining_sec = self.app.get_config().read().task_download_interval_sec;
|
||||||
|
|||||||
Reference in New Issue
Block a user