Automatic update.

This commit is contained in:
sdbs Terra 2020-11-16 20:00:39 +01:00
parent fd57fad242
commit 3709fed4d2

View file

@ -6,33 +6,22 @@ Essentials
### What? ### What?
[ffmpeg](https://ffmpeg.org/) is a swiss army knife for everything [ffmpeg](https://ffmpeg.org/) is a swiss army knife for everything audio/video. It can do practically every task under the sun, and in fact powers most major dedicated "video players" (VLC, MPC-HC, built-in players in Chrome and Firefox...)[^1]
audio/video. It can do practically every task under the sun, and in fact
powers most major dedicated \"video players\" (VLC, MPC-HC, built-in
players in Chrome and Firefox\...)[^1]
### How? ### How?
If you\'re on Windows, it\'s technically possible to install `ffmpeg` If you're on Windows, it's technically possible to install `ffmpeg` and use it directly [^2], but since the windows Command Prompt sucks ass comfort-wise and scripting-wise, it's recommended to just [install Ubuntu as part of the Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10), and then `apt-get install ffmpeg`.
and use it directly [^2], but since the windows Command Prompt sucks ass
comfort-wise and scripting-wise, it\'s recommended to just [install
Ubuntu as part of the Windows Subsystem for
Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10), and
then `apt-get install ffmpeg`.
If you\'re on Linux, you already know what to do 8-) If you're on Linux, you already know what to do 😎
Techniques Techniques
---------- ----------
(All commands are expected to be ran in `bash` or a similar Linux (All commands are expected to be ran in `bash` or a similar Linux shell.)
shell.)
### Basic conversions ### Basic conversions
`ffmpeg` is pretty clever, it can correctly guess the codecs and `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[^3]!):
reasonable default settings by the file extension, so all of the
following will work as expected (and retain metadata[^3]!):
``` {.bash} ``` {.bash}
ffmpeg -i video.avi video.mp4 ffmpeg -i video.avi video.mp4
@ -43,10 +32,9 @@ ffmpeg -i song.flac song.mp3
#### mp3 bitrates #### mp3 bitrates
\"Reasonable\" might not be what you want though, especially in the case "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.
of mp3, where the default bitrate is V4 (!), i.e. 140-185 kbps.
If you want, for example, V[0]{.ul}, use the `-q:a`[^4] option, like so: If you want, for example, V[0], use the `-q:a`[^4] option, like so:
``` {.bash} ``` {.bash}
ffmpeg -i song.flac -q:a 0 song.mp3 ffmpeg -i song.flac -q:a 0 song.mp3
@ -56,13 +44,9 @@ More info at: <https://trac.ffmpeg.org/wiki/Encode/MP3>
#### video codecs #### video codecs
Since container/format ≠ codec, you might want to select the codec Since container/format ≠ codec, you might want to select the codec manually.
manually.
While it can reasonably assumed that `mp4``h264`, `avi` is a bit more While it can reasonably assumed that `mp4``h264`, `avi` is a bit more complex. You can list all the supported codecs with `ffmpeg -codecs`[^5], but since there's several hundreds, you better have an idea of what you want to do in the first place.
complex. You can list all the supported codecs with
`ffmpeg -codecs`[^5], 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: For example, if you want an `.avi` with xvid codec, you just do:
@ -72,8 +56,7 @@ ffmpeg -i original.mp4 -c:v libxvid output.avi
#### General codec options #### General codec options
This StackOverflow post explains everything: This StackOverflow post explains everything: <https://stackoverflow.com/a/20587693/3833159>
<https://stackoverflow.com/a/20587693/3833159>
### video // image files // frames ### video // image files // frames
@ -81,9 +64,7 @@ This StackOverflow post explains everything:
##### 1. creating a list of images ##### 1. creating a list of images
`ffmpeg` needs a list of images in a text file in a [specific `ffmpeg` needs a list of images in a text file in a [specific format](https://trac.ffmpeg.org/wiki/Concatenate#demuxer) in order to convert them to a video. There's a couple ways to do this:
format](https://trac.ffmpeg.org/wiki/Concatenate#demuxer) in order to
convert them to a video. There\'s a couple ways to do this:
``` {.bash} ``` {.bash}
ls *.jpg | xargs -I xyz echo "file 'xyz'" > list.txt ls *.jpg | xargs -I xyz echo "file 'xyz'" > list.txt
@ -93,8 +74,7 @@ ls *.jpg | xargs -I xyz echo "file 'xyz'" > list.txt
for f in *.jpg; do echo "file '$f'" >> list.txt; done for f in *.jpg; do echo "file '$f'" >> list.txt; done
``` ```
It\'s up to preference, all end up with a list of all JPGs in current It's up to preference, all end up with a list of all JPGs in current directory, in `list.txt`.
directory, in `list.txt`.
##### 2. list to video ##### 2. list to video
@ -106,8 +86,7 @@ ffmpeg -f concat -r 30 -i list.txt out.mp4
`-r 30` specifies resulting FPS (30 FPS) `-r 30` specifies resulting FPS (30 FPS)
`out.mp4` is output file - autodetected as h264-encoded. (`out.avi`, `out.mp4` is output file - autodetected as h264-encoded. (`out.avi`, `out.gif`, etc. also work - refer to ffmpeg manual)
`out.gif`, etc. also work - refer to ffmpeg manual)
#### video -&gt; images #### video -&gt; images
@ -115,16 +94,11 @@ ffmpeg -f concat -r 30 -i list.txt out.mp4
ffmpeg -i FILE image%05d.png ffmpeg -i FILE image%05d.png
``` ```
Where `FILE` is the video file, and `image%05d.png` is the format string 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...)
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 ### Streams
`ffmpeg` can also smoothly handle streams, so basic stream capture is `ffmpeg` can also smoothly handle streams, so basic stream capture is pretty trivial, provided you grabbed the playlist/HLS url from somewhere[^6]:
pretty trivial, provided you grabbed the playlist/HLS url from
somewhere[^6]:
``` {.bash} ``` {.bash}
ffmpeg -i "https://example.com/playlist.m3u8" my_stream.mp4 ffmpeg -i "https://example.com/playlist.m3u8" my_stream.mp4
@ -132,9 +106,7 @@ ffmpeg -i "https://example.com/playlist.m3u8" my_stream.mp4
#### Taking a screenshot of a stream #### Taking a screenshot of a stream
`-vframes 1` is the option that tells `ffmpeg` to just capture one (i.e. `-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.
the first) frame of the video - in the case of streams, this means the
latest one anyway.
``` {.bash} ``` {.bash}
ffmpeg -i "https://example.com/playlist.m3u8" -vframes 1 capture.jpg ffmpeg -i "https://example.com/playlist.m3u8" -vframes 1 capture.jpg
@ -142,37 +114,16 @@ ffmpeg -i "https://example.com/playlist.m3u8" -vframes 1 capture.jpg
### dropped frame re-interpolation ### dropped frame re-interpolation
`ffmpeg` also has a [rich set of `ffmpeg` also has a [rich set of filters](https://ffmpeg.org/ffmpeg-filters.html), two of which are of interest for us now:
filters](https://ffmpeg.org/ffmpeg-filters.html), two of which are of
interest for us now:
- [mpdecimate](https://ffmpeg.org/ffmpeg-filters.html#mpdecimate) - - [mpdecimate](https://ffmpeg.org/ffmpeg-filters.html#mpdecimate) - *Drop frames that do not differ greatly from the previous frame in order to reduce frame rate.*
*Drop frames that do not differ greatly from the previous frame in - [minterpolate](https://ffmpeg.org/ffmpeg-filters.html#minterpolate) - *Convert the video to specified frame rate using motion interpolation.*
order to reduce frame rate.*
- [minterpolate](https://ffmpeg.org/ffmpeg-filters.html#minterpolate) -
*Convert the video to specified frame rate using motion
interpolation.*
The idea is that `mpdecimate` drops all near-duplicate frames, and The idea is that `mpdecimate` drops all near-duplicate frames, and `minterpolate` re-calculates them using non-duplicate frames that were left.
`minterpolate` re-calculates them using non-duplicate frames that were
left.
`mpdecimate`\'s defaults are pretty okay, but the result may not look `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.
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 `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.
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: **TL;DR**: Full command(s) including the filter pipeline:
@ -187,33 +138,9 @@ ffmpeg -i choppy_video.mp4 -vf mpdecimate=max=10,minterpolate=mi_mode=blend smoo
ffmpeg -i choppy_video.mp4 -vf mpdecimate,minterpolate smoother_video.mp4 ffmpeg -i choppy_video.mp4 -vf mpdecimate,minterpolate smoother_video.mp4
``` ```
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>))
*
> Set fixed rate of 25 frames per second:
> `setpts=N/(25*TB)`
- 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 ### mp4 compatibility
h264 also has \"profiles\", basically [sets of h264 also has "profiles", basically [sets of features](https://en.wikipedia.org/wiki/Advanced_Video_Coding#Profiles) - 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.
features](https://en.wikipedia.org/wiki/Advanced_Video_Coding#Profiles)
- 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 > > The `-profile:v` option limits the output to a specific H.264
> > profile. Some devices (mostly very old or obsolete) only support the > > profile. Some devices (mostly very old or obsolete) only support the
@ -226,9 +153,7 @@ projectors.
ffmpeg -i original.mp4 -profile:v baseline output.mp4 ffmpeg -i original.mp4 -profile:v baseline output.mp4
``` ```
And apparently, some players are also sensitive to the pixel format[^7], And apparently, some players are also sensitive to the pixel format[^7], 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:
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:
``` {.bash} ``` {.bash}
ffmpeg -i original.mp4 -pix_fmt yuv420p output.mp4 ffmpeg -i original.mp4 -pix_fmt yuv420p output.mp4
@ -236,15 +161,17 @@ ffmpeg -i original.mp4 -pix_fmt yuv420p output.mp4
ffmpeg -i original.mp4 -profile:v baseline -pix_fmt yuv420p output.mp4 ffmpeg -i original.mp4 -profile:v baseline -pix_fmt yuv420p output.mp4
``` ```
No silver bullet, you\'ll just have to try different things for 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.
different devices. A database of crappy players and appropriate `ffmpeg`
settings would be great.
### random ### random
<https://ottverse.com/ffmpeg-drawtext-filter-dynamic-overlays-timecode-scrolling-text-credits/> <https://ottverse.com/ffmpeg-drawtext-filter-dynamic-overlays-timecode-scrolling-text-credits/>
[^1]: <https://en.wikipedia.org/wiki/FFmpeg#Projects_using_FFmpeg> ---
# Footnotes
[^1]: See https://en.wikipedia.org/wiki/FFmpeg#Projects_using_FFmpeg
[^2]: from <https://ffmpeg.zeranoe.com/builds/> [^2]: from <https://ffmpeg.zeranoe.com/builds/>
@ -254,8 +181,6 @@ settings would be great.
[^5]: and respectively, formats with `ffmpeg -formats` [^5]: and respectively, formats with `ffmpeg -formats`
[^6]: like [^6]: like <https://addons.mozilla.org/en-US/firefox/addon/hls-stream-detector/>; or just press F12, check the Network tab, and look carefully
<https://addons.mozilla.org/en-US/firefox/addon/hls-stream-detector/>;
or just press F12, check the Network tab, and look carefully
[^7]: <https://trac.ffmpeg.org/wiki/Encode/H.264#Encodingfordumbplayers> [^7]: From: https://trac.ffmpeg.org/wiki/Encode/H.264#Encodingfordumbplayers