This commit is contained in:
2026-01-12 10:05:57 -05:00
parent 8181bebaa0
commit 0a6e9ed1d8
2 changed files with 28 additions and 48 deletions
@@ -3,17 +3,26 @@ import subprocess
import sys import sys
from utils import verify_file_not_empty from utils import verify_file_not_empty
def run_ffmpeg(args):
"""
Runs ffmpeg, automatically escaping Flatpak sandbox if necessary.
"""
in_flatpak = os.path.exists("/.flatpak-info")
cmd = ["flatpak-spawn", "--host", "ffmpeg"] + args if in_flatpak else ["ffmpeg"] + args
try:
subprocess.run(cmd, check=True)
return True
except subprocess.CalledProcessError as e:
print(f"FFmpeg Error: {e}")
return False
except FileNotFoundError:
print("Error: 'ffmpeg' command not found. Please ensure it is installed on your host system.")
return False
def extract_audio(video_path, output_path=None): def extract_audio(video_path, output_path=None):
""" """
Extracts audio from a video file using ffmpeg. Extracts audio from a video file using ffmpeg.
Args:
video_path (str): Path to the input video file.
output_path (str, optional): Path for the output audio file.
If None, defaults to same name with .wav extension.
Returns:
str: Path to the generated audio file.
""" """
if not os.path.exists(video_path): if not os.path.exists(video_path):
raise FileNotFoundError(f"Video file not found: {video_path}") raise FileNotFoundError(f"Video file not found: {video_path}")
@@ -22,49 +31,33 @@ def extract_audio(video_path, output_path=None):
base_name = os.path.splitext(video_path)[0] base_name = os.path.splitext(video_path)[0]
output_path = f"{base_name}.wav" output_path = f"{base_name}.wav"
# Check if output file already exists to avoid redundant processing
if verify_file_not_empty(output_path): if verify_file_not_empty(output_path):
print(f"Audio file already exists: {output_path}") print(f"Audio file already exists: {output_path}")
return output_path return output_path
print(f"Extracting audio from {video_path}...") print(f"Extracting audio from {video_path}...")
# Command matching the user's preferred settings: 16kHz, Mono, PCM s16le args = [
# -y overwrites without asking (though we checked existence above, this is for safety if we force it)
command = [
"ffmpeg",
"-i", video_path, "-i", video_path,
"-ar", "16000", "-ar", "16000",
"-ac", "1", "-ac", "1",
"-c:a", "pcm_s16le", "-c:a", "pcm_s16le",
"-y", "-y",
"-v", "error", # Less verbose "-v", "error",
output_path output_path
] ]
try: if run_ffmpeg(args):
subprocess.run(command, check=True)
if not verify_file_not_empty(output_path): if not verify_file_not_empty(output_path):
raise Exception("FFmpeg command succeeded but output file is empty or missing.") raise Exception("FFmpeg succeeded but output is empty.")
print(f"Audio extracted to: {output_path}") print(f"Audio extracted to: {output_path}")
return output_path return output_path
except subprocess.CalledProcessError as e: else:
print(f"Error extracting audio: {e}")
sys.exit(1)
except Exception as e:
print(f"Error: {e}")
sys.exit(1) sys.exit(1)
def embed_subtitles(video_path, srt_path, output_path=None): def embed_subtitles(video_path, srt_path, output_path=None):
""" """
Embeds subtitles into the video file (Soft Subs) and sets them as primary. Embeds subtitles into the video file (Soft Subs) and sets them as primary.
Args:
video_path (str): Path to the input video.
srt_path (str): Path to the SRT file.
output_path (str, optional): Path for the output video.
""" """
if not os.path.exists(video_path) or not os.path.exists(srt_path): if not os.path.exists(video_path) or not os.path.exists(srt_path):
print("Error: Video or SRT file not found for embedding.") print("Error: Video or SRT file not found for embedding.")
@@ -76,18 +69,9 @@ def embed_subtitles(video_path, srt_path, output_path=None):
print(f"Embedding subtitles into: {output_path}...") print(f"Embedding subtitles into: {output_path}...")
# Determine subtitle codec based on container
sub_codec = "mov_text" if video_path.lower().endswith(".mp4") else "srt" sub_codec = "mov_text" if video_path.lower().endswith(".mp4") else "srt"
# Command breakdown: args = [
# -map 0:v -map 0:a -> Keep all video and audio from source
# -map 1:0 -> Add the subtitle from the 2nd input (srt_path)
# -c copy -> Copy video/audio streams (no re-encoding)
# -disposition:s:0 default -> Make the first subtitle track (ours) the default
# -metadata:s:s:0 -> Set metadata for the first subtitle stream
command = [
"ffmpeg",
"-ignore_editlist", "1", "-ignore_editlist", "1",
"-i", video_path, "-i", video_path,
"-i", srt_path, "-i", srt_path,
@@ -106,13 +90,9 @@ def embed_subtitles(video_path, srt_path, output_path=None):
output_path output_path
] ]
try: if run_ffmpeg(args):
subprocess.run(command, check=True)
if not verify_file_not_empty(output_path): if not verify_file_not_empty(output_path):
raise Exception("FFmpeg command succeeded but output video is empty or missing.") raise Exception("FFmpeg succeeded but output video is empty.")
print(f"Subtitles embedded successfully: {output_path}")
print(f"Subtitles embedded successfully: {output_path} (Set as primary)") else:
except subprocess.CalledProcessError as e: print("Error: Embedding failed.")
print(f"Error embedding subtitles: {e}")
except Exception as e:
print(f"Error embedding subtitles: {e}")