Softsubs
MP4 supports streaming text format subtitles, but playback support for this among players and devices is not universal.
Basic example using default stream selection behavior while stream copying the audio:
ffmpeg -i input.mkv -c copy -c:s mov_text output.mp4
Example to stream copy all of the video and audio streams, convert the all text based subtitle input streams (SRT, ASS, VTT, etc) to the streaming text format, and set the language for the first two subtitle streams.
ffmpeg -i input.mkv -map 0 -c copy -c:s mov_text -metadata:s:s:0 language=eng -metadata:s:s:1 language=ipk output.mp4
Same as above but re-encode the video and audio to formats compatible with the MP4 container (H.264 video:
ffmpeg -i input.mkv -map 0 -c:v libx264 -c:a aac -c:s mov_text -metadata:s:s:0 language=eng -metadata:s:s:1 language=ipk output.mp4
Same as above but use the -map
option to choose the first video stream, second audio stream, and third subtitle stream:
ffmpeg -i input.mkv -map 0:v:0 -map 0:a:1 -map 0:s:2 -c:v libx264 -c:a aac -c:s mov_text -metadata:s:s:0 language=eng output.mp4
Hardsubs
Text based subtitle format inputs
Use the subtitles filter to "burn-in" text based subtitle formats (SRT, ASS, VTT, etc). Note that this requires re-encoding, so it will by much slower than using softsubs.
Basic example using default stream selection behavior while stream copying the audio:
ffmpeg -i input.mkv -filter_complex "subtitles=input.mkv" -c:a copy output.mp4
Example to use the third video stream, fifth subtitle stream, and first audio stream:
ffmpeg -i input.mkv -filter_complex "[0:v:2]subtitles=input.mkv:si=4[v]" -map "[v]" -map 0:a:0 -c:a copy output.mp4
Example for a separate subtitle input file (your-subtitles-file.srt
):
ffmpeg -i input.mp4 -filter_complex "subtitles=your-subtitles-file.srt" -c:a copy output.mp4
Image based subtitle format inputs
Use the overlay filter. This example will overlay the fourth subtitle stream over the second video stream, and stream copy the seventh audio stream:
ffmpeg -i input.mkv -filter_complex "[0:v:2][0:s:3]overlay[v]" -map "[v]" -map 0:a:6 -c:a copy output.mp4
Also see
You say you want to "extract audio from them (mp3 or ogg)". But what if the audio in the mp4 file is not one of those? you'd have to transcode anyway. So why not leave the audio format detection up to ffmpeg?
To convert one file:
ffmpeg -i videofile.mp4 -vn -acodec libvorbis audiofile.ogg
To convert many files:
for vid in *.mp4; do ffmpeg -i "$vid" -vn -acodec libvorbis "${vid%.mp4}.ogg"; done
You can of course select any ffmpeg parameters for audio encoding that you like, to set things like bitrate and so on.
Use -acodec libmp3lame
and change the extension from .ogg
to .mp3
for mp3 encoding.
If what you want is to really extract the audio, you can simply "copy" the audio track to a file using -acodec copy
. Of course, the main difference is that transcoding is slow and cpu-intensive, while copying is really quick as you're just moving bytes from one file to another. Here's how to copy just the audio track (assuming it's in mp3 format):
ffmpeg -i videofile.mp4 -vn -acodec copy audiofile.mp3
Note that in this case, the audiofile format has to be consistent with what the container has (i.e. if the audio is AAC format, you have to say audiofile.aac
). You can use the ffprobe
command to see which codec you have, this may provide some information:
ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -print_format csv=p=0 "videofile.mp4"
A possible way to automatically parse the audio codec and name the audio file accordingly would be:
mkdir -p output
# current directory has to contain at least one .mp4 file
for vid in *.mp4; do
codec="$(ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -print_format csv=p=0 "$vid")"
case "$codec" in
mp3 ) filetype=mp3 ;;
vorbis ) filetype=ogg ;;
* ) filetype= ;;
esac
if [ "$filetype" ]; then
ffmpeg -i "$vid" -vn -acodec copy output/"${vid%.*}"."$filetype"
else
ffmpeg -i "$vid" -vn -acodec libvorbis output/"${vid%.*}".ogg
done
Notes: the output files are created in sub-directory output
it creates in the beginning (if necessary). For other codecs than mp3 and vorbis it converts audio to ogg. Ubuntu 14.04 does not have ffmpeg in standard repositories, but you could add ppa:mc3man/trusty-media repository and install ffmpeg package to get the needed software. See here for details.
Best Answer
Check out mkvtoolnix. Think it might do what you need it to.
https://mkvtoolnix.download/downloads.html#ubuntu
Edit:
sudo apt-get install mkvtoolnix mkvtoolnix-gui