Reputation: 798
I have read many posts related to extracting streams per language with ffmpeg, but it seems that the -map 0:m:language:xxx
is global, and goes for all streams.
Let’s say I have a video file that contains hopefully one english audio stream and some french subtitle streams, among possibly many other streams. I want to get a smaller file with the first video track, the (first) english audio stream and all the french subtitle streams.
If I run
ffmpeg -i "$file" -map 0:v:0 -vcodec copy -map 0:m:language:eng -acodec copy -map 0:m:language:fre -scodec copy -f matroska "${file%.*}.mkv_out"
I get in file.mkv_out
all audio and subtitle tracks which are either french or english.
Is there a way to achieve this, without having any prior knowledge of track numbers in the original file ?
Thanks.
Upvotes: 1
Views: 3230
Reputation: 133743
Using ffmpeg
to pipe to another ffmpeg
to avoid temporary files:
ffmpeg -i input.mkv -map 0:v:0 -map 0:a:m:language:eng -map 0:s:m:language:fre -c copy -f matroska - | ffmpeg -i - -map 0:v -map 0:a:0 -map 0:s -c copy output.mkv
Upvotes: 3
Reputation: 1074
I'm afraid this can't be done in a single command because of the "first english audio stream" requirement. However, you can first extract all english audio streams and then pick the first one in second command like so:
Extract the first video, all english audio streams, all french subtitle streams to a temporary file:
ffmpeg -i "$file" -map 0:v:0 -map 0:a:m:language:eng -map 0:s:m:language:fre -c copy -f matroska "${file%.*}.mkv_out_tmp"
Then, from this file take the first stream (video), second stream (the first english audio), and all subtitles (all french):
ffmpeg -i "${file%.*}.mkv_out_tmp" -map 0:0 -map 0:1 -map 0:s -c copy -f matroska "${file%.*}.mkv_out"
And finally, delete the temporary file:
rm "${file%.*}.mkv_out_tmp"
Upvotes: 1