67 lines
1.9 KiB
Python
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 = "/home/honney/projects/mkv/output_dir/08.mkv"
|
|
print(get_intro_outro(Path(file))) |