Video Snippets🔗
- Introduction
- Merge video files and subtitles in a single file
- Change the aspect ratio for bad encoded movies
- Concatenate videos
- Extract the audio stream from a video
- Extract subtitles from an mkv file
- Convert a bunch of audio files into Vorbis format
- Play a horizontally flipped movie
- Extract part of videos
- Scale a video for VR with mobile phone
- Scale and crop a video for VR phone
- Find all libx264 options
Introduction
When you want to deal with a movie collection, you need some good tools to manipulate video files. Most of the time, command-line tools like ffmpeg, mkvmerge, etc. are better than GUI tools with limited options and parameters. This page is a way to easily remember the different uses of those tools…
Merge video files and subtitles in a single file
You get video files on the web and very often, there is no subtitles. You have to find yourself subtitles files (.srt for example), test them as they can be bad synchronized with the movie and you have to tell your video player to use this file… For me it is a real pain in the ass because watching a movie should just be a "launch the video, period" operation, nothing more.
After fighting with lots of srt files for subtitles, I've found that Mastroska container can incorporate srt files. Inserting those files is very easy with a command-line tool called mkvmerge which can be found in mkvtoolnix Debian package.
Here is the way to build an mkv file from an avi (or mp4) and an srt file:
mkvmerge -o new_movie.mkv the_movie.avi the_subtitle_file.srt
And there you have it!
Change the aspect ratio for bad encoded movies
Sometimes I grab movie files with very bad aspect ratios. The easy workaround is to use VLC or mpv and change the aspect ratio in the interface. But each time you launch the movie, you have to test and find the real aspect ratio. This is also a real pain in the ass… but you can change this by using gentlemen tools.
Just ask mkvmerge to change the declared aspect ratio in the Matroska container:
mkvmerge -o My_Movie.mkv --aspect-ratio 0:16/9 the_movie.avi the_subtitle_file.srt
Everything is done with aspect-ratio option. 0 means that we are declaring the aspect ratio for the track 0 (which is often the video track you want to correct). 16/9 is a way to declare a 16/9 ratio. You can use float numbers too:
mkvmerge -o My_Movie.mkv --aspect-ratio 0:2.35 the_movie.avi the_subtitle_file.srt
Just use VLC or mpv to find the best aspect ratio and then, use mkvmerge to build a nice "just launch the video" movie!
Concatenate videos
Want to append a video at the end of another one? The answer is still mkvmerge with a + !!!
mkvmerge -o My_Movie.mkv part_1.avi +part_2.avi +part_3.avi
You can also do it with ffmpeg:
ffmpeg -i part1.mp4 -i part2.mp4 -i part3.mp4 -filter_complex "[0:v] [1:v] [2:v] concat=n=3:v=1 [v]" -map "[v]" -an -c:copy output.mp4
Extract the audio stream from a video
This time you have to use ffmpeg.
Use ffprobe
to find the real audio format:
ffprobe MyMovie.mp4 Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'MyMovie.mp4': Metadata: major_brand : mp42 minor_version : 0 compatible_brands: isommp42 creation_time : 2014-11-25 17:23:00 Duration: 00:51:22.98, start: 0.000000, bitrate: 247 kb/s Stream #0.0(und): Video: h264 (High), yuv420p, 1280x720 [PAR 1:1 DAR 16:9], 222 kb/s, 29.97 fps, 30k tbn, 59.94 tbc (default) Stream #0.1(und): Audio: aac, 44100 Hz, stereo, fltp, 191 kb/s (default) Metadata: creation_time : 2014-11-25 17:23:12
You can find that the audio codec is AAC. Now, you can extract the stream into a m4a container like this:
ffmpeg -i MyMovie.mp4 -vn -acodec copy MyMusic.m4a
Explanations:
-i
: option to tell to avprobe that the input file is MyMovie.mp4-vn
: do not record video-acodec
: tells which audio codec will be used for output.copy
means: use the same codec as source.
Be sure to use m4a for file container because some music players don't handle raw AAC streams.
Extract subtitles from an mkv file
The best way to extract subtitles from an mkv file is probably to use mkvinfo and mkvextract from mkvtoolnix.
First, find what is the "channel" of the subtitles:
mkvinfo myvideo.mkv + Entête EBML |+ Version EBML : 1 |+ Version EBML lue : 1 |+ Longueur maximale de l'identifiant EBML : 4 |+ Longueur maximale de la taille EBML : 8 |+ Type de document : matroska |+ Version du type de document : 2 |+ Version lue du type de document : 2 + Segment, taille 98931722 |+ Tête de positionnement (sous-entrées ignorées) |+ EbmlVoid (taille : 187) |+ EbmlVoid (taille : 4096) |+ Informations de segment | + UID de segment : 0xf5 0xfa 0xbc 0x1b 0x23 0x7f 0x01 0x7a 0xa7 0x8f 0x66 0x7b 0xa8 0x11 0x2f 0x6b | + Application de multiplexage : libmkv 0.6.5 | + Écriture de l'application : HandBrake 0.9.9 | + Échelle de code temporel : 1000000 | + Durée : 1325.366s (00:22:05.365) |+ Pistes du segment | + Une piste | + Numéro de piste : 1 (identifiant de piste pour mkvmerge & mkvextract : 0) ... | + Une piste | + Numéro de piste : 3 (identifiant de piste pour mkvmerge & mkvextract : 2) | + UID de piste : 7080 | + Type de piste : subtitles | + Signal de laçage : 0 | + Identifiant du codec : S_TEXT/UTF8 | + Langue : eng | + Signal par défaut : 1 |+ Grappe
There we can find that our subtitles are on the track 3 but must be called track number 2 with the other tools.
Then, you just extract the subtitles to a .srt file like this:
mkvextract tracks myvideo.mkv 2:subtitles.srt
Convert a bunch of audio files into Vorbis format
I have a phone that is not able to read modern codecs like opus or aac. So, sometimes I have to convert a bunch of audio albums into Ogg Vorbis files to be able to read them on this smartphone.
I've ended to use this one-liner:
find /media/data/music/artist/ -type f -exec bash -c 'f="$1"; fname=$(basename "$f"); fname=${fname%%.*}; tdir=$(basename $(dirname "$f")); mkdir -p "$tdir"; ext="${f##*.}"; ext="${ext,,}"; if [ "$ext" != "ogg" -a "$ext" != "jpg" ]; then ffmpeg -y -loglevel panic -i "$f" -c:a libvorbis -q:a 8 "./$tdir/$fname.ogg"; else cp "$f" "./$tdir"; fi' _ {} \;
Play a horizontally flipped movie
Sometimes, movies have been horizontally flipped by people who have re-encoded them (most of the time, to reverse watermark to avoid automated copyright infringment detection tools).
To keep the best quality without having to re-encode the file, you can use an ffmpeg filter directly into mpv (and starting it from the command-line, of course):
mpv --vf=lavfi=hflip video.mp4
--vf
: use a video filter in mpv.=lavfi
: we are using an ffmpeg filter.=hflip
: this filter is called hflip (for horizontal flip).
Read the reference for further details.
Extract part of videos
If you want an accurate cut of a video, you can use the following command:
ffmpeg -i video.mp4 -ss HOURS:MM:SS.MILLISECONDS -to HOURS:MM:SS.MILLISECONDS -c copy -copyts cut.mp4
Placing -ss
after -i
will take time as ffmpeg will do a precise seeking on the input video. It generaly takes 10 seconds on an hour video. But with this option, you will be able to cut the video at the very beginning of the start time. Otherwise, you will seek on the nearest key frame.
If you want a fast but not accurate cut of the video, place -ss
before -i
option:
ffmpeg -ss HOURS:MM:SS.MILLISECONDS -i video.mp4 -to HOURS:MM:SS.MILLISECONDS -c copy -copyts cut.mp4
Scale a video for VR with mobile phone
Sometimes, a VR video is put up for high end Virtual Reality headsets like HTC Vive Cosmos or Occulus Rift S or Valve Index. But you can also use them on your smartphone and a VR cardboard.
If your phone support h264:
ffmpeg -v error -i "input.mp4" -c:v libx264 -preset slower -crf 18 -tune film -profile:v high -x264-params mvrange=511 -maxrate 50M -bufsize 25M -vf "scale=2160x1080" -pix_fmt yuv420p -c:a copy -movflags faststart -r 50 "output_h264.mp4"
If your phone support h265/HEVC:
ffmpeg -v error -i "input.mp4" -c:v libx265 -preset slower -crf 23 -tune fastdecode -profile:v main -maxrate 50M -bufsize 25M -vf "scale=2160x1080" -pix_fmt yuv420p -c:a copy -movflags faststart -r 50 "output_h265.mp4"
Some explanations:
-vf scale=2160x1080
: this is the resizing information.-maxrate 50M -bufsize 25M
: read this.-movflags faststart
: put all metadata information at the beginning of the file. Whenever you download such a file you are able to play it without having to fully download it. Read this.
Scale and crop a video for VR phone
From 360 Side-By-Side to 180 Side-By-Side
It is a little complex and we have to use two crops to achieve this using only one ffmpeg command. Here is what I have used so far with mild results (don't forget to change timings, as it is written, it only serves to test the job).
For square videos:
ffmpeg -y -ss 00:00:05.000 -i vr.mp4 -to 00:00:10.000 -c:v libx264 -preset slower -crf 18 -tune film -profile:v high -x264-params mvrange=511 -maxrate 50M -bufsize 25M -filter_complex "color=s=2048x2048:c=black[bg];[0:v]crop=iw/4:ih:iw/8:ih[crop1];[0:v]crop=iw/4:ih:iw/2+iw/8:ih[crop2];[bg][crop1]overlay=x=0:y=0:shortest=1[out1];[out1][crop2]overlay=x=1024:y=0[final]" -map "[final]" -pix_fmt yuv420p -c:a copy -movflags faststart test_360_to_180_h264.mp4
For wide videos:
ffmpeg -y -ss 00:00:05.000 -i vr.mp4 -to 00:00:10.000 -c:v libx264 -preset slower -crf 18 -tune film -profile:v high -x264-params mvrange=511 -maxrate 50M -bufsize 25M -filter_complex "color=s=2048x1024:c=black[bg];[0:v]crop=iw/4:ih/2:iw/8:ih[crop1];[0:v]crop=iw/4:ih/2:iw/2+iw/8:ih[crop2];[bg][crop1]overlay=x=0:y=0:shortest=1[out1];[out1][crop2]overlay=x=1024:y=0[final]" -map "[final]" -pix_fmt yuv420p -c:a copy -movflags faststart test_360_to_180_h264.mp4
Find all libx264 options
Whenever you want to have maximum of details about a lib support in ffmpeg:
ffmpeg -h encoder=libx264