fix (core): main fixes of codec/container/file_extension inconsistency #11

Merged
max merged 8 commits from major_fix into dev 2026-09-01 15:11:40 +04:00
3 changed files with 53 additions and 14 deletions
Showing only changes of commit f3abbb8f0c - Show all commits
+3
View File
@@ -194,6 +194,9 @@ def split_audio(input_file: str, output_directory: str, tracks: List[Dict[str, A
subtitle_codec=args.subtitle_codec,
metadata=metadata,
cover_image_path=cover_image_path,
video_quality=getattr(args, 'video_quality', None),
drop_video=args.drop_video,
drop_subs=args.drop_subs,
)
print(cmd)
+43 -14
View File
@@ -281,30 +281,49 @@ def build_ffmpeg_command(
subtitle_codec: Optional[str] = 'copy',
metadata: Optional[Dict] = None,
cover_image_path: Optional[str] = None,
video_quality: Optional[int] = None,
drop_video: bool = False,
drop_subs: bool = False,
) -> List[str]:
"""
Construct the FFmpeg command line.
Construct the FFmpeg command line as a list of arguments.
Args:
audio_codec: 'copy' or encoder name (e.g., 'libopus')
video_codec: 'copy' or encoder name (e.g., 'libx264')
subtitle_codec: 'copy' or encoder name (e.g., 'srt')
input_file: Path to the input media file.
start_seconds: Start time for the segment (in seconds).
duration_seconds: Duration of the segment (in seconds).
output_path: Destination path for the output file.
stream_info: Dictionary from get_stream_info().
format_opt: Output container format (e.g., 'mp3', 'mkv').
audio_codec: Audio codec to use ('copy' or encoder name like 'libopus').
video_codec: Video codec to use ('copy' or encoder name).
subtitle_codec: Subtitle codec to use ('copy' or encoder name).
metadata: Optional dict of metadata key/value pairs to write.
cover_image_path: Path to extracted cover image (if any).
video_quality: Quality value for video encoder (e.g., 1-31, lower=better).
drop_video: If True, remove video streams.
drop_subs: If True, remove subtitle streams.
Returns:
A list of commandline arguments suitable for subprocess.run().
"""
cmd = ['ffmpeg']
# Add cover image if provided
# Add cover image as first input if provided
if cover_image_path:
cmd.extend(['-i', cover_image_path])
# Add main input file
cmd.extend(['-i', input_file])
# Time options
cmd.extend(['-ss', format_time(start_seconds), '-t', format_time(duration_seconds)])
# Clear metadata
# Clear all original metadata.
cmd.append('-map_metadata')
cmd.append('-1')
# Apply custom metadata
# Apply custom metadata.
if metadata:
for key, value in metadata.items():
if value is not None and value != '':
@@ -328,15 +347,22 @@ def build_ffmpeg_command(
else:
cmd.extend(['-c:a', 'copy'])
# Subtitle: none (we don't copy from original when using cover image)
# 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:
# Standard mapping: copy all streams by default, then filter based on options
if not stream_info.get('has_video') or drop_video:
# Standard mapping (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:
# Map all streams
cmd.extend(['-map', '0'])
# Audio codec
@@ -345,17 +371,20 @@ def build_ffmpeg_command(
else:
cmd.extend(['-c:a', 'copy'])
# Video codec (if video present and not dropped)
if stream_info.get('has_video') and not drop_video:
# 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 stream_info.get('has_subtitle') and not drop_subs:
if not drop_subs and stream_info.get('has_subtitle'):
if subtitle_codec and subtitle_codec != 'copy':
cmd.extend(['-c:s', subtitle_codec])
else:
+7
View File
@@ -60,6 +60,13 @@ def main():
help="Drop video streams")
parser.add_argument('--drop-subs', action='store_true', default=DEFAULT_DROP_SUBS,
help="Drop subtitle streams")
parser.add_argument(
'--video-quality', '-vq',
type=int,
default=None,
help="Video quality (integer, encoder-specific; usually 1-31, lower=better). "
"If omitted, FFmpeg default is used."
)
# Filename options
parser.add_argument('--number-tracks', action='store_true', default=DEFAULT_NUMBER_TRACKS,