diff --git a/rewind/core.py b/rewind/core.py index 1a04290..b73a69b 100644 --- a/rewind/core.py +++ b/rewind/core.py @@ -2,6 +2,7 @@ import os import datetime import subprocess +import tempfile from rewind.state import load_state, add_marker_to_state, remove_marker_from_state from rewind.config import Config @@ -120,61 +121,62 @@ def _get_ts_files(start_timestamp: float, end_timestamp: float) -> tuple[list[st return selected_files, start_offset, end_offset def _concat_ts_files(file_list: list[str], start_offset: float, end_offset: float, length: float, output_file: str) -> None: - with open("file_list.txt", "w") as f: + tmp_file = tempfile.NamedTemporaryFile(mode="w", suffix=".txt", delete=False) + try: for file_path in file_list: - f.write(f"file '{file_path}'\n") + tmp_file.write(f"file '{file_path}'\n") + tmp_file.close() - cmd = ["ffmpeg", "-y", "-hide_banner", "-loglevel", "error", "-nostats", "-progress", "pipe:1"] - if start_offset > 0: - cmd += ["-ss", str(start_offset)] - if end_offset > 0: - cmd += ["-t", str(length)] - cmd += ["-f", "concat", "-safe", "0", "-i", "file_list.txt", "-c", "copy"] - cmd.append(output_file) + cmd = ["ffmpeg", "-y", "-hide_banner", "-loglevel", "error", "-nostats", "-progress", "pipe:1"] + if start_offset > 0: + cmd += ["-ss", str(start_offset)] + if end_offset > 0: + cmd += ["-t", str(length)] + cmd += ["-f", "concat", "-safe", "0", "-i", tmp_file.name, "-c", "copy"] + cmd.append(output_file) - process = subprocess.Popen( - cmd, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - text=True, - bufsize=1, - ) + process = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + bufsize=1, + ) - init_ms_val = 0 - init_ms_val_set = False + init_ms_val = 0 + init_ms_val_set = False - with tqdm( - total=length, - unit="s", - unit_scale=True, - unit_divisor=60, - desc="Processing", - leave=True, - ) as pbar: - for line in process.stdout: - line = line.strip() - + with tqdm( + total=length, + unit="s", + unit_scale=True, + unit_divisor=60, + desc="Processing", + leave=True, + ) as pbar: + for line in process.stdout: # type: ignore[union-attr] + line = line.strip() - if line.startswith("out_time_ms="): - out_time_ms = int(line.split("=")[1]) + if line.startswith("out_time_ms="): + out_time_ms = int(line.split("=")[1]) - if not init_ms_val_set: - init_ms_val = out_time_ms - init_ms_val_set = True - out_time_ms -= init_ms_val + if not init_ms_val_set: + init_ms_val = out_time_ms + init_ms_val_set = True + out_time_ms -= init_ms_val - seconds = abs(out_time_ms / 1_000_000) - pbar.n = min(seconds, length) - pbar.refresh() + seconds = abs(out_time_ms / 1_000_000) + pbar.n = min(seconds, length) + pbar.refresh() - elif line == "progress=end": - break + elif line == "progress=end": + break - ret = process.wait() - os.remove("file_list.txt") - - if ret != 0: - raise RuntimeError("ffmpeg failed") + ret = process.wait() + if ret != 0: + raise RuntimeError("ffmpeg failed") + finally: + os.unlink(tmp_file.name) def get_duration(file_path: str) -> float: result = subprocess.run(