How to get information of your MKV file :
mediainfo
Or :
ffmpeg -i myfile.mkv
Then, using this, check what streams to add into the output file (here ffmpeg -i myfile.mkv) :
Stream #0:0(eng): Video: h264 (High), yuv420p, 1920x800, SAR 1:1 DAR 12:5, 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc (default) Stream #0:1(fre): Audio: dts (DTS), 48000 Hz, 5.1(side), fltp, 1536 kb/s (default) Metadata: title : French Stream #0:2(eng): Audio: dts (DTS), 48000 Hz, 5.1(side), fltp, 1536 kb/s (default) Metadata: title : English Stream #0:3(fre): Subtitle: subrip Metadata: title : French Forced Stream #0:4(fre): Subtitle: subrip Metadata: title : French Stream #0:5(eng): Subtitle: subrip Metadata: title : English
Here for example, if you want to only keep english audio and subtitles, streams you want to keep are : video (0:0), audio (0:2) and sub (0:5). This will result in the following ffmpeg arguments :
-map 0:0 -map 0:2 -map 0:5
It is also possible to combine multiple mkv files (for example, you have one mkv with the video you want to use or copy, and another one with a sound you want to use). To do that, use ffmpeg -i on all files, and note all streams to use. For example, we want stream 0 from myfile1.mkv and streams 1,3,5 from myfile2.mkv. To do that, use :
ffmpeg -i myfile1.mkv -i myfile2.mkv -map 0:0 -map 1:1 -map 1:3 -map 1:5
So here, myfile1.mkv is 0:x and myfile2.mkv is 1:x. This VERY usefull if after a video conversion you realise you didn't selected the right audio/subs. Don't need to re-encode all, just mix both mkv (original and first produce one) and copy streams that do not need to be modified.
If you need something more sophisticated or if ffmpeg crash with a specific stream (video, audio, sub), you can use the very good tool mkvtoolnix or even better mkvtoolinx-gui (because GUI handles all the flags for you).
Copy stream:
-c:v copy
For h264 :
-c:v libx264 -crf 23 -preset veryslow
More :
https://trac.ffmpeg.org/wiki/Encode/H.264
For h265 :
-c:v libx265 -crf 28 -preset veryslow
More :
https://trac.ffmpeg.org/wiki/Encode/H.265
To resize :
If division is possible :
-vf scale -1:720
or if not :
-vf scale="-2:720"
or :
-vf scale="trunc(oh*a/2)*2:720"
Better is -2, as it let ffmpeg to choose the best way to do it.
To copy stream without recompression :
-c:a copy
For libvorbis :
-codec:a libvorbis -qscale:a 5
To reduce 5.1/Other to 2 (stereo):
-ac 2
More here :
https://trac.ffmpeg.org/wiki/TheoraVorbisEncodingGuide
https://trac.ffmpeg.org/wiki/Encode/HighQualityAudio
https://trac.ffmpeg.org/wiki/AudioChannelManipulation#a5.1stereo
To copy subtitles
-c:s copy
Solve errors from subtitles
With ffmpeg, subtitles are REALLY a pain. Many conversions will not work because of an unformated thing or a small error in one of the sub streams, and ffmpeg does not seem to simply copy subtitles, but it checks them and stop in case of error, even if subtitles are working with video players.
Trick is to convert the mkv first without the subtitles, (so only video and audio), then extract the subtitles from the original file with mkvextract (from mkvtoolnix), and merge them with the converted file with mkvmerge (from mkvtoolnix).
For example, if my subtitles are stream 0 and 1 of my original mkv file, then I can extract them using:
mkvextract tracks myoriginalfile.mkv 0:0.srt 1:1.srt
Then, subtitles will be in file 0.srt and file 1.srt. Then, merge them with audio/video converted mkv:
mkvmerge -o myfinalmkvfile.mkv myaudiovideoconvertedfile.mkv --language 0:fre 0.srt --language 0:fre 1.srt
Here, the –language allow to have something more “shiny” than just an “Track 1” and “Track 2” in the player for srt streams. It is possible to get all language codes using:
mkvmerge --list-languages
For h264
-threads 4
For h265 More sophisticated here, but much more convenient on multi-socket servers. See http://x265.readthedocs.io/en/latest/cli.html#performance-options.
-c:v libx265 -preset veryslow -x265-params crf=25:pools=+,-
+,- means : “hey libx265, I have 2 sockets, and I want you to use all cores on my socket 0 and let all cores on my socket 1 free.” Why doing this ? Because it is as fast as using both socket, because of memory latency between both sockets. Using only one socket per encoding ensure all memory is located on the same socket, and so I use all resources of this socket instead of using badly resources of both. Then, I can encode a second file using : -,+ at the same time.
To get a video compatible with all Powerpoints and Windows systems from XP :
ffmpeg -i INFILE -r 25 -f mpeg -vcodec mpeg1video -ar 48000 -b:v 5000k -b:a 128k -acodec mp2 -ar 44100 -ac 1 -y OUTFILE.mpg
To set frame rate : 30/1 = frames/s
ffmpeg -f image2 -r 30/1 -i test-%04d.png -vcodec msmpeg4 -s 300x300 -b 6000k out.avi
30 = framerate
ffmpeg -i P1009.MOV -30 -f image2 "test-%4d.png"
To use all files from 0 to ??, 2 frames per second.
ffmpeg.exe -f image2 -r 2/1 -i image_end%d.jpg -vcodec msmpeg4 -s 1950x1300 -b 6000k out2.avi
All files from 1519 to ??, 2 frames per second.
ffmpeg.exe -f image2 -r 2/1 -start_number 1519 -i image_end%04d.jpg -vcodec msmpeg4 -s 1950x1300 -b 6000k out2.avi
To fix index of a file, use mencoder:
mencoder -idx full_encoding.avi -ovc copy -oac copy -o full_encoding_fixed.avi
Other commands:
mencoder mf://*.png -mf w=800:h=600:fps=25:type=png -ovc raw -oac copy -o output.avi
mencoder mf://*.jpg -mf w=800:h=600:fps=25:type=jpg -ovc copy -oac copy -o output.avi
Creating an MPEG-4 file from all the JPEG files in the current directory:
mencoder mf://*.jpg -mf w=800:h=600:fps=25:type=jpg -ovc lavc -lavcopts vcodec=mpeg4:mbd=2:trell -oac copy -o output.avi
Creating an MPEG-4 file from some JPEG files in the current directory:
mencoder mf://frame001.jpg,frame002.jpg -mf w=800:h=600:fps=25:type=jpg -ovc lavc -lavcopts vcodec=mpeg4:mbd=2:trell -oac copy -o output.avi
Creating an MPEG-4 file from explicit list of JPEG files (list.txt in current directory contains the list of files to use as source, one per line):
mencoder mf://@list.txt -mf w=800:h=600:fps=25:type=jpg -ovc lavc -lavcopts vcodec=mpeg4:mbd=2:trell -oac copy -o output.avi
1080.flv or 1080.mp4___ xxx xxxko 720.flv or 720.mp4___xxx xxxko 480p.flv___38 003ko HQ135.mp4___35 995ko 360p.flv___25 425ko medium.mp4___24 989ko HQ134.mp4___16 109ko HQ5.flv___12 331ko HQ133.mp4___10 379ko HQ141.mp4___9 787ko HQ36.mp4___9 753ko HQ140.mp4___4 876ko HQ160.mp4___3 754ko MOBILE.3gp___3 398ko HQ139.mp4___1 827ko
Extract audio from Youtube MP4 files (note that 720/1080p quality is 192kb/s, much better than 480/30p quality with 96kb/s) :
ffmpeg -i input.mp4 -c:a copy -vn -sn output.m4a
Or with the fork (ubuntu) :
avconv -i input.mp4 -c:a copy -vn -sn output.m4a
For a whole directory (all mp4 files in a directory) :
for i in *.mp4; do avconv -i "$i" -c:a copy -vn -sn "$i.m4a" ; done
Mp3gain allow mp3 and m4a normalization : http://mp3gain.sourceforge.net/
ffmpeg -i input.mp3 -codec copy -map_metadata -1 output.mp3
ffmpeg -i input.mp3 -c:a libmp3lame -q:a 2 -ac 1 output.mp3
Or for a whole directory :
for f in *.mp3; do ffmpeg -i "$f" -c:a libmp3lame -q:a 2 -ac 1 mono-"$f"; done