====== Videos and audio manipulation ====== \\ ===== Video ===== ==== Infos from mkv ==== How to get information of your MKV file : mediainfo Or : ffmpeg -i myfile.mkv ==== Choose streams to use ==== 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). ==== Choose video compression ==== ** 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. ==== Choose audio compression ==== **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 ==== Subtitles ==== **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 ==== Multithreading ==== ** 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. ==== More with ffmpeg ==== 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 ==== mencoder ==== 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 ==== youtube video size ==== 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 ===== Audio ===== ==== mp4 to m4a ==== 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 ==== Normalize musics ==== Mp3gain allow mp3 and m4a normalization : http://mp3gain.sourceforge.net/ ==== Remove all tags of an mp3 ==== ffmpeg -i input.mp3 -codec copy -map_metadata -1 output.mp3 ==== Convert from stereo to mono ==== 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