Files
at2-webapp-dicta2stream/concat_opus.py

79 lines
2.6 KiB
Python

# concat_opus.py — Concatenate all opus files in a user directory in random order into a single stream.opus
import os
import random
import subprocess
from pathlib import Path
def concat_opus_files(user_dir: Path, output_file: Path):
"""
Concatenate all .opus files in user_dir (except stream.opus) in random order into output_file.
Overwrites output_file if exists. Creates it if missing.
"""
# Clean up any existing filelist.txt to prevent issues
filelist_path = user_dir / 'filelist.txt'
if filelist_path.exists():
try:
filelist_path.unlink()
except Exception as e:
print(f"Warning: Could not clean up old filelist.txt: {e}")
# Get all opus files except stream.opus and remove any duplicates
import hashlib
file_hashes = set()
files = []
for f in user_dir.glob('*.opus'):
if f.name == 'stream.opus':
continue
try:
# Calculate file hash for duplicate detection
hasher = hashlib.md5()
with open(f, 'rb') as file:
buf = file.read(65536) # Read in 64kb chunks
while len(buf) > 0:
hasher.update(buf)
buf = file.read(65536)
file_hash = hasher.hexdigest()
# Skip if we've seen this exact file before
if file_hash in file_hashes:
print(f"Removing duplicate file: {f.name}")
f.unlink()
continue
file_hashes.add(file_hash)
files.append(f)
except Exception as e:
print(f"Error processing {f}: {e}")
if not files:
# If no files, create an empty stream.opus
output_file.write_bytes(b'')
return output_file
random.shuffle(files)
# Create a filelist for ffmpeg concat
filelist_path = user_dir / 'filelist.txt'
with open(filelist_path, 'w') as f:
for opusfile in files:
f.write(f"file '{opusfile.resolve()}'\n")
# ffmpeg concat demuxer (no re-encoding)
cmd = [
'ffmpeg', '-y', '-f', 'concat', '-safe', '0', '-i', str(filelist_path),
'-c', 'copy', str(output_file)
]
try:
subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
except subprocess.CalledProcessError as e:
raise RuntimeError(f"FFmpeg concat failed: {e}")
finally:
if filelist_path.exists():
filelist_path.unlink()
if not output_file.exists():
raise RuntimeError("Concatenation did not produce output.")
return output_file