User Tools

Site Tools


ffmpeg

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
ffmpeg [2020/03/12 17:15]
sdbs [How?] make clearer that you want WSL
ffmpeg [2021/12/11 23:21] (current)
sdbs improve commando
Line 6: Line 6:
 ==== How? ==== ==== How? ====
  
-If you're on Windows, it's possible to install ''ffmpeg'' and use it directly ((from https://ffmpeg.zeranoe.com/builds/)), but since the windows Command Prompt sucks ass comfort-wise and scripting-wise, it's recommended to just [[https://docs.microsoft.com/en-us/windows/wsl/install-win10|install Ubuntu as part of the Windows Subsystem for Linux]], and then ''apt-get install ffmpeg''.+If you're on Windows, it'technically possible to install ''ffmpeg'' and use it directly ((from https://ffmpeg.zeranoe.com/builds/)), but since the windows Command Prompt sucks ass comfort-wise and scripting-wise, it's recommended to just [[https://docs.microsoft.com/en-us/windows/wsl/install-win10|install Ubuntu as part of the Windows Subsystem for Linux]], and then ''apt-get install ffmpeg''.
  
-If you're on Linux, you know what to do 8-)+If you're on Linux, you already know what to do 8-)
  
 ===== Techniques ===== ===== Techniques =====
  
 +(All commands are expected to be ran in ''bash'' or a similar Linux shell.)
 +
 +==== Basic conversions ====
 +
 +''ffmpeg'' is pretty clever, it can correctly guess the codecs and reasonable default settings by the file extension, so all of the following will work as expected (and retain metadata((like ID3 tags and their FLAC, OGG, WAV, etc. equivalents))!):
 +
 +<code bash>
 +ffmpeg -i video.avi video.mp4
 +ffmpeg -i video.mp4 video_sound_only.wav
 +ffmpeg -i video_sound_only.wav video_sound_only.mp3
 +ffmpeg -i song.flac song.mp3
 +</code>
 +
 +=== mp3 bitrates ===
 +
 +"Reasonable" might not be what you want though, especially in the case of mp3, where the default bitrate is V4 (!), i.e. 140-185 kbps.
 +
 +If you want, for example, V__0__, use the ''-q:a''((read as -quality:audio)) option, like so:
 +
 +<code bash>
 +ffmpeg -i song.flac -q:a 0 song.mp3
 +</code>
 +
 +More info at: https://trac.ffmpeg.org/wiki/Encode/MP3
 +
 +=== video codecs ===
 +
 +Since container/format ≠ codec, you might want to select the codec manually.
 +
 +While it can reasonably assumed that ''mp4'' ≅ ''h264'', ''avi'' is a bit more complex. You can list all the supported codecs with ''ffmpeg -codecs''((and respectively, formats with ''ffmpeg -formats'')), but since there's several hundreds, you better have an idea of what you want to do in the first place.
 +
 +For example, if you want an ''.avi'' with xvid codec, you just do:
 +
 +<code bash>
 +ffmpeg -i original.mp4 -c:v libxvid output.avi
 +</code>
 +
 +=== General codec options ===
 +
 +This StackOverflow post explains everything:
 +https://stackoverflow.com/a/20587693/3833159
 ==== video // image files // frames ==== ==== video // image files // frames ====
  
Line 19: Line 60:
  
 <code bash> <code bash>
-ls *.jpg | xargs -I xyz echo "file 'xyz'" > list.txt+ls -1 | grep 'jpg$' | xargs -I xyz echo "file 'xyz'" > list.txt
 </code> </code>
  
Line 26: Line 67:
 </code> </code>
  
-It's up to preference, all end up with a list of all JPGs in current directory, in ''list.txt''.+It's up to preference, all end up with a list of all JPGs in current directory, in ''list.txt''(Though the first command can handle a bit more files.)
  
 == 2. list to video == == 2. list to video ==
Line 45: Line 86:
 Where ''FILE'' is the video file, and ''image%05d.png'' is the format string for image filenames; this will create ''image00001.png'', ''image00002.png'', ''image00123.png'', etc. (''%05d'' means pad with ''5'' zeroes; ''%010d'' for padding with ''10'' zeroes...) Where ''FILE'' is the video file, and ''image%05d.png'' is the format string for image filenames; this will create ''image00001.png'', ''image00002.png'', ''image00123.png'', etc. (''%05d'' means pad with ''5'' zeroes; ''%010d'' for padding with ''10'' zeroes...)
  
 +==== Streams ====
 +
 +''ffmpeg'' can also smoothly handle streams, so basic stream capture is pretty trivial, provided you grabbed the playlist/HLS url from somewhere((like https://addons.mozilla.org/en-US/firefox/addon/hls-stream-detector/; or just press F12, check the Network tab, and look carefully)):
 +
 +<code bash>
 +ffmpeg -i "https://example.com/playlist.m3u8" my_stream.mp4
 +</code>
 +
 +
 +=== Taking a screenshot of a stream ===
 +
 +''-vframes 1'' is the option that tells ''ffmpeg'' to just capture one (i.e. the first) frame of the video - in the case of streams, this means the latest one anyway.
 +
 +<code bash>
 +ffmpeg -i "https://example.com/playlist.m3u8" -vframes 1 capture.jpg
 +</code>
 +
 +
 +==== dropped frame re-interpolation ====
 +
 +''ffmpeg'' also has a [[https://ffmpeg.org/ffmpeg-filters.html|rich set of filters]], two of which are of interest for us now:
 +
 +  * [[https://ffmpeg.org/ffmpeg-filters.html#mpdecimate|mpdecimate]] - //Drop frames that do not differ greatly from the previous frame in order to reduce frame rate.//
 +  * [[https://ffmpeg.org/ffmpeg-filters.html#minterpolate|minterpolate]] - //Convert the video to specified frame rate using motion interpolation.//
 +
 +The idea is that ''mpdecimate'' drops all near-duplicate frames, and ''minterpolate'' re-calculates them using non-duplicate frames that were left.
 +
 +''mpdecimate'''s defaults are pretty okay, but the result may not look too good if the frame drops are frequent and long. I've had pretty good results using its ''max'' parameter which limits the amount of frames dropped in a single stretch of video, e.g. ''-vf mpdecimate=max=15'' which drops at most 15 frames (i.e. half a second assuming 30 FPS), meaning interpolation won't happen everywhere and the video will remain faithfully choppy.
 +
 +''minterpolate'', on the other hand, defaults to semi-smart motion compensated interpolation, and that //might// just be what you want, but it generally gives pretty funky results. Fortunately, it also has a "blend" mode, which just averages the start and end frames and crossfades them, which gives much more agreeable outputs for simple frame drop situations. It is also generally much faster, I was getting near or above real-time speeds using "blend", whereas motion compensation dropped the processing speed to 0.01x.
 +
 +**TL;DR**: Full command(s) including the filter pipeline:
 +
 +<code bash>
 +# Fill out all frame drop gaps
 +ffmpeg -i choppy_video.mp4 -vf mpdecimate,minterpolate=mi_mode=blend smoother_video.mp4
 +
 +# Fill out all frame drop gaps no longer than 10 frames:
 +ffmpeg -i choppy_video.mp4 -vf mpdecimate=max=10,minterpolate=mi_mode=blend smoother_video.mp4
 +
 +# Motion interpolate the gaps and replicate a bad ketamine trip
 +ffmpeg -i choppy_video.mp4 -vf mpdecimate,minterpolate smoother_video.mp4
 +</code>
 +
 +ffmpeg - skipping - remove duplicate frames after effects
 +
 +=== what is `N/FRAME_RATE/TB` ===
 +
 +  *  except the use of `FRAME_RATE` variable the `N/FRAME_RATE/TB` is equal to the example below from ffmpeg documentation ([source](https://ffmpeg.org/ffmpeg-filters.html#Examples-123))
 +  * 
 +<code>    
 +    > Set fixed rate of 25 frames per second:  
 +    > `setpts=N/(25*TB)`
 +</code>    
 +
 +  *   the math behind it perfectly explained in What is video timescale, timebase, or timestamp in ffmpeg? 
 +       it basically calculates timestamp for each frame and multiplies it with timebase `TB` to enhance precision
 +
 +==== mp4 compatibility ====
 +
 +h264 also has "profiles", basically [[https://en.wikipedia.org/wiki/Advanced_Video_Coding#Profiles|sets of features]] - and it turns out this can make the difference between a file working and not working on some crappy embedded media players, like TVs or pico projectors.
 +
 +>>The ''-profile:v'' option limits the output to a specific H.264 profile. Some devices (mostly very old or obsolete) only support the more limited Constrained Baseline or Main profiles. You can set these profiles with ''-profile:v baseline'' or ''-profile:v main''.
 +>https://trac.ffmpeg.org/wiki/Encode/H.264#Profile
 +
 +<code bash>
 +ffmpeg -i original.mp4 -profile:v baseline output.mp4
 +</code>
 +
 +And apparently, some players are also sensitive to the pixel format((https://trac.ffmpeg.org/wiki/Encode/H.264#Encodingfordumbplayers)), i.e. can't handle anything else than YUV w/ 4:2:0 chroma subsampling, to fix this use the ''-pix_fmt'' option as follows:
 +
 +<code bash>
 +ffmpeg -i original.mp4 -pix_fmt yuv420p output.mp4
 +# or, with the profile settings...
 +ffmpeg -i original.mp4 -profile:v baseline -pix_fmt yuv420p output.mp4
 +</code>
 +
 +
 +No silver bullet, you'll just have to try different things for different devices. A database of crappy players and appropriate ''ffmpeg'' settings would be great.
 +
 +
 +==== random ====
 +
 +https://ottverse.com/ffmpeg-drawtext-filter-dynamic-overlays-timecode-scrolling-text-credits/
 +
 +===== Other cheatsheets =====
 +  * [[https://gist.github.com/steven2358/ba153c642fe2bb1e47485962df07c730|FFmpeg cheat sheet]]
 +  * [[https://devhints.io/ffmpeg]]
 +  * [[https://gist.github.com/nickkraakman/e351f3c917ab1991b7c9339e10578049|FFmpeg Cheat Sheet for 360º video]]
ffmpeg.1584029732.txt.gz · Last modified: 2020/03/12 17:15 by sdbs