Initial commit. Basic featues are implemented

This commit is contained in:
2026-07-28 16:25:11 +05:00
commit 842e3bf1b0
12 changed files with 1190 additions and 0 deletions
+76
View File
@@ -0,0 +1,76 @@
"""Timestamp parsing and resolution."""
from .utils import parse_timestamp
def parse_track_timestamps(tracks):
"""
Parse timestamps from each track.
Args:
tracks: List of dicts from tracklist parsing.
Returns:
List of (start_seconds, end_seconds_or_None) for each track.
Raises:
ValueError: If timestamp is invalid or range is malformed.
"""
track_times = []
for idx, track in enumerate(tracks, 1):
ts_str = track.get('ts', '').strip()
if not ts_str:
raise ValueError(f"Track {idx}: timestamp is empty")
# Detect range: contains a dash.
if '-' in ts_str:
parts = ts_str.split('-', 1)
start_str = parts[0].strip()
end_str = parts[1].strip()
if not start_str or not end_str:
raise ValueError(f"Track {idx}: invalid range format '{ts_str}'. Expected 'start-end'.")
try:
start_sec = parse_timestamp(start_str)
end_sec = parse_timestamp(end_str)
except ValueError as e:
raise ValueError(f"Track {idx}: invalid timestamp in range '{ts_str}': {e}")
if end_sec <= start_sec:
raise ValueError(f"Track {idx}: end time ({end_str}) must be after start time ({start_str})")
track_times.append((start_sec, end_sec))
else:
# Start-only: we will compute end later.
try:
start_sec = parse_timestamp(ts_str)
except ValueError as e:
raise ValueError(f"Track {idx}: invalid timestamp '{ts_str}': {e}")
track_times.append((start_sec, None))
return track_times
def resolve_end_times(track_times, total_duration):
"""
Resolve None ends to next start or total duration.
Args:
track_times: List of (start_sec, end_sec_or_None).
total_duration: Total duration of the input file.
Returns:
List of (start_sec, end_sec) with all ends resolved.
Raises:
ValueError: If end time is not after start time.
"""
resolved = []
for idx, (start_sec, end_sec) in enumerate(track_times):
if end_sec is None:
if idx + 1 < len(track_times):
next_start = track_times[idx + 1][0]
end_sec = next_start
else:
end_sec = int(total_duration)
if end_sec <= start_sec:
raise ValueError(f"Track {idx+1}: end time ({end_sec}) is not after start ({start_sec})")
resolved.append((start_sec, end_sec))
return resolved