Files
anime_dub_sync/mkv/chapter.py
T
2026-03-20 00:46:36 +01:00

67 lines
1.9 KiB
Python

# for import needed
import sys
from pathlib import Path
sys.path.append(str(Path(__file__).resolve().parent.parent))
from utils import run
### Regular Imports
from typing import Tuple, List
import json
def get_chapters(file: Path) -> List[Tuple[float, float]]:
"""Return list of (start_ti
from .intro_outro importme, duration) for each chapter."""
cmd = [
"ffprobe",
"-i", str(file),
"-print_format", "json",
"-show_chapters",
"-loglevel", "error"
]
result = run(cmd)
data = json.loads(result.stdout)
chapters = []
for ch in data.get("chapters", []):
start = float(ch["start_time"])
end = float(ch["end_time"])
duration = end - start
chapters.append((start, duration))
return chapters
def get_intro_outro(file: Path, length: float = 90.0) -> List[Tuple[float, float]]:
try:
chapters = get_chapters(Path(file))
except:
raise AttributeError(f"{file} has no chapter Marks")
multiplier = 2
min_len = length / multiplier
max_len = length * multiplier
filtered = [
(start, dur) for start, dur in chapters
if min_len <= dur <= max_len
]
while len(filtered) > 2 and multiplier <= 1.1:
multiplier -= 0.1
min_len = length / multiplier
max_len = length * multiplier
filtered = [
(start, dur) for start, dur in chapters
if min_len <= dur <= max_len
]
if len(filtered) == 2:
return filtered
elif len(filtered) == 1:
### Found only a Intro or Outro
raise ValueError(f"Could only find one intro or outro:\n{filtered}")
elif len(filtered) == 0:
raise ValueError(f"Found no outro or intro:\n{filtered}")
else:
raise ValueError(f"Found too many intros/outros:\n{filtered}")
if __name__ == '__main__':
file = "./output_dir/episode.mkv"
print(get_intro_outro(Path(file)))