aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpukkandan <pukkandan.ytdlp@gmail.com>2021-10-18 16:03:05 +0530
committerpukkandan <pukkandan.ytdlp@gmail.com>2021-10-18 16:06:51 +0530
commit2d9ec70423121dbf280475769690f19b0034ee8b (patch)
treef2474bc75c9f51e21232d9714d90906985bd3905
parente820fbaa6ff41625b6f4d8453253883b86bf9ca4 (diff)
downloadhypervideo-pre-2d9ec70423121dbf280475769690f19b0034ee8b.tar.lz
hypervideo-pre-2d9ec70423121dbf280475769690f19b0034ee8b.tar.xz
hypervideo-pre-2d9ec70423121dbf280475769690f19b0034ee8b.zip
[ModifyChapters] Allow removing sections by timestamp
Eg: --remove-chapters "*10:15-15:00". The `*` prefix is used so as to avoid any conflicts with other valid regex
-rw-r--r--README.md6
-rw-r--r--yt_dlp/__init__.py10
-rw-r--r--yt_dlp/options.py6
-rw-r--r--yt_dlp/postprocessor/modify_chapters.py13
4 files changed, 30 insertions, 5 deletions
diff --git a/README.md b/README.md
index cbd3f337d..141be3315 100644
--- a/README.md
+++ b/README.md
@@ -847,7 +847,11 @@ Then simply run `make`. You can also run `make yt-dlp` instead to compile only t
--no-split-chapters Do not split video based on chapters
(default)
--remove-chapters REGEX Remove chapters whose title matches the
- given regular expression. This option can
+ given regular expression. Time ranges
+ prefixed by a "*" can also be used in place
+ of chapters to remove the specified range.
+ Eg: --remove-chapters "*10:15-15:00"
+ --remove-chapters "intro". This option can
be used multiple times
--no-remove-chapters Do not remove any chapters from the file
(default)
diff --git a/yt_dlp/__init__.py b/yt_dlp/__init__.py
index 4b82efea7..b952cc062 100644
--- a/yt_dlp/__init__.py
+++ b/yt_dlp/__init__.py
@@ -31,6 +31,7 @@ from .utils import (
expand_path,
match_filter_func,
MaxDownloadsReached,
+ parse_duration,
preferredencoding,
read_batch_urls,
RejectedVideoReached,
@@ -490,8 +491,14 @@ def _real_main(argv=None):
if opts.allsubtitles and not opts.writeautomaticsub:
opts.writesubtitles = True
# ModifyChapters must run before FFmpegMetadataPP
- remove_chapters_patterns = []
+ remove_chapters_patterns, remove_ranges = [], []
for regex in opts.remove_chapters:
+ if regex.startswith('*'):
+ dur = list(map(parse_duration, regex[1:].split('-')))
+ if len(dur) == 2 and all(t is not None for t in dur):
+ remove_ranges.append(tuple(dur))
+ continue
+ parser.error(f'invalid --remove-chapters time range {regex!r}. Must be of the form ?start-end')
try:
remove_chapters_patterns.append(re.compile(regex))
except re.error as err:
@@ -501,6 +508,7 @@ def _real_main(argv=None):
'key': 'ModifyChapters',
'remove_chapters_patterns': remove_chapters_patterns,
'remove_sponsor_segments': opts.sponsorblock_remove,
+ 'remove_ranges': remove_ranges,
'sponsorblock_chapter_title': opts.sponsorblock_chapter_title,
'force_keyframes': opts.force_keyframes_at_cuts
})
diff --git a/yt_dlp/options.py b/yt_dlp/options.py
index d2dc7687b..1c99e7e7c 100644
--- a/yt_dlp/options.py
+++ b/yt_dlp/options.py
@@ -1378,7 +1378,11 @@ def parseOpts(overrideArguments=None):
postproc.add_option(
'--remove-chapters',
metavar='REGEX', dest='remove_chapters', action='append',
- help='Remove chapters whose title matches the given regular expression. This option can be used multiple times')
+ help=(
+ 'Remove chapters whose title matches the given regular expression. '
+ 'Time ranges prefixed by a "*" can also be used in place of chapters to remove the specified range. '
+ 'Eg: --remove-chapters "*10:15-15:00" --remove-chapters "intro". '
+ 'This option can be used multiple times'))
postproc.add_option(
'--no-remove-chapters', dest='remove_chapters', action='store_const', const=None,
help='Do not remove any chapters from the file (default)')
diff --git a/yt_dlp/postprocessor/modify_chapters.py b/yt_dlp/postprocessor/modify_chapters.py
index 72a705fc5..a0818c41b 100644
--- a/yt_dlp/postprocessor/modify_chapters.py
+++ b/yt_dlp/postprocessor/modify_chapters.py
@@ -20,11 +20,12 @@ DEFAULT_SPONSORBLOCK_CHAPTER_TITLE = '[SponsorBlock]: %(category_names)l'
class ModifyChaptersPP(FFmpegPostProcessor):
- def __init__(self, downloader, remove_chapters_patterns=None, remove_sponsor_segments=None,
- sponsorblock_chapter_title=DEFAULT_SPONSORBLOCK_CHAPTER_TITLE, force_keyframes=False):
+ def __init__(self, downloader, remove_chapters_patterns=None, remove_sponsor_segments=None, remove_ranges=None,
+ *, 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._ranges_to_remove = set(remove_ranges or [])
self._sponsorblock_chapter_title = sponsorblock_chapter_title
self._force_keyframes = force_keyframes
@@ -97,6 +98,14 @@ class ModifyChaptersPP(FFmpegPostProcessor):
if warn_no_chapter_to_remove:
self.to_screen('There are no matching SponsorBlock chapters')
+ sponsor_chapters.extend({
+ 'start_time': start,
+ 'end_time': end,
+ 'category': 'manually_removed',
+ '_categories': [('manually_removed', start, end)],
+ 'remove': True,
+ } for start, end in self._ranges_to_remove)
+
return chapters, sponsor_chapters
def _get_supported_subs(self, info):