mirror of
https://github.com/lanyeeee/bilibili-video-downloader.git
synced 2026-09-04 23:17:45 +08:00
feat: 给受版权保护(DRM)的视频添加提示,并跳过视频处理
This commit is contained in:
@@ -447,6 +447,7 @@ impl BiliClient {
|
||||
"ep_id": ep_id,
|
||||
"qn": 127,
|
||||
"fnval": 4048,
|
||||
"drm_tech_type": 2,
|
||||
});
|
||||
// 发送获取课程url的请求
|
||||
let request = self
|
||||
|
||||
@@ -66,6 +66,7 @@ pub struct DownloadProgress {
|
||||
pub json_task: JsonTask,
|
||||
pub create_ts: u64,
|
||||
pub completed_ts: Option<u64>,
|
||||
pub is_drm: bool,
|
||||
}
|
||||
|
||||
impl DownloadProgress {
|
||||
@@ -138,6 +139,7 @@ impl DownloadProgress {
|
||||
json_task: tasks.json,
|
||||
create_ts,
|
||||
completed_ts: None,
|
||||
is_drm: false,
|
||||
};
|
||||
|
||||
Ok(progress)
|
||||
@@ -185,6 +187,7 @@ impl DownloadProgress {
|
||||
json_task: tasks.json,
|
||||
create_ts,
|
||||
completed_ts: None,
|
||||
is_drm: false,
|
||||
};
|
||||
|
||||
Ok(progress)
|
||||
@@ -240,7 +243,16 @@ impl DownloadProgress {
|
||||
tracing::debug!("{ids_string} `{filename}`音频下载任务完成");
|
||||
}
|
||||
|
||||
if !video_process_task.is_completed() {
|
||||
let video_process_task_is_completed = video_process_task.is_completed();
|
||||
if self.is_drm && !video_process_task_is_completed {
|
||||
download_task.update_progress(|p| {
|
||||
p.video_process_task.skipped = true;
|
||||
p.video_process_task.completed = true;
|
||||
});
|
||||
tracing::debug!(
|
||||
"{ids_string} `{filename}`受版权保护(DRM),无法处理,已跳过视频处理任务"
|
||||
);
|
||||
} else if !video_process_task_is_completed {
|
||||
video_process_task
|
||||
.process(download_task, self, &mut player_info)
|
||||
.await
|
||||
@@ -359,6 +371,8 @@ impl DownloadProgress {
|
||||
.await
|
||||
.context("获取课程视频链接失败")?;
|
||||
|
||||
self.is_drm = media_url.is_drm;
|
||||
|
||||
if video_selected && !video_completed {
|
||||
// 如果视频被选中且未完成,则准备视频任务
|
||||
self.video_task.prepare_cheese(app, &media_url).await?;
|
||||
@@ -507,6 +521,7 @@ fn create_normal_progresses_for_single(
|
||||
json_task: tasks.json,
|
||||
create_ts,
|
||||
completed_ts: None,
|
||||
is_drm: false,
|
||||
};
|
||||
|
||||
return Ok(vec![progress]);
|
||||
@@ -543,6 +558,7 @@ fn create_normal_progresses_for_single(
|
||||
json_task: tasks.json,
|
||||
create_ts,
|
||||
completed_ts: None,
|
||||
is_drm: false,
|
||||
};
|
||||
|
||||
return Ok(vec![progress]);
|
||||
@@ -579,6 +595,7 @@ fn create_normal_progresses_for_single(
|
||||
json_task: tasks.json.clone(),
|
||||
create_ts,
|
||||
completed_ts: None,
|
||||
is_drm: false,
|
||||
};
|
||||
|
||||
progresses.push(progress);
|
||||
@@ -647,6 +664,7 @@ fn create_normal_progresses_for_season(
|
||||
json_task: tasks.json,
|
||||
create_ts,
|
||||
completed_ts: None,
|
||||
is_drm: false,
|
||||
};
|
||||
|
||||
return Ok(vec![progress]);
|
||||
@@ -683,6 +701,7 @@ fn create_normal_progresses_for_season(
|
||||
json_task: tasks.json,
|
||||
create_ts,
|
||||
completed_ts: None,
|
||||
is_drm: false,
|
||||
};
|
||||
|
||||
return Ok(vec![progress]);
|
||||
@@ -720,6 +739,7 @@ fn create_normal_progresses_for_season(
|
||||
json_task: tasks.json.clone(),
|
||||
create_ts,
|
||||
completed_ts: None,
|
||||
is_drm: false,
|
||||
};
|
||||
|
||||
progresses.push(progress);
|
||||
@@ -766,6 +786,7 @@ impl Tasks {
|
||||
embed_chapter_selected: config.embed_chapter,
|
||||
embed_skip_selected: config.embed_skip,
|
||||
completed: false,
|
||||
skipped: false,
|
||||
};
|
||||
|
||||
let danmaku = DanmakuTask {
|
||||
|
||||
@@ -24,11 +24,13 @@ pub struct VideoProcessTask {
|
||||
pub embed_chapter_selected: bool,
|
||||
pub embed_skip_selected: bool,
|
||||
pub completed: bool,
|
||||
pub skipped: bool,
|
||||
}
|
||||
|
||||
impl VideoProcessTask {
|
||||
pub fn mark_uncompleted(&mut self) {
|
||||
self.completed = false;
|
||||
self.skipped = false;
|
||||
}
|
||||
|
||||
pub fn is_completed(&self) -> bool {
|
||||
|
||||
@@ -23,6 +23,7 @@ pub struct CheeseMediaUrl {
|
||||
pub seek_type: String,
|
||||
pub from: String,
|
||||
pub video_codecid: i64,
|
||||
pub is_drm: bool,
|
||||
pub no_rexcode: i64,
|
||||
pub format: String,
|
||||
pub support_formats: Vec<SupportFormatInCheese>,
|
||||
|
||||
+2
-2
@@ -284,7 +284,7 @@ export type Dimension = { width: number; height: number; rotate: number }
|
||||
export type DimensionInBangumi = { height: number; rotate: number; width: number }
|
||||
export type DimensionInWatchLater = { width: number; height: number; rotate: number }
|
||||
export type DownloadEvent = { event: "Speed"; data: { speed: string } } | { event: "TaskCreate"; data: { state: DownloadTaskState; progress: DownloadProgress } } | { event: "TaskStateUpdate"; data: { task_id: string; state: DownloadTaskState } } | { event: "TaskSleeping"; data: { task_id: string; remaining_sec: number } } | { event: "TaskDelete"; data: { task_id: string } } | { event: "ProgressPreparing"; data: { task_id: string } } | { event: "ProgressUpdate"; data: { progress: DownloadProgress } }
|
||||
export type DownloadProgress = { task_id: string; episode_type: EpisodeType; aid: number; bvid: string | null; cid: number; ep_id: number | null; duration: number; pub_ts: number; collection_title: string; part_title: string | null; part_order: number | null; episode_title: string; episode_order: number; up_name: string | null; up_uid: number | null; up_avatar: string | null; episode_dir: string; filename: string; video_task: VideoTask; audio_task: AudioTask; video_process_task: VideoProcessTask; subtitle_task: SubtitleTask; danmaku_task: DanmakuTask; cover_task: CoverTask; nfo_task: NfoTask; json_task: JsonTask; create_ts: number; completed_ts: number | null }
|
||||
export type DownloadProgress = { task_id: string; episode_type: EpisodeType; aid: number; bvid: string | null; cid: number; ep_id: number | null; duration: number; pub_ts: number; collection_title: string; part_title: string | null; part_order: number | null; episode_title: string; episode_order: number; up_name: string | null; up_uid: number | null; up_avatar: string | null; episode_dir: string; filename: string; video_task: VideoTask; audio_task: AudioTask; video_process_task: VideoProcessTask; subtitle_task: SubtitleTask; danmaku_task: DanmakuTask; cover_task: CoverTask; nfo_task: NfoTask; json_task: JsonTask; create_ts: number; completed_ts: number | null; is_drm: boolean }
|
||||
export type DownloadTaskState = "Pending" | "Downloading" | "Paused" | "Completed" | "Failed"
|
||||
export type Ed = { end: number; start: number }
|
||||
export type EpInBangumi = { aid: number; badge: string; badge_info: BadgeInfoInBangumi; badge_type: number | null; bvid: string | null; cid: number; cover: string; dimension: DimensionInBangumi | null; duration: number | null; enable_vt: boolean; ep_id: number; from: string | null; id: number; is_view_hide: boolean; link: string; link_type: string | null; long_title: string | null; pub_time: number; pv: number; release_date: string | null; rights: RightsInBangumiEp | null; section_type: number; share_copy: string | null; share_url: string | null; short_link: string | null; showDrmLoginDialog: boolean; show_title: string | null; skip: Skip | null; status: number; subtitle: string | null; title: string; vid: string | null; icon_font: IconFont | null }
|
||||
@@ -420,7 +420,7 @@ export type UserStatusInCheese = { bp: number; expire_at: number; favored: numbe
|
||||
export type UserVideoInfo = { list: UserVideoList; page: PageInUserVideo }
|
||||
export type UserVideoList = { vlist: EpInUserVideo[] }
|
||||
export type UserVideoSearchResult = UserVideoInfo
|
||||
export type VideoProcessTask = { merge_selected: boolean; embed_chapter_selected: boolean; embed_skip_selected: boolean; completed: boolean }
|
||||
export type VideoProcessTask = { merge_selected: boolean; embed_chapter_selected: boolean; embed_skip_selected: boolean; completed: boolean; skipped: boolean }
|
||||
export type VideoQuality = "Unknown" | "240P" | "360P" | "480P" | "720P" | "720P60" | "1080P" | "AiRepair" | "1080P+" | "1080P60" | "4K" | "HDR" | "Dolby" | "8K"
|
||||
export type VideoQualityAndCodecType = { video_quality: VideoQuality; codec_type: CodecType }
|
||||
export type VideoTask = { selected: boolean; url: string; video_quality: VideoQuality; codec_type: CodecType; content_length: number; chunks: MediaChunk[]; completed: boolean; skipped: boolean }
|
||||
|
||||
@@ -149,12 +149,20 @@ function handleModifyClick() {
|
||||
@contextmenu="handleProgressContextMenu"
|
||||
@dblclick="handleProgressDoubleClick">
|
||||
<div class="flex">
|
||||
<img
|
||||
class="w-224px h-140px rounded-lg object-cover lazyload"
|
||||
:data-src="`${ensureHttps(p.cover_task.url)}@672w_378h_1c.webp`"
|
||||
:key="p.cover_task.url"
|
||||
alt=""
|
||||
draggable="false" />
|
||||
<div class="relative">
|
||||
<img
|
||||
class="w-224px h-140px rounded-lg object-cover lazyload"
|
||||
:data-src="`${ensureHttps(p.cover_task.url)}@672w_378h_1c.webp`"
|
||||
:key="p.cover_task.url"
|
||||
alt=""
|
||||
draggable="false" />
|
||||
<div
|
||||
v-if="p.is_drm"
|
||||
class="absolute top-3 left-3 z-1 bg-red-5 text-white px-1 rounded"
|
||||
title="该资源受版权保护(DRM)">
|
||||
🔒DRM
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ml-2 flex flex-col w-full overflow-hidden">
|
||||
<div class="text-lg font-bold line-clamp-2" :title="p.episode_title">{{ p.episode_title }}</div>
|
||||
@@ -187,9 +195,24 @@ function handleModifyClick() {
|
||||
</span>
|
||||
</ColorfulTag>
|
||||
|
||||
<ColorfulTag v-if="p.video_process_task.merge_selected" color="purple">自动合并</ColorfulTag>
|
||||
<ColorfulTag v-if="p.video_process_task.embed_chapter_selected" color="purple">标记章节</ColorfulTag>
|
||||
<ColorfulTag v-if="p.video_process_task.embed_skip_selected" color="purple">标记广告</ColorfulTag>
|
||||
<ColorfulTag v-if="p.video_process_task.merge_selected" color="purple">
|
||||
<span :class="{ 'text-gray': p.video_process_task.skipped }">
|
||||
<span>自动合并</span>
|
||||
<span v-if="p.video_process_task.skipped">(跳过)</span>
|
||||
</span>
|
||||
</ColorfulTag>
|
||||
<ColorfulTag v-if="p.video_process_task.embed_chapter_selected" color="purple">
|
||||
<span :class="{ 'text-gray': p.video_process_task.skipped }">
|
||||
<span>标记章节</span>
|
||||
<span v-if="p.video_process_task.skipped">(跳过)</span>
|
||||
</span>
|
||||
</ColorfulTag>
|
||||
<ColorfulTag v-if="p.video_process_task.embed_skip_selected" color="purple">
|
||||
<span :class="{ 'text-gray': p.video_process_task.skipped }">
|
||||
<span>标记广告</span>
|
||||
<span v-if="p.video_process_task.skipped">(跳过)</span>
|
||||
</span>
|
||||
</ColorfulTag>
|
||||
|
||||
<ColorfulTag v-if="p.danmaku_task.xml_selected" color="green">
|
||||
<span :class="{ 'text-gray': p.danmaku_task.skipped }">
|
||||
|
||||
Reference in New Issue
Block a user