refact (core): split large code blocks, remove useless files/code #12
+116
-85
@@ -269,6 +269,109 @@ def extract_cover_image(input_file: str, output_path: str) -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def _build_inputs(cmd: List[str], input_file: str, cover_image_path: Optional[str]) -> None:
|
||||||
|
"""Add input files to the command."""
|
||||||
|
if cover_image_path:
|
||||||
|
cmd.extend(['-i', cover_image_path])
|
||||||
|
cmd.extend(['-i', input_file])
|
||||||
|
|
||||||
|
|
||||||
|
def _build_time_options(cmd: List[str], start_seconds: int, duration_seconds: int) -> None:
|
||||||
|
"""Add time-based options to the command."""
|
||||||
|
cmd.extend(['-ss', format_time(start_seconds), '-t', format_time(duration_seconds)])
|
||||||
|
|
||||||
|
|
||||||
|
def _build_metadata(cmd: List[str], metadata: Optional[Dict]) -> None:
|
||||||
|
"""Add metadata options to the command."""
|
||||||
|
cmd.append('-map_metadata')
|
||||||
|
cmd.append('-1')
|
||||||
|
if metadata:
|
||||||
|
for key, value in metadata.items():
|
||||||
|
if value is not None and value != '':
|
||||||
|
cmd.extend(['-metadata', f"{key}={value}"])
|
||||||
|
|
||||||
|
|
||||||
|
def _build_cover_image_mapping(
|
||||||
|
cmd: List[str],
|
||||||
|
audio_codec: Optional[str],
|
||||||
|
video_codec: Optional[str],
|
||||||
|
video_quality: Optional[int],
|
||||||
|
) -> None:
|
||||||
|
"""Build stream mapping for cover image extraction (audio + cover video)."""
|
||||||
|
cmd.extend(['-map', '1:a:0', '-map', '0:v:0'])
|
||||||
|
|
||||||
|
if video_codec and video_codec != 'copy':
|
||||||
|
cmd.extend(['-c:v', video_codec])
|
||||||
|
else:
|
||||||
|
cmd.extend(['-c:v', 'png'])
|
||||||
|
|
||||||
|
if audio_codec and audio_codec != 'copy':
|
||||||
|
cmd.extend(['-c:a', audio_codec])
|
||||||
|
else:
|
||||||
|
cmd.extend(['-c:a', 'copy'])
|
||||||
|
|
||||||
|
cmd.append('-sn')
|
||||||
|
|
||||||
|
if video_quality is not None:
|
||||||
|
cmd.extend(['-q:v', str(video_quality)])
|
||||||
|
|
||||||
|
|
||||||
|
def _build_standard_mapping(
|
||||||
|
cmd: List[str],
|
||||||
|
stream_info: Dict,
|
||||||
|
audio_codec: Optional[str],
|
||||||
|
video_codec: Optional[str],
|
||||||
|
subtitle_codec: Optional[str],
|
||||||
|
video_quality: Optional[int],
|
||||||
|
drop_video: bool,
|
||||||
|
drop_subs: bool,
|
||||||
|
) -> None:
|
||||||
|
"""Build stream mapping for standard extraction (no cover image)."""
|
||||||
|
if drop_video and drop_subs:
|
||||||
|
cmd.extend(['-map', '0:a:0'])
|
||||||
|
elif drop_video:
|
||||||
|
cmd.extend(['-map', '0:a:0', '-map', '0:s?'])
|
||||||
|
elif drop_subs:
|
||||||
|
cmd.extend(['-map', '0:a:0', '-map', '0:v:0'])
|
||||||
|
else:
|
||||||
|
cmd.extend(['-map', '0'])
|
||||||
|
|
||||||
|
if audio_codec and audio_codec != 'copy':
|
||||||
|
cmd.extend(['-c:a', audio_codec])
|
||||||
|
else:
|
||||||
|
cmd.extend(['-c:a', 'copy'])
|
||||||
|
|
||||||
|
if not drop_video and stream_info.get('has_video'):
|
||||||
|
if video_codec and video_codec != 'copy':
|
||||||
|
cmd.extend(['-c:v', video_codec])
|
||||||
|
if video_quality is not None:
|
||||||
|
cmd.extend(['-q:v', str(video_quality)])
|
||||||
|
else:
|
||||||
|
cmd.extend(['-c:v', 'copy'])
|
||||||
|
else:
|
||||||
|
cmd.append('-vn')
|
||||||
|
|
||||||
|
if not drop_subs and stream_info.get('has_subtitle'):
|
||||||
|
if subtitle_codec and subtitle_codec != 'copy':
|
||||||
|
cmd.extend(['-c:s', subtitle_codec])
|
||||||
|
else:
|
||||||
|
cmd.extend(['-c:s', 'copy'])
|
||||||
|
else:
|
||||||
|
cmd.append('-sn')
|
||||||
|
|
||||||
|
|
||||||
|
def _build_format(cmd: List[str], format_opt: Optional[str]) -> None:
|
||||||
|
"""Add output format option if specified."""
|
||||||
|
if format_opt:
|
||||||
|
ffmpeg_format = FORMAT_INFO.get(format_opt, {}).get('ffmpeg', format_opt)
|
||||||
|
cmd.extend(['-f', ffmpeg_format])
|
||||||
|
|
||||||
|
|
||||||
|
def _build_output(cmd: List[str], output_path: str) -> None:
|
||||||
|
"""Add output file to the command."""
|
||||||
|
cmd.extend(['-y', output_path])
|
||||||
|
|
||||||
|
|
||||||
def build_ffmpeg_command(
|
def build_ffmpeg_command(
|
||||||
input_file: str,
|
input_file: str,
|
||||||
start_seconds: int,
|
start_seconds: int,
|
||||||
@@ -309,93 +412,21 @@ def build_ffmpeg_command(
|
|||||||
"""
|
"""
|
||||||
cmd = ['ffmpeg']
|
cmd = ['ffmpeg']
|
||||||
|
|
||||||
# Add cover image as first input if provided
|
_build_inputs(cmd, input_file, cover_image_path)
|
||||||
|
_build_time_options(cmd, start_seconds, duration_seconds)
|
||||||
|
_build_metadata(cmd, metadata)
|
||||||
|
|
||||||
if cover_image_path:
|
if cover_image_path:
|
||||||
cmd.extend(['-i', cover_image_path])
|
_build_cover_image_mapping(cmd, audio_codec, video_codec, video_quality)
|
||||||
|
|
||||||
# Add main input file
|
|
||||||
cmd.extend(['-i', input_file])
|
|
||||||
|
|
||||||
# Time options
|
|
||||||
cmd.extend(['-ss', format_time(start_seconds), '-t', format_time(duration_seconds)])
|
|
||||||
|
|
||||||
# Clear all original metadata.
|
|
||||||
cmd.append('-map_metadata')
|
|
||||||
cmd.append('-1')
|
|
||||||
|
|
||||||
# Apply custom metadata.
|
|
||||||
if metadata:
|
|
||||||
for key, value in metadata.items():
|
|
||||||
if value is not None and value != '':
|
|
||||||
cmd.extend(['-metadata', f"{key}={value}"])
|
|
||||||
|
|
||||||
# ---------- Stream mapping and codecs ----------
|
|
||||||
if cover_image_path:
|
|
||||||
# We have two inputs: index 0 = cover image, index 1 = main input
|
|
||||||
# Map audio from main input (index 1) and video from cover image (index 0)
|
|
||||||
cmd.extend(['-map', '1:a:0', '-map', '0:v:0'])
|
|
||||||
|
|
||||||
# Video codec: use user-specified codec if provided, otherwise fallback to png
|
|
||||||
if video_codec and video_codec != 'copy':
|
|
||||||
cmd.extend(['-c:v', video_codec])
|
|
||||||
else:
|
|
||||||
cmd.extend(['-c:v', 'png'])
|
|
||||||
|
|
||||||
# Audio codec
|
|
||||||
if audio_codec and audio_codec != 'copy':
|
|
||||||
cmd.extend(['-c:a', audio_codec])
|
|
||||||
else:
|
|
||||||
cmd.extend(['-c:a', 'copy'])
|
|
||||||
|
|
||||||
# Subtitle: we don't copy subtitles when using cover image (they would be from main input)
|
|
||||||
cmd.append('-sn')
|
|
||||||
|
|
||||||
# Video quality if specified
|
|
||||||
if video_quality is not None:
|
|
||||||
cmd.extend(['-q:v', str(video_quality)])
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Standard mapping (no cover image)
|
_build_standard_mapping(
|
||||||
if drop_video and drop_subs:
|
cmd, stream_info, audio_codec, video_codec, subtitle_codec,
|
||||||
cmd.extend(['-map', '0:a:0'])
|
video_quality, drop_video, drop_subs
|
||||||
elif drop_video:
|
)
|
||||||
cmd.extend(['-map', '0:a:0', '-map', '0:s?'])
|
|
||||||
elif drop_subs:
|
|
||||||
cmd.extend(['-map', '0:a:0', '-map', '0:v:0'])
|
|
||||||
else:
|
|
||||||
cmd.extend(['-map', '0'])
|
|
||||||
|
|
||||||
# Audio codec
|
_build_format(cmd, format_opt)
|
||||||
if audio_codec and audio_codec != 'copy':
|
_build_output(cmd, output_path)
|
||||||
cmd.extend(['-c:a', audio_codec])
|
|
||||||
else:
|
|
||||||
cmd.extend(['-c:a', 'copy'])
|
|
||||||
|
|
||||||
# Video codec
|
|
||||||
if not drop_video and stream_info.get('has_video'):
|
|
||||||
if video_codec and video_codec != 'copy':
|
|
||||||
cmd.extend(['-c:v', video_codec])
|
|
||||||
# Add video quality if specified (only when re-encoding)
|
|
||||||
if video_quality is not None:
|
|
||||||
cmd.extend(['-q:v', str(video_quality)])
|
|
||||||
else:
|
|
||||||
cmd.extend(['-c:v', 'copy'])
|
|
||||||
else:
|
|
||||||
cmd.append('-vn')
|
|
||||||
|
|
||||||
# Subtitle codec
|
|
||||||
if not drop_subs and stream_info.get('has_subtitle'):
|
|
||||||
if subtitle_codec and subtitle_codec != 'copy':
|
|
||||||
cmd.extend(['-c:s', subtitle_codec])
|
|
||||||
else:
|
|
||||||
cmd.extend(['-c:s', 'copy'])
|
|
||||||
else:
|
|
||||||
cmd.append('-sn')
|
|
||||||
|
|
||||||
# Output format
|
|
||||||
if format_opt:
|
|
||||||
ffmpeg_format = FORMAT_INFO.get(format_opt, {}).get('ffmpeg', format_opt)
|
|
||||||
cmd.extend(['-f', ffmpeg_format])
|
|
||||||
|
|
||||||
cmd.extend(['-y', output_path])
|
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user