FEATURE: adds quality flag for video stream
This commit is contained in:
@@ -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
@@ -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 command‑line 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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user