aboutsummaryrefslogtreecommitdiffstats
path: root/hypervideo_dl/postprocessor/modify_chapters.py
diff options
context:
space:
mode:
Diffstat (limited to 'hypervideo_dl/postprocessor/modify_chapters.py')
-rw-r--r--hypervideo_dl/postprocessor/modify_chapters.py22
1 files changed, 13 insertions, 9 deletions
diff --git a/hypervideo_dl/postprocessor/modify_chapters.py b/hypervideo_dl/postprocessor/modify_chapters.py
index a0818c4..22506bc 100644
--- a/hypervideo_dl/postprocessor/modify_chapters.py
+++ b/hypervideo_dl/postprocessor/modify_chapters.py
@@ -24,19 +24,21 @@ class ModifyChaptersPP(FFmpegPostProcessor):
*, sponsorblock_chapter_title=DEFAULT_SPONSORBLOCK_CHAPTER_TITLE, force_keyframes=False):
FFmpegPostProcessor.__init__(self, downloader)
self._remove_chapters_patterns = set(remove_chapters_patterns or [])
- self._remove_sponsor_segments = set(remove_sponsor_segments or [])
+ self._remove_sponsor_segments = set(remove_sponsor_segments or []) - set(SponsorBlockPP.POI_CATEGORIES.keys())
self._ranges_to_remove = set(remove_ranges or [])
self._sponsorblock_chapter_title = sponsorblock_chapter_title
self._force_keyframes = force_keyframes
@PostProcessor._restrict_to(images=False)
def run(self, info):
+ # Chapters must be preserved intact when downloading multiple formats of the same video.
chapters, sponsor_chapters = self._mark_chapters_to_remove(
- info.get('chapters') or [], info.get('sponsorblock_chapters') or [])
+ copy.deepcopy(info.get('chapters')) or [],
+ copy.deepcopy(info.get('sponsorblock_chapters')) or [])
if not chapters and not sponsor_chapters:
return [], info
- real_duration = self._get_real_video_duration(info)
+ real_duration = self._get_real_video_duration(info['filepath'])
if not chapters:
chapters = [{'start_time': 0, 'end_time': real_duration, 'title': info['title']}]
@@ -55,6 +57,7 @@ class ModifyChaptersPP(FFmpegPostProcessor):
self.write_debug('Expected and actual durations mismatch')
concat_opts = self._make_concat_opts(cuts, real_duration)
+ self.write_debug('Concat spec = %s' % ', '.join(f'{c.get("inpoint", 0.0)}-{c.get("outpoint", "inf")}' for c in concat_opts))
def remove_chapters(file, is_sub):
return file, self.remove_chapters(file, cuts, concat_opts, self._force_keyframes and not is_sub)
@@ -65,12 +68,13 @@ class ModifyChaptersPP(FFmpegPostProcessor):
# Renaming should only happen after all files are processed
files_to_remove = []
for in_file, out_file in in_out_files:
+ mtime = os.stat(in_file).st_mtime
uncut_file = prepend_extension(in_file, 'uncut')
os.replace(in_file, uncut_file)
os.replace(out_file, in_file)
+ self.try_utime(in_file, mtime, mtime)
files_to_remove.append(uncut_file)
- info['_real_duration'] = info['chapters'][-1]['end_time']
return files_to_remove, info
def _mark_chapters_to_remove(self, chapters, sponsor_chapters):
@@ -126,7 +130,7 @@ class ModifyChaptersPP(FFmpegPostProcessor):
cuts = []
def append_cut(c):
- assert 'remove' in c
+ assert 'remove' in c, 'Not a cut is appended to cuts'
last_to_cut = cuts[-1] if cuts else None
if last_to_cut and last_to_cut['end_time'] >= c['start_time']:
last_to_cut['end_time'] = max(last_to_cut['end_time'], c['end_time'])
@@ -154,7 +158,7 @@ class ModifyChaptersPP(FFmpegPostProcessor):
new_chapters = []
def append_chapter(c):
- assert 'remove' not in c
+ assert 'remove' not in c, 'Cut is appended to chapters'
length = c['end_time'] - c['start_time'] - excess_duration(c)
# Chapter is completely covered by cuts or sponsors.
if length <= 0:
@@ -237,7 +241,7 @@ class ModifyChaptersPP(FFmpegPostProcessor):
heapq.heappush(chapters, (c['start_time'], i, c))
# (normal, sponsor) and (sponsor, sponsor)
else:
- assert '_categories' in c
+ assert '_categories' in c, 'Normal chapters overlap'
cur_chapter['_was_cut'] = True
c['_was_cut'] = True
# Push the part after the sponsor to PQ.
@@ -301,7 +305,7 @@ class ModifyChaptersPP(FFmpegPostProcessor):
'name': SponsorBlockPP.CATEGORIES[category],
'category_names': [SponsorBlockPP.CATEGORIES[c] for c in cats]
})
- c['title'] = self._downloader.evaluate_outtmpl(self._sponsorblock_chapter_title, c)
+ c['title'] = self._downloader.evaluate_outtmpl(self._sponsorblock_chapter_title, c.copy())
# Merge identically named sponsors.
if (new_chapters and 'categories' in new_chapters[-1]
and new_chapters[-1]['title'] == c['title']):
@@ -331,6 +335,6 @@ class ModifyChaptersPP(FFmpegPostProcessor):
continue
opts[-1]['outpoint'] = f'{s["start_time"]:.6f}'
# Do not create 0 duration chunk at the end.
- if s['end_time'] != duration:
+ if s['end_time'] < duration:
opts.append({'inpoint': f'{s["end_time"]:.6f}'})
return opts