hello friends! new(ish)!
WebM: Difference between revisions
>Hevnoraak (Major re-organization of content; command-line params tutorial) |
>32yGeLMN (4chan VP9/Opus update) |
||
(62 intermediate revisions by 26 users not shown) | |||
Line 1: | Line 1: | ||
{{TOCright}} | |||
WebM is an audiovisual media file format. It is primarily intended to offer a royalty-free alternative to use in the HTML5 video and the HTML5 audio elements. It has a sister project, WebP, which is a shitty image format that nobody cares about. The development of WebM is unfortunately sponsored by Google, and the corresponding software is distributed under [[Cuck license|some BSD license]]. On imageboards WebMs serve the same purpose as GIFs, that is, to encode short clips of anime, pornography and cartel beheading videos. | |||
WebM | The WebM container is based on a profile of Matroska. WebM initially supported VP8 video and Vorbis audio streams. In 2013, it was updated to accommodate VP9 video and Opus audio, however it took 4chan until July 2022 to implement it. WebM also supports the new AV1 video codec, but 4chan currently does not. | ||
This wiki page is meant to serve as an instructional tool to help you get started converting your content to WebM for posting. | |||
== General info == | |||
See a list of useful archived 4chan threads further down the page | |||
=== 4chan limitations === | |||
Current limits for WebM files on 4chan are: | |||
... and | *Maximum file size is 4096KB for /gif/ and 6144KB for /wsg/. | ||
*Maximum duration is 300 seconds (5 minutes). | |||
*Maximum resolution is 2048x2048 pixels. | |||
*No audio streams except on /gif/ and /wsg/. (use -an) | |||
== Converting with ffmpeg == | == Converting with ffmpeg == | ||
Line 14: | Line 23: | ||
'''Note:''' avconv and ffmpeg are not entirely drop-in replacements. Make sure you know which one you are using. | '''Note:''' avconv and ffmpeg are not entirely drop-in replacements. Make sure you know which one you are using. | ||
=== Command | '''OS X Users:''' The homebrew version of ffmpeg doesn't include WebM support by default, try '''brew install ffmpeg --with-libvpx'''. | ||
=== Command line options === | |||
==== The basic command ==== | |||
:<code>ffmpeg -i input.mkv output.webm</code> | |||
Wow! Is it really that easy? Yes. Yes it is. However, this will give you a really shitty WebM that everyone will mock you for. You might as well be posting GIFs. In order to make good quality WebMs, we need to add extra options to fine-tune it. | |||
First, let's examine the structure of an ffmpeg command: | |||
:<code>ffmpeg</code> | |||
:Starts the ffmpeg program you have on your computer. Pretty straightforward. | |||
:<code>-i input.mkv</code> | |||
:The file you want to convert. You always need an -i in front. If the filename has spaces you need to enclose it in quotes: <code>-i "my file.mkv"</code> | |||
:<code>output.webm</code> | |||
:The name of the converted WebM. | |||
==== A more detailed ffmpeg command==== | |||
{{bc|ffmpeg -i input.mp4 -c:v libvpx-vp9 -b:v 1M -c:a libopus output.webm}} | |||
This may look intimidating but it is not all that bad. Let's look at the different parameters: | This may look intimidating but it is not all that bad. Let's look at the different parameters: | ||
* '''-i''': Specifies the input file, which you're converting to another format. | * '''-i''': Specifies the input file, which you're converting to another format. | ||
* '''-c:v''' Specifies the video codec to use. | * '''-c:v''' Specifies the video codec to use. Follow it with "libvpx-vp9" to use the VP9 video codec. | ||
* '''-b''': Sets the target bitrate. '''-b:v''' sets video bitrate and '''-b:a''' sets audio. Only use this option if you desire a constant bitrate, which will produce a higher quality file. If you are looking for a smaller file size, consider leaving this out. | * '''-b''': Sets the target bitrate. '''-b:v''' sets video bitrate and '''-b:a''' sets audio. Only use this option if you desire a constant bitrate, which will produce a higher quality file. If you are looking for a smaller file size, consider leaving this out. | ||
* '''-c:a''': Specifies the audio codec to use. Some options | * '''-c:a''': Specifies the audio codec to use. Follow it with "libopus" to use the Opus audio codec. | ||
Other useful options: | |||
* '''-threads''': Tells ffmpeg to use multithreading, speeding up the encoding process. Enter the number of cores your processor has -1 as a parameter (for quadcore, use -threads 3) <s>or put 0 to use them all</s>. VP8 and VP9 cannot auto-detect the amount of cores your processor has, so using -threads 0 is equivalent to using -threads 1. Be aware that using multithreading may slightly lower output quality and have the effect that repeat encodes do not have identical results. | |||
* '''-ac''': Sets number of audio channels, normally 2 or 1. Sometimes setting to 1 will give you a smaller filesize. You should probably not touch this unless you know what you're doing. | |||
* '''-an''': Disable audio. Use when converting .gif files to .webm. | |||
* '''-sn''': Disable subtitles. | |||
* '''-ss''': Seeks to a position in the file. Useful for cutting out small scenes. Takes time in seconds as a parameter or HH:MM:SS syntax. use '''-t''' in tandem to set the file duration. For example, {{ic|-t 00:00:10 }} cuts out the first ten seconds of the video for conversion, and {{ic|-ss 00:00:10 -t 00:00:10}} would skip the first ten seconds and cut out the next ten for conversion. | |||
* '''-speed''': Controls the speed at which the video is encoded. Faster speeds come at the expense of lower quality and larger filesizes. Use -speed 0 for maximum quality and lowest filesizes. | |||
* '''-qmin''' and '''-qmax''': Tells ffmpeg what "quantization parameter" to use when assigning quality. Don't worry if you don't know what a quantization parameter is, because neither do I. All I know is that lower numbers = better quality. I believe the -qmax option prevents the quality from dropping below a certain level for any given frame, so the overall video quality will be more consistent (it prevents you from getting certain frames in your video which are of absolutely dreadful quality where everything is blocky as fuck, basically). Recommended values: -qmin 0 -qmax 50 | |||
* '''-crf''': Sets CRF value. Must be from 4-63 in VP8, or 0-63 in VP9. Lower is higher quality. 10 the recommended setting. There are two ways of using CRF - 1) "Constant Quality" mode, 2) "Constrained Quality" mode. | |||
**1) To use constant quality mode, you MUST use a value of "0" when specifying the video bitrate (-b:v 0). If you just remove the "-b:v" option altogether, ffmpeg will simply fall back on the default bitrate (256K, I think), which will result in a constrained quality encode with extremely poor quality. Constant quality mode tries to achieve a... well... constant level of quality, using whatever bitrate is necessary to achieve that level of quality. This can result in very large file sizes, so is generally not suitable for making WebMs intended for imageboards which typically have a file size limit of 10MB or less. Example command: {{ic|ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 10 -b:v 0 -c:a libopus output.webm}} | |||
**2) To use constrained quality mode, you must specify both a CRF value (e.g. -crf 10) AND a video bitrate value (e.g. -b:v 1M). Constrained quality mode will try to achieve a certain level of quality, but without going over a specified bitrate level. When -b:v is used without -crf, the value of -b:v is a ''target'' bitrate, but when -b:v and -crf are used together, -b:v becomes a ''maximum'' bitrate. This is a way of achieving high quality while still retaining control over the filesize. Ideally it should be used with the 2-pass encoding method. Example command: {{ic|ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 10 -b:v 1M -c:a libopus output.webm}} | |||
=== How seeking works in ffmpeg === | |||
ffmpeg has two seeking modes: | |||
* input file seeking (put the -ss START before the -i input file) | |||
:<code>ffmpeg -ss START -i "INPUT.mkv" output.webm</code> | |||
This will take all data from the time specified at START. It starts transcoding from the specified time instantly, but the timestamps in the output file will be reset to 0, so if you attach subtitles, it will transcode them '''from the beginning of the subtitle file'''. You can also add the -t/-to options to specify an endpoint of transcoding, too. | |||
* ouput file seeking (put the -ss START after the -i input file and before the output file) | |||
:<code>ffmpeg -i "INPUT.mkv" -ss START output.webm</code> | |||
This will also take all data from the time specified at START, however, it will first transcode everything up to that point, but throw it away. This is slower than the previous option, because of that seeking, but it does keep the timestamps in the output, so if you add subtitles, it will add the ones at the right time. Again, you can use the -t/-to options to specify an endpoint of transcoding. | |||
=== Calculating the best bitrate to fit within the size limit === | |||
4chan limits file sizes to 4MB. To find the maximum bitrate that will keep your WebM within 4MB, for example you can do a simple calculation. | |||
:(4MB/seconds)*8 = bitrate. | |||
For example, let's say you have a 10 second clip you want to post. | |||
:4MB/10 seconds = .4MB/s. | |||
Since bitrate is measured in bits(b) and not bytes (B), multiply by 8 to get the final bitrate: | |||
:3.2M. | |||
However, the encoder is not always exact, so you may end up going over or under. Just adjust your bitrate and try again. | |||
=== 2-pass encoding === | |||
You may utilise the 2-pass encoding method in order to increase the quality of your video, at the expense of making the encoding process a little longer. During 2-pass encoding, you will make one "pass" through the video where the encoder simply collects information about the video you want to make a WebM from, and then a second "pass" where you encode the video for real utilising the information collected during the first "pass". The advantage of this is that the encoder knows what to expect when encoding the video and doesn't have to guess whether the next frame is going to be a difficult frame or not depending on how difficult the previous frames were. This results in a better allocation of bits, and thus better quality. | |||
Here is an example: | |||
*First pass: {{ic|ffmpeg -i input.mp4 -c:v libvpx-vp9 -pass 1 -qmin 0 -qmax 50 -crf 10 -b:v 1M -threads 1 -tile-columns 0 -speed 4 -g 128 -aq-mode 0 -an -sn -f webm /dev/null}} | |||
*Second pass: {{ic|ffmpeg -i input.mp4 -c:v libvpx-vp9 -pass 2 -qmin 0 -qmax 50 -crf 10 -b:v 1M -c:a libopus -b:a 64K -vbr on -threads 1 -tile-columns 0 -speed 0 -auto-alt-ref 1 -lag-in-frames 25 -g 128 -aq-mode 0 -sn -f webm output.webm}} | |||
=== Using filters with -vf === | |||
The '''-vf''' flag allows you to define 'filters' which can help you further manipulate the file. The syntax for this looks something like {{ic|1=-vf <filter>=<param>,<filter>=<param>}}. Use {{ic|ffmpeg -filters}} to get a list of filters and how to use them. Some of the more common ones will be explored below. | |||
* '''scale''': Scale takes two arguments separated by a colon, which are width and height respectively. If you enter -1 for either variable, ffmpeg will scale the video based off of the aspect ratio of the source file. An example of this would be {{ic|1=-vf scale=640:-1}}, though it is preferable to use -2 which will ensure that the resolution is divisible by 2. | |||
* '''crop''': Crop the input video to given dimensions. Takes 4 arguments: width:height:left:top. For example {{ic|1=-vf crop=200:100:50:10}} will crop a 200x100 rectangle 50px left from the border and 10 from the top. | |||
* '''rotate''': Takes 1 argument in radians, can use PI as a variable: For example {{ic|1=-vf rotate=PI}} will rotate a video 180 degrees, {{ic|1=-vf rotate=PI/2}} will rotate a video 90 degrees, {{ic|1=-vf rotate=PI*45/180}} will rotate a video 45 degrees. | |||
== Common applications of ffmpeg == | |||
=== Metadata === | |||
To simply print metadata about a video file: {{ic|ffmpeg -i input_file -f ffmetadata metadata.txt}} | |||
=== Extract a snippet of video === | |||
To extract a snippet of video from a long video, all you need to do is input the time the clip begins and the length. | |||
:<code>-ss START -t DURATION</code> | |||
Or, you can specify the end time instead of the duration: | |||
:<code>-ss START -to END</code> | |||
Time format of start and end is generally hh:mm:ss. | |||
[https://trac.ffmpeg.org/wiki/Seeking Here's the ffmpeg tutorial on using the cut option] | |||
=== Resizing === | |||
:<code>-vf scale=-1:HEIGHT</code> | |||
=== Hardsubbing === | |||
First, extract the sub file. | |||
:<code>ffmpeg -i "INPUT.mkv" -an -vn -c copy "SUB.ass"</code> | |||
Add this to your options | |||
:<code> -vf subtitles="SUB.ass"</code> | |||
Unfortunately, if you use input seeking it fucks up. Use output seeking only. | |||
=== Cropping === | |||
:<code>-vf "crop=WIDTH:HEIGHT:TOP:LEFT"</code> | |||
=== Joining clips together === | |||
To join 2 or more clips, create a text file containing the name of the files like this: | |||
{{bc|<nowiki> | |||
file 'file1.webm' | |||
file 'file2.webm' | |||
file 'file3.webm' | |||
</nowiki>}} | |||
Then call ffmpeg: {{ic|1=ffmpeg -f concat -i files.txt -c copy output.webm}} | |||
=== Reverse a video === | |||
Use the following command to reverse a video: | |||
{{bc|<nowiki> | |||
ffmpeg -i input.webm -vf reverse out.webm | |||
</nowiki>}} | |||
=== Downloading from YouTube === | |||
If you want to download YouTube videos, use youtube-dl: https://rg3.github.io/youtube-dl/ | |||
GNU/Linux users can find this in their package managers. | |||
Download that and extract it wherever you want | |||
Open your command prompt (Windows+R and then type cmd and press enter) | |||
Paste these 2 commands: | |||
cd C:\folder\path\where\youtube-dl.exe\is\located | |||
youtube-dl.exe https://www.youtube.com/ThisIsTheLinkToTheVideoYouWantToDownload | |||
And that's it. The program will start downloading the YouTube video. From here on you can trim it, resize it, etc. | |||
There are also other alternatives, like | |||
http://en.savefrom.net/ | |||
== More advanced ffmpeg use == | |||
=== Manipulating individual video, audio and subtitle streams === | |||
Each file is made up of 1 or more streams: video, audio. or subtitle stream(s). They's sometimes also called channels or tracks. | |||
Each stream in a file is numbered from 0 upwards. Stream types can also be accessed via the letters v/a/s for video/audio/subtitle respectively. | |||
Ffmpeg can also take multiple input files: | |||
:<code>ffmpeg -i FILE.mkv -i OTHERFILE.mkv</code> | |||
Numbered in order from 0 upwards. By default, if you only use one file, it will be numbered 0. | |||
ffmpeg uses the -map option to map multiple inputs to the one output. For example, if you want to map the audio and video stream of a file to the output file, you would do this: | |||
:<code>ffmpeg -i FILE.mkv -map 0:a -map 0:v OUTPUT.webm</code> | |||
-map 0:a means "use the audio stream of the first file. -map 0:v says you want to use the video stream of the first file | |||
But what if there are multiple streams of the same type? i.e. multiple subtitle streams? By default, ffmpeg takes the first of each type of stream, but you can specifiy what you want: | |||
:<code>ffmpeg -i FILE.mkv -map 0:a -map 0:v -map 0:1:s OUTPUT.webm</code> | |||
This next command tells ffmpeg to take the audio stream and the video stream of the first file, and the subtitle stream of the second file: | |||
:<code>ffmpeg -i FILE.mkv -i FILE2.mkv -map -0:a 0:v 1:s OUTPUT.webm</code> | |||
[https://trac.ffmpeg.org/wiki/How%20to%20use%20-map%20option Here's the ffmpeg guide on using -map] | |||
== General tips == | |||
- Bitrate is more important than resolution for a video's quality. Don't upscale your videos, increase the bitrate instead. | |||
- Summarize your content as much as you can. No need to make 2 min WebMs if you can show what you wanted in 10 seconds or less. | |||
- Don't post WebMs that are above 720p unless you know what you're doing. 720p and 480p are more than enough for most things. | |||
- Don't record in 1080p only to downscale it later. Record your screen in 720p or less. | |||
- Don't record at more than 30 fps unless you want to show how good your game looks at higher framerates. | |||
- The more the camera moves, the bigger the file size you're going to get. When recording, try to minimize unnecessary camera movements. | |||
- The more general movement there is on a video, the bigger the file size you're going to get. Even if your camera is standing still, if there are lots of things happening on your screen, the file size is going to increase. | |||
- If the quality is not good enough, lower the resolution. A 720p at 500 kbps video is going to look worse than a 480p at 500 kbps video, even when you upscale the 480p video to 720p. | |||
== Issues == | |||
=== Seeking issue with VP9 === | |||
VP9 currently has a stupid default value (9999, i.e. infinite) for the maximum interval between keyframes, which can result in only a single keyframe being created at the very beginning of the video causing the following seeking issues during playback: | |||
*Trying to navigate forwards through the video using the arrow keys on your keyboard causes the audio to skip ahead but the video to freeze. | |||
* | *Trying to navigate backwards causes the video to skip right back to the first frame. | ||
*Precise seeking using mouse clicks is very slow; after clicking somewhere on the progress bar, there will be a delay of several seconds before the video actually skips to that point. | |||
* | |||
If you encounter this problem, it is easily fixed with the -g option. The default value in VP8 for this option was 128, so try that first ("-g 128"). If seeking issues persist, try lowering the interval further (e.g. "-g 64"). | |||
== Scripts and GUIs == | |||
=== Windows === | |||
Save these programs as a .bat file and place them in the folder of the video you want to convert. | Save these programs as a .bat file and place them in the folder of the video you want to convert. | ||
==== Linux / OS X | ''Video to WebM''' | ||
{{bc|<nowiki>@echo off | |||
rem about 3megabyte in bit 3*1024*1024*8*0.95 | |||
set /A MAXSIZE=23907532 | |||
set WIDTH=720 | |||
ffmpeg -i %1 2> webm.tmp | |||
for /F "tokens=1,2,3,4,5,6 delims=:., " %%i in (webm.tmp) do ( | |||
if "%%i"=="Duration" call :calcLength %%j %%k %%l %%m | |||
) | |||
del webm.tmp | |||
SET /a BITRATE=%MAXSIZE%/%VSECONDS% | |||
ffmpeg -y -i %1 -threads 0 -sn -an -c:v libvpx -b:v %BITRATE% -vf scale=-1:%WIDTH% -quality best -cpu-used 0 -slices 8 -auto-alt-ref 1 -f webm -pass 1 NUL | |||
ffmpeg -y -i %1 -threads 0 -sn -an -c:v libvpx -b:v %BITRATE% -vf scale=-1:%WIDTH% -quality best -cpu-used 0 -slices 8 -auto-alt-ref 1 -f webm -pass 2 %~n1.webm" | |||
del ffmpeg2pass-0.log > NUL | |||
goto :EOF | |||
:calcLength | |||
FOR /F "tokens=* delims=0" %%A IN ("%3") DO SET /A s=%%A | |||
FOR /F "tokens=* delims=0" %%A IN ("%2") DO SET /A s=s+%%A*60 | |||
FOR /F "tokens=* delims=0" %%A IN ("%1") DO SET /A s=s+%%A*60*60 | |||
set /A VSECONDS=s | |||
</nowiki>}} | |||
'''gif to webm''' | |||
{{bc|@ECHO OFF | |||
ffmpeg -y -i "%~1" -b:v 3M -quality best -cpu-used 0 -slices 8 "%~1.webm"}} | |||
=== Linux / OS X === | |||
If you're using OS X or Linux, you probably know how to save and execute these scripts already, but here's a quick overview: | If you're using OS X or Linux, you probably know how to save and execute these scripts already, but here's a quick overview: | ||
# Create a file, such as | # Create a file, such as {{ic|~/bin/my_script.sh}} | ||
# Copy and paste the code into this file with your favorite editor. | # Copy and paste the code into this file with your favorite editor. | ||
# Open a shell. Run the command | # Open a shell. Run the command {{ic|chmod +x ~/bin/my_script.sh}} | ||
# The script can now be called as | # The script can now be called as {{ic|~/bin/my_script.sh some_file.type}} or if you have your PATH set correctly, {{ic|my_script.sh some_file.type}} | ||
'''webm.bash''' | |||
It does interactive cropping with mplayer, interactive selection of start and end times with mplayer, hardsubs, and has many more options. | |||
https://gist.github.com/interjection/4b83c0790ce82982caec | |||
'''.gif Convert''' | |||
{{bc|#!/bin/bash | |||
ffmpeg -i $1 -threads 0 -cpu-used 0 -c:v libvpx -f webm -b:v 700k -quality good -qmin 10 -qmax 42 -an /dev/null | |||
ffmpeg -i $1 -threads 0 -cpu-used 0 -c:v libvpx -f webm -b:v 700k -quality good -qmin 10 -qmax 42 -an "$F"}} | |||
'''High-End Video Convert''' | |||
{{bc|#!/bin/bash | |||
# Warning: this script will probably take up a lot of CPU usage. Don't crash your machine. | |||
ffmpeg -i $1 -threads 0 -cpu-used 0 -c:v libvpx -c:a libopus -ac 2 -qmin 0 -qmax 10 -bufsize 1000k -quality good -crf 4 -b:v 2M -pass 1 /dev/null | |||
ffmpeg -i $1 -threads 0 -cpu-used 0 -c:v libvpx -c:a libopus -ac 2 -qmin 0 -qmax 10 -bufsize 1000k -quality good -crf 4 -b:v 2M -pass 1 "$1".webm}} | |||
̈́'''Split Video''' | |||
{{bc|<nowiki>#!/bin/bash | |||
# Takes a large video file and splits it into multiple 3MB webm files | |||
crf=18 | |||
bitrate=500K | |||
threads=8 | |||
# Duration of original video in seconds | |||
duration=$(expr `mediainfo --Inform="General;%Duration%" "$1"` / 1000) | |||
sec=0 | |||
j=1 | |||
until (($sec >= $duration)) | |||
do | |||
ffmpeg -ss $sec -i "$1" -an -sn -threads $threads -c:v libvpx -crf $crf -b:v $bitrate -fs 3M $j.webm | |||
# Duration of previous video is added to the sum of every previous video | |||
sec=$(expr $(expr `mediainfo --Inform="General;%Duration%" $j.webm` / 1000) + $sec) | |||
j=$((j+1)) | |||
done</nowiki> | |||
}} | |||
'''Poster Image with Audio''' | |||
{{bc|ffmpeg -r 1 -loop 1 -i 1.png -i 1.wav -c:v libvpx -c:a libopus -b:a 64k -shortest out.webm}} | |||
== GUI options == | |||
=== Recorders === | |||
[[File:Webm cam screenshot.png|right|thumb|WebMCam]] | |||
;WebMCam | |||
:Records the selected area and saves the output as WebM, just like GifCam does it with GIFs. | |||
:https://github.com/TheTarkus/WebMCam/ | |||
=== Converters === | |||
*[https://gist.github.com/Zehkul/25ea7ae77b30af959be0 convert_script.lua] - A lua script for mpv to convert, crop, resize and encode directly from the mpv window. | |||
*https://github.com/Wsheerio/webmConverter | |||
*https://gitgud.io/nixx/WebMConverter - Most up-to-date converter for Windows. | |||
*https://github.com/rzumer/Webbum - Also supports AV1 | |||
*https://firefogg.org - Requires the Firefogg extension, will only work in Firefox. | |||
You can also refer to [[Recommended_software]] for video editing and converting programs. | |||
== | == External resources == | ||
=== List of stickies / test threads === | |||
*https://rbt.asia/g/thread/S41184007 | |||
*https://rbt.asia/g/thread/S41183707 | |||
*https://rbt.asia/g/thread/S41178861 | |||
*https://rbt.asia/g/thread/S41190521 | |||
*https://rbt.asia/g/thread/S41212767#p41212767 | |||
=== Further links === | |||
#https://trac.ffmpeg.org/wiki/vpxEncodingGuide | #https://trac.ffmpeg.org/wiki/vpxEncodingGuide | ||
#WebM of a WebM tutorial: https://rbt.asia/boards/g/img/0411/75/1396646705233.webm | #WebM of a WebM tutorial: https://rbt.asia/boards/g/img/0411/75/1396646705233.webm | ||
Line 77: | Line 358: | ||
#http://wiki.webmproject.org/ffmpeg | #http://wiki.webmproject.org/ffmpeg | ||
#N0Lif3's Windows tutorial: https://www.youtube.com/watch?v=WeM3SUp-HRg | #N0Lif3's Windows tutorial: https://www.youtube.com/watch?v=WeM3SUp-HRg | ||
#http://wiki.webmproject.org/ffmpeg/vp9-encoding-guide | |||
#https://github.com/Kagami/webm.py/wiki/Notes-on-encoding-settings | |||
#https://trac.ffmpeg.org/wiki/Encode/VP8 | |||
#https://trac.ffmpeg.org/wiki/Encode/VP9 | |||
#http://forum.doom9.org/showthread.php?t=168947 | |||
#http://slhck.info/video-encoding | |||
#The "ultimate WebM guide" for ffmpeg: https://github.com/vp8m8/webm-guide | |||
[[Category:Software]] | |||
[[Category:HowTo]] |
Latest revision as of 16:49, 7 July 2022
WebM is an audiovisual media file format. It is primarily intended to offer a royalty-free alternative to use in the HTML5 video and the HTML5 audio elements. It has a sister project, WebP, which is a shitty image format that nobody cares about. The development of WebM is unfortunately sponsored by Google, and the corresponding software is distributed under some BSD license. On imageboards WebMs serve the same purpose as GIFs, that is, to encode short clips of anime, pornography and cartel beheading videos.
The WebM container is based on a profile of Matroska. WebM initially supported VP8 video and Vorbis audio streams. In 2013, it was updated to accommodate VP9 video and Opus audio, however it took 4chan until July 2022 to implement it. WebM also supports the new AV1 video codec, but 4chan currently does not.
This wiki page is meant to serve as an instructional tool to help you get started converting your content to WebM for posting.
General info
See a list of useful archived 4chan threads further down the page
4chan limitations
Current limits for WebM files on 4chan are:
- Maximum file size is 4096KB for /gif/ and 6144KB for /wsg/.
- Maximum duration is 300 seconds (5 minutes).
- Maximum resolution is 2048x2048 pixels.
- No audio streams except on /gif/ and /wsg/. (use -an)
Converting with ffmpeg
Note: avconv and ffmpeg are not entirely drop-in replacements. Make sure you know which one you are using.
OS X Users: The homebrew version of ffmpeg doesn't include WebM support by default, try brew install ffmpeg --with-libvpx.
Command line options
The basic command
ffmpeg -i input.mkv output.webm
Wow! Is it really that easy? Yes. Yes it is. However, this will give you a really shitty WebM that everyone will mock you for. You might as well be posting GIFs. In order to make good quality WebMs, we need to add extra options to fine-tune it.
First, let's examine the structure of an ffmpeg command:
ffmpeg
- Starts the ffmpeg program you have on your computer. Pretty straightforward.
-i input.mkv
- The file you want to convert. You always need an -i in front. If the filename has spaces you need to enclose it in quotes:
-i "my file.mkv"
output.webm
- The name of the converted WebM.
A more detailed ffmpeg command
ffmpeg -i input.mp4 -c:v libvpx-vp9 -b:v 1M -c:a libopus output.webm
This may look intimidating but it is not all that bad. Let's look at the different parameters:
- -i: Specifies the input file, which you're converting to another format.
- -c:v Specifies the video codec to use. Follow it with "libvpx-vp9" to use the VP9 video codec.
- -b: Sets the target bitrate. -b:v sets video bitrate and -b:a sets audio. Only use this option if you desire a constant bitrate, which will produce a higher quality file. If you are looking for a smaller file size, consider leaving this out.
- -c:a: Specifies the audio codec to use. Follow it with "libopus" to use the Opus audio codec.
Other useful options:
- -threads: Tells ffmpeg to use multithreading, speeding up the encoding process. Enter the number of cores your processor has -1 as a parameter (for quadcore, use -threads 3)
or put 0 to use them all. VP8 and VP9 cannot auto-detect the amount of cores your processor has, so using -threads 0 is equivalent to using -threads 1. Be aware that using multithreading may slightly lower output quality and have the effect that repeat encodes do not have identical results. - -ac: Sets number of audio channels, normally 2 or 1. Sometimes setting to 1 will give you a smaller filesize. You should probably not touch this unless you know what you're doing.
- -an: Disable audio. Use when converting .gif files to .webm.
- -sn: Disable subtitles.
- -ss: Seeks to a position in the file. Useful for cutting out small scenes. Takes time in seconds as a parameter or HH:MM:SS syntax. use -t in tandem to set the file duration. For example,
-t 00:00:10
cuts out the first ten seconds of the video for conversion, and-ss 00:00:10 -t 00:00:10
would skip the first ten seconds and cut out the next ten for conversion. - -speed: Controls the speed at which the video is encoded. Faster speeds come at the expense of lower quality and larger filesizes. Use -speed 0 for maximum quality and lowest filesizes.
- -qmin and -qmax: Tells ffmpeg what "quantization parameter" to use when assigning quality. Don't worry if you don't know what a quantization parameter is, because neither do I. All I know is that lower numbers = better quality. I believe the -qmax option prevents the quality from dropping below a certain level for any given frame, so the overall video quality will be more consistent (it prevents you from getting certain frames in your video which are of absolutely dreadful quality where everything is blocky as fuck, basically). Recommended values: -qmin 0 -qmax 50
- -crf: Sets CRF value. Must be from 4-63 in VP8, or 0-63 in VP9. Lower is higher quality. 10 the recommended setting. There are two ways of using CRF - 1) "Constant Quality" mode, 2) "Constrained Quality" mode.
- 1) To use constant quality mode, you MUST use a value of "0" when specifying the video bitrate (-b:v 0). If you just remove the "-b:v" option altogether, ffmpeg will simply fall back on the default bitrate (256K, I think), which will result in a constrained quality encode with extremely poor quality. Constant quality mode tries to achieve a... well... constant level of quality, using whatever bitrate is necessary to achieve that level of quality. This can result in very large file sizes, so is generally not suitable for making WebMs intended for imageboards which typically have a file size limit of 10MB or less. Example command:
ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 10 -b:v 0 -c:a libopus output.webm
- 2) To use constrained quality mode, you must specify both a CRF value (e.g. -crf 10) AND a video bitrate value (e.g. -b:v 1M). Constrained quality mode will try to achieve a certain level of quality, but without going over a specified bitrate level. When -b:v is used without -crf, the value of -b:v is a target bitrate, but when -b:v and -crf are used together, -b:v becomes a maximum bitrate. This is a way of achieving high quality while still retaining control over the filesize. Ideally it should be used with the 2-pass encoding method. Example command:
ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 10 -b:v 1M -c:a libopus output.webm
- 1) To use constant quality mode, you MUST use a value of "0" when specifying the video bitrate (-b:v 0). If you just remove the "-b:v" option altogether, ffmpeg will simply fall back on the default bitrate (256K, I think), which will result in a constrained quality encode with extremely poor quality. Constant quality mode tries to achieve a... well... constant level of quality, using whatever bitrate is necessary to achieve that level of quality. This can result in very large file sizes, so is generally not suitable for making WebMs intended for imageboards which typically have a file size limit of 10MB or less. Example command:
How seeking works in ffmpeg
ffmpeg has two seeking modes:
- input file seeking (put the -ss START before the -i input file)
ffmpeg -ss START -i "INPUT.mkv" output.webm
This will take all data from the time specified at START. It starts transcoding from the specified time instantly, but the timestamps in the output file will be reset to 0, so if you attach subtitles, it will transcode them from the beginning of the subtitle file. You can also add the -t/-to options to specify an endpoint of transcoding, too.
- ouput file seeking (put the -ss START after the -i input file and before the output file)
ffmpeg -i "INPUT.mkv" -ss START output.webm
This will also take all data from the time specified at START, however, it will first transcode everything up to that point, but throw it away. This is slower than the previous option, because of that seeking, but it does keep the timestamps in the output, so if you add subtitles, it will add the ones at the right time. Again, you can use the -t/-to options to specify an endpoint of transcoding.
Calculating the best bitrate to fit within the size limit
4chan limits file sizes to 4MB. To find the maximum bitrate that will keep your WebM within 4MB, for example you can do a simple calculation.
- (4MB/seconds)*8 = bitrate.
For example, let's say you have a 10 second clip you want to post.
- 4MB/10 seconds = .4MB/s.
Since bitrate is measured in bits(b) and not bytes (B), multiply by 8 to get the final bitrate:
- 3.2M.
However, the encoder is not always exact, so you may end up going over or under. Just adjust your bitrate and try again.
2-pass encoding
You may utilise the 2-pass encoding method in order to increase the quality of your video, at the expense of making the encoding process a little longer. During 2-pass encoding, you will make one "pass" through the video where the encoder simply collects information about the video you want to make a WebM from, and then a second "pass" where you encode the video for real utilising the information collected during the first "pass". The advantage of this is that the encoder knows what to expect when encoding the video and doesn't have to guess whether the next frame is going to be a difficult frame or not depending on how difficult the previous frames were. This results in a better allocation of bits, and thus better quality.
Here is an example:
- First pass:
ffmpeg -i input.mp4 -c:v libvpx-vp9 -pass 1 -qmin 0 -qmax 50 -crf 10 -b:v 1M -threads 1 -tile-columns 0 -speed 4 -g 128 -aq-mode 0 -an -sn -f webm /dev/null
- Second pass:
ffmpeg -i input.mp4 -c:v libvpx-vp9 -pass 2 -qmin 0 -qmax 50 -crf 10 -b:v 1M -c:a libopus -b:a 64K -vbr on -threads 1 -tile-columns 0 -speed 0 -auto-alt-ref 1 -lag-in-frames 25 -g 128 -aq-mode 0 -sn -f webm output.webm
Using filters with -vf
The -vf flag allows you to define 'filters' which can help you further manipulate the file. The syntax for this looks something like -vf <filter>=<param>,<filter>=<param>
. Use ffmpeg -filters
to get a list of filters and how to use them. Some of the more common ones will be explored below.
- scale: Scale takes two arguments separated by a colon, which are width and height respectively. If you enter -1 for either variable, ffmpeg will scale the video based off of the aspect ratio of the source file. An example of this would be
-vf scale=640:-1
, though it is preferable to use -2 which will ensure that the resolution is divisible by 2.
- crop: Crop the input video to given dimensions. Takes 4 arguments: width:height:left:top. For example
-vf crop=200:100:50:10
will crop a 200x100 rectangle 50px left from the border and 10 from the top.
- rotate: Takes 1 argument in radians, can use PI as a variable: For example
-vf rotate=PI
will rotate a video 180 degrees,-vf rotate=PI/2
will rotate a video 90 degrees,-vf rotate=PI*45/180
will rotate a video 45 degrees.
Common applications of ffmpeg
Metadata
To simply print metadata about a video file: ffmpeg -i input_file -f ffmetadata metadata.txt
Extract a snippet of video
To extract a snippet of video from a long video, all you need to do is input the time the clip begins and the length.
-ss START -t DURATION
Or, you can specify the end time instead of the duration:
-ss START -to END
Time format of start and end is generally hh:mm:ss.
Here's the ffmpeg tutorial on using the cut option
Resizing
-vf scale=-1:HEIGHT
Hardsubbing
First, extract the sub file.
ffmpeg -i "INPUT.mkv" -an -vn -c copy "SUB.ass"
Add this to your options
-vf subtitles="SUB.ass"
Unfortunately, if you use input seeking it fucks up. Use output seeking only.
Cropping
-vf "crop=WIDTH:HEIGHT:TOP:LEFT"
Joining clips together
To join 2 or more clips, create a text file containing the name of the files like this:
file 'file1.webm' file 'file2.webm' file 'file3.webm'
Then call ffmpeg: ffmpeg -f concat -i files.txt -c copy output.webm
Reverse a video
Use the following command to reverse a video:
ffmpeg -i input.webm -vf reverse out.webm
Downloading from YouTube
If you want to download YouTube videos, use youtube-dl: https://rg3.github.io/youtube-dl/
GNU/Linux users can find this in their package managers.
Download that and extract it wherever you want Open your command prompt (Windows+R and then type cmd and press enter) Paste these 2 commands: cd C:\folder\path\where\youtube-dl.exe\is\located youtube-dl.exe https://www.youtube.com/ThisIsTheLinkToTheVideoYouWantToDownload
And that's it. The program will start downloading the YouTube video. From here on you can trim it, resize it, etc.
There are also other alternatives, like http://en.savefrom.net/
More advanced ffmpeg use
Manipulating individual video, audio and subtitle streams
Each file is made up of 1 or more streams: video, audio. or subtitle stream(s). They's sometimes also called channels or tracks. Each stream in a file is numbered from 0 upwards. Stream types can also be accessed via the letters v/a/s for video/audio/subtitle respectively. Ffmpeg can also take multiple input files:
ffmpeg -i FILE.mkv -i OTHERFILE.mkv
Numbered in order from 0 upwards. By default, if you only use one file, it will be numbered 0.
ffmpeg uses the -map option to map multiple inputs to the one output. For example, if you want to map the audio and video stream of a file to the output file, you would do this:
ffmpeg -i FILE.mkv -map 0:a -map 0:v OUTPUT.webm
-map 0:a means "use the audio stream of the first file. -map 0:v says you want to use the video stream of the first file
But what if there are multiple streams of the same type? i.e. multiple subtitle streams? By default, ffmpeg takes the first of each type of stream, but you can specifiy what you want:
ffmpeg -i FILE.mkv -map 0:a -map 0:v -map 0:1:s OUTPUT.webm
This next command tells ffmpeg to take the audio stream and the video stream of the first file, and the subtitle stream of the second file:
ffmpeg -i FILE.mkv -i FILE2.mkv -map -0:a 0:v 1:s OUTPUT.webm
Here's the ffmpeg guide on using -map
General tips
- Bitrate is more important than resolution for a video's quality. Don't upscale your videos, increase the bitrate instead.
- Summarize your content as much as you can. No need to make 2 min WebMs if you can show what you wanted in 10 seconds or less.
- Don't post WebMs that are above 720p unless you know what you're doing. 720p and 480p are more than enough for most things.
- Don't record in 1080p only to downscale it later. Record your screen in 720p or less.
- Don't record at more than 30 fps unless you want to show how good your game looks at higher framerates.
- The more the camera moves, the bigger the file size you're going to get. When recording, try to minimize unnecessary camera movements.
- The more general movement there is on a video, the bigger the file size you're going to get. Even if your camera is standing still, if there are lots of things happening on your screen, the file size is going to increase.
- If the quality is not good enough, lower the resolution. A 720p at 500 kbps video is going to look worse than a 480p at 500 kbps video, even when you upscale the 480p video to 720p.
Issues
Seeking issue with VP9
VP9 currently has a stupid default value (9999, i.e. infinite) for the maximum interval between keyframes, which can result in only a single keyframe being created at the very beginning of the video causing the following seeking issues during playback:
- Trying to navigate forwards through the video using the arrow keys on your keyboard causes the audio to skip ahead but the video to freeze.
- Trying to navigate backwards causes the video to skip right back to the first frame.
- Precise seeking using mouse clicks is very slow; after clicking somewhere on the progress bar, there will be a delay of several seconds before the video actually skips to that point.
If you encounter this problem, it is easily fixed with the -g option. The default value in VP8 for this option was 128, so try that first ("-g 128"). If seeking issues persist, try lowering the interval further (e.g. "-g 64").
Scripts and GUIs
Windows
Save these programs as a .bat file and place them in the folder of the video you want to convert.
Video to WebM'
@echo off rem about 3megabyte in bit 3*1024*1024*8*0.95 set /A MAXSIZE=23907532 set WIDTH=720 ffmpeg -i %1 2> webm.tmp for /F "tokens=1,2,3,4,5,6 delims=:., " %%i in (webm.tmp) do ( if "%%i"=="Duration" call :calcLength %%j %%k %%l %%m ) del webm.tmp SET /a BITRATE=%MAXSIZE%/%VSECONDS% ffmpeg -y -i %1 -threads 0 -sn -an -c:v libvpx -b:v %BITRATE% -vf scale=-1:%WIDTH% -quality best -cpu-used 0 -slices 8 -auto-alt-ref 1 -f webm -pass 1 NUL ffmpeg -y -i %1 -threads 0 -sn -an -c:v libvpx -b:v %BITRATE% -vf scale=-1:%WIDTH% -quality best -cpu-used 0 -slices 8 -auto-alt-ref 1 -f webm -pass 2 %~n1.webm" del ffmpeg2pass-0.log > NUL goto :EOF :calcLength FOR /F "tokens=* delims=0" %%A IN ("%3") DO SET /A s=%%A FOR /F "tokens=* delims=0" %%A IN ("%2") DO SET /A s=s+%%A*60 FOR /F "tokens=* delims=0" %%A IN ("%1") DO SET /A s=s+%%A*60*60 set /A VSECONDS=s
gif to webm
@ECHO OFF ffmpeg -y -i "%~1" -b:v 3M -quality best -cpu-used 0 -slices 8 "%~1.webm"
Linux / OS X
If you're using OS X or Linux, you probably know how to save and execute these scripts already, but here's a quick overview:
- Create a file, such as
~/bin/my_script.sh
- Copy and paste the code into this file with your favorite editor.
- Open a shell. Run the command
chmod +x ~/bin/my_script.sh
- The script can now be called as
~/bin/my_script.sh some_file.type
or if you have your PATH set correctly,my_script.sh some_file.type
webm.bash
It does interactive cropping with mplayer, interactive selection of start and end times with mplayer, hardsubs, and has many more options.
https://gist.github.com/interjection/4b83c0790ce82982caec
.gif Convert
#!/bin/bash ffmpeg -i $1 -threads 0 -cpu-used 0 -c:v libvpx -f webm -b:v 700k -quality good -qmin 10 -qmax 42 -an /dev/null ffmpeg -i $1 -threads 0 -cpu-used 0 -c:v libvpx -f webm -b:v 700k -quality good -qmin 10 -qmax 42 -an "$F"
High-End Video Convert
#!/bin/bash # Warning: this script will probably take up a lot of CPU usage. Don't crash your machine. ffmpeg -i $1 -threads 0 -cpu-used 0 -c:v libvpx -c:a libopus -ac 2 -qmin 0 -qmax 10 -bufsize 1000k -quality good -crf 4 -b:v 2M -pass 1 /dev/null ffmpeg -i $1 -threads 0 -cpu-used 0 -c:v libvpx -c:a libopus -ac 2 -qmin 0 -qmax 10 -bufsize 1000k -quality good -crf 4 -b:v 2M -pass 1 "$1".webm
̈́Split Video
#!/bin/bash # Takes a large video file and splits it into multiple 3MB webm files crf=18 bitrate=500K threads=8 # Duration of original video in seconds duration=$(expr `mediainfo --Inform="General;%Duration%" "$1"` / 1000) sec=0 j=1 until (($sec >= $duration)) do ffmpeg -ss $sec -i "$1" -an -sn -threads $threads -c:v libvpx -crf $crf -b:v $bitrate -fs 3M $j.webm # Duration of previous video is added to the sum of every previous video sec=$(expr $(expr `mediainfo --Inform="General;%Duration%" $j.webm` / 1000) + $sec) j=$((j+1)) done
Poster Image with Audio
ffmpeg -r 1 -loop 1 -i 1.png -i 1.wav -c:v libvpx -c:a libopus -b:a 64k -shortest out.webm
GUI options
Recorders
- WebMCam
- Records the selected area and saves the output as WebM, just like GifCam does it with GIFs.
- https://github.com/TheTarkus/WebMCam/
Converters
- convert_script.lua - A lua script for mpv to convert, crop, resize and encode directly from the mpv window.
- https://github.com/Wsheerio/webmConverter
- https://gitgud.io/nixx/WebMConverter - Most up-to-date converter for Windows.
- https://github.com/rzumer/Webbum - Also supports AV1
- https://firefogg.org - Requires the Firefogg extension, will only work in Firefox.
You can also refer to Recommended_software for video editing and converting programs.
External resources
List of stickies / test threads
- https://rbt.asia/g/thread/S41184007
- https://rbt.asia/g/thread/S41183707
- https://rbt.asia/g/thread/S41178861
- https://rbt.asia/g/thread/S41190521
- https://rbt.asia/g/thread/S41212767#p41212767
Further links
- https://trac.ffmpeg.org/wiki/vpxEncodingGuide
- WebM of a WebM tutorial: https://rbt.asia/boards/g/img/0411/75/1396646705233.webm
- http://www.webmproject.org/docs/encoder-parameters/
- http://wiki.webmproject.org/ffmpeg
- N0Lif3's Windows tutorial: https://www.youtube.com/watch?v=WeM3SUp-HRg
- http://wiki.webmproject.org/ffmpeg/vp9-encoding-guide
- https://github.com/Kagami/webm.py/wiki/Notes-on-encoding-settings
- https://trac.ffmpeg.org/wiki/Encode/VP8
- https://trac.ffmpeg.org/wiki/Encode/VP9
- http://forum.doom9.org/showthread.php?t=168947
- http://slhck.info/video-encoding
- The "ultimate WebM guide" for ffmpeg: https://github.com/vp8m8/webm-guide