Home > Software engineering >  ffmpeg/bash - mapping code for several output
ffmpeg/bash - mapping code for several output

Time:10-31

I use ffmpeg on a RaspberryPi3 (99% sure it is a pre-compiled version which I got from https://johnvansickle.com/ffmpeg/ as other methods to install failed for me)

Starting point:
Several multimedia files, each with a single video track, one or more audio tracks, and sometimes plenty subtitles.

My objective:
A bash script taking 3 inputs: respectively track number for video (mostly 0), track number for audio (mostly 1 but can be 2 or..) and track number for subtitles (mostly 2 but can also be 3 or 7 or..).
As output, I want:
a) a new video file with selected tracks (video, single audio which is re-encoded, single subtitle) b) a new separate srt file with only selected subtitle.

My code was already working for a) but can't seem to get it to work for b)
See below. It does generate the video I want with right selection of tracks.
But its fails to write the right srt file: seems to always default to first subtitle track ?

Is my mapping incorrect, or is this a bash coding issue ?

The file is called Remux.sh, and called with arguments so for example: ./Remux.sh 0 1 5

#!/bin/bash
PATH="/mnt/USB1/Series/_Remux/"
for fullfile in "$PATH"*.mkv
do
newname="${fullfile%}_converted.mkv"
srtname="${fullfile%}_converted.srt"
/usr/local/bin/ffmpeg -i "${fullfile}" -map 0:$1 -map 0:$2 -map 0:$3 \
-c:v copy -c:s copy -c:a ac3 -b:a 640k "${newname}" \
-c:s copy "$srtname"
done

Edit: many thanks @llogan for the pointer ! it's now working with the mapping addition :)

CodePudding user response:

Each output must have its own -map options. Otherwise, an output with no -map options will use the default stream selection behavior which chooses only 1 stream per stream type.

#!/bin/bash
PATH="/mnt/USB1/Series/_Remux/"
for fullfile in "$PATH"*.mkv
do
newname="${fullfile%}_converted.mkv"
srtname="${fullfile%}_converted.srt"
/usr/local/bin/ffmpeg -i "${fullfile}" -map 0:$1 -map 0:$2 -map 0:$3 \
-c:v copy -c:s copy -c:a ac3 -b:a 640k "${newname}" \
-map 0:$3 -c:s copy "$srtname"
done
  • You may find it helpful to use stream specifiers in your -map options, such as -map 0:s:1 for subtitle stream #2 (index starts at 0). See FFmpeg Wiki: Map.
  • Recommend you paste your script into shellcheck.net for additional Bash suggestions.
  • Related