refactor: Zeitauswahl nur noch über -z, -s/-e entfallen
-z 00:05:10 (ab), -z 0-00:20 (vom Anfang bis), -z 00:05-00:06 und mehrere Bereiche, mit oder ohne Anführungszeichen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
5e9a11d0f4
commit
8edef11c78
1 changed files with 93 additions and 108 deletions
78
vtt2txt.py
78
vtt2txt.py
|
|
@ -45,33 +45,22 @@ def parse_user_time(text):
|
|||
return int(first) * 3600 + int(minutes) * 60 + seconds
|
||||
|
||||
|
||||
def time_option(text):
|
||||
"""argparse type for -s/--start and -e/--ende."""
|
||||
try:
|
||||
return parse_user_time(text)
|
||||
except ValueError:
|
||||
raise argparse.ArgumentTypeError(
|
||||
f"ungültige Zeit „{text}“ ({TIME_EXAMPLES})"
|
||||
) from None
|
||||
|
||||
|
||||
def parse_ranges(text):
|
||||
"""Sorted (start, end) seconds from "00:05:00-00:06:00 00:10-00:12 00:25".
|
||||
|
||||
"A" or "A-" runs to the end, "-B" from the beginning; None marks an open side.
|
||||
"A" or "A-" runs to the end, "0-B" from the beginning; None marks an open side.
|
||||
"""
|
||||
ranges = []
|
||||
for item in text.split():
|
||||
start, dash, end = item.partition("-")
|
||||
if item.startswith("-"):
|
||||
raise ValueError(f"ungültiger Bereich „{item}“, vom Anfang: 0-B schreiben")
|
||||
start, _, end = item.partition("-")
|
||||
try:
|
||||
span = (
|
||||
parse_user_time(start) if start else None,
|
||||
parse_user_time(end) if end else None,
|
||||
)
|
||||
span = (parse_user_time(start) or None, parse_user_time(end) if end else None)
|
||||
except ValueError:
|
||||
raise ValueError(f"ungültiger Bereich „{item}“") from None
|
||||
if span == (None, None):
|
||||
raise ValueError(f"ungültiger Bereich „{item}“")
|
||||
raise ValueError(f"Bereich „{item}“ ist das ganze Video: -z weglassen")
|
||||
if None not in span and span[0] >= span[1]:
|
||||
raise ValueError(f"Bereich „{item}“: Start muss vor Ende liegen")
|
||||
ranges.append(span)
|
||||
|
|
@ -86,17 +75,6 @@ def parse_ranges(text):
|
|||
return ranges
|
||||
|
||||
|
||||
def ranges_option(text):
|
||||
"""argparse type for -z/--zeitraeume."""
|
||||
try:
|
||||
return parse_ranges(text)
|
||||
except ValueError as error:
|
||||
raise argparse.ArgumentTypeError(
|
||||
f"{error} (Bereiche durch Leerzeichen getrennt, je A-B, A = ab A, "
|
||||
f"-B = bis B; Zeiten {TIME_EXAMPLES})"
|
||||
) from None
|
||||
|
||||
|
||||
def format_time(seconds, separator=":"):
|
||||
seconds = int(seconds)
|
||||
return separator.join(
|
||||
|
|
@ -124,41 +102,35 @@ def time_suffix(ranges):
|
|||
return "_" + "+".join(range_name(start, end) for start, end in ranges)
|
||||
|
||||
|
||||
RANGE_FORMS = (
|
||||
"A-B (von A bis B), A (ab A bis zum Ende) oder 0-B (vom Anfang bis B); "
|
||||
f"Zeiten {TIME_EXAMPLES}"
|
||||
)
|
||||
|
||||
|
||||
def add_time_options(parser):
|
||||
parser.add_argument(
|
||||
"-s", "--start", type=time_option, metavar="ZEIT",
|
||||
help=f"nur Untertitel ab dieser Zeit, {TIME_EXAMPLES}",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-e", "--ende", type=time_option, metavar="ZEIT",
|
||||
help="nur Untertitel vor dieser Zeit (Format wie -s)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-z", "--zeitraeume", type=ranges_option, metavar="BEREICHE",
|
||||
help="mehrere Bereiche statt -s/-e, durch Leerzeichen getrennt: A-B, "
|
||||
"A (ab A bis zum Ende) oder -B (vom Anfang bis B), "
|
||||
"z. B. \"00:05:00-00:06:00 00:10-00:12 00:25\"",
|
||||
"-z", "--zeitraeume", nargs="+", metavar="BEREICH",
|
||||
help=f"nur Untertitel in diesen Bereichen: {RANGE_FORMS}; mehrere durch "
|
||||
"Leerzeichen getrennt, z. B. -z 00:05-00:06 00:10-00:12 00:25",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--exakt", action="store_true",
|
||||
help="genau an den Zeiten schneiden, statt angeschnittene Sätze vollständig "
|
||||
f"aufzunehmen (bis {MAX_SNAP_SECONDS} s über den Zeitraum hinaus)",
|
||||
f"aufzunehmen (bis {MAX_SNAP_SECONDS} s über den Bereich hinaus)",
|
||||
)
|
||||
|
||||
|
||||
def resolve_time_ranges(parser, args):
|
||||
"""Check the time options and set args.bereiche: list of (start, end), maybe empty."""
|
||||
single = args.start is not None or args.ende is not None
|
||||
if args.zeitraeume is not None:
|
||||
if single:
|
||||
parser.error("-z/--zeitraeume nicht zusammen mit -s/-e angeben.")
|
||||
args.bereiche = args.zeitraeume
|
||||
elif single:
|
||||
if args.start is not None and args.ende is not None and args.start >= args.ende:
|
||||
parser.error("-s/--start muss vor -e/--ende liegen.")
|
||||
args.bereiche = [(args.start, args.ende)]
|
||||
else:
|
||||
"""Check -z and set args.bereiche: sorted list of (start, end), maybe empty."""
|
||||
if args.zeitraeume is None:
|
||||
args.bereiche = []
|
||||
return
|
||||
# Parts with and without quotes alike: "-z '0:05-0:06 0:25'" or "-z 0:05-0:06 0:25"
|
||||
try:
|
||||
args.bereiche = parse_ranges(" ".join(args.zeitraeume))
|
||||
except ValueError as error:
|
||||
parser.error(f"-z/--zeitraeume: {error} ({RANGE_FORMS})")
|
||||
|
||||
|
||||
def read_cues(vtt):
|
||||
|
|
@ -423,7 +395,7 @@ def parse_args():
|
|||
"-o", "--output",
|
||||
help="Ausgabedatei (nur bei einer Eingabedatei) oder Verzeichnis "
|
||||
"(vorhanden oder mit / am Ende); Standard: <Eingabe ohne Endung>.txt, "
|
||||
"mit -s/-e/-z zusätzlich die Zeiträume im Namen",
|
||||
"mit -z zusätzlich die Bereiche im Namen",
|
||||
)
|
||||
add_time_options(parser)
|
||||
args = parser.parse_args()
|
||||
|
|
|
|||
Loading…
Reference in a new issue