Encoding Snippets

I do a lot of encoding work, but I seem to lose track of useful encoding snippets from time to time.

This post will act as a central repository for me to organize my snippets.


Downscale video using spline36§

ffmpeg -i input.mp4 -vf zscale=w=1920:h=-1:filter=spline36 out.mp4

Denoise using hqdn3d or fftdnoiz§

hqdn3d, with a luma_spatial of 6 (default is 4).

ffmpeg -i input.mp4 -vf hqdn3d=luma_spatial=6 out.mp4

fftdnoiz, sigma 4, using 1 previous and 1 future frame for temporal filtering

ffmpeg -i input.mp4 -vf fftdnoiz=sigma=4:prev=1:next=1 out.mp4

Downscale and denoise§

ffmpeg -i input.mp4 -vf zscale=w=1920:h=-1:filter=spline36,hqdn3d=luma_spatial=6 out.mp4

Output using x264, copying audio§

ffmpeg -i input.mp4 -c:a copy -c:v libx264 -preset slower -tune film -crf 21 out.mp4

Enable video fast start by adding movflags to MP4 file§

ffmpeg -i input.mp4 -movflags +faststart out.mp4

This enables videos to start playing as soon as the first few bytes are sent to the client, instead of requiring the client to download the full video.

Process video with Vapoursynth, encode video and copy audio using FFMPEG§

This is useful to handle video processing with Vapoursynth (denoise, deinterlacing, sharpening, etc etc) while still maintaining the audio from the original source.

vspipe --arg 'source=./input.mp4' -c y4m script.py - | ffmpeg -i - -i input.mp4 -map 0:v -map 1:a -c:a copy -c:v libx264 -preset fast -tune film -crf 20 out.mp4

The magic is in the -map 0:v -map 1:a -c:a copy line. map is used to select from multiple sources, so in the case we're saying "select video from the first input (raw pipe from Vapoursynth), select audio from the second input (the same file we fed to Vapoursynth), and copy the audio".


vspipe, used for reading Vapoursynth (Python) files and feeding them to other programs.

Feed vspipe output to MPV in a paused state§

vspipe -c y4m script.vpy - | mpv --pause --demuxer-rawvideo-codec=y4m -

Feed vspipe to x265§

vspipe -c y4m script.vpy - | x265 --y4m [...] -o out.h265

Feed vspipe to x265 with 10-bit video§

vspipe -c y4m script.vpy - | x265 --y4m --input-depth 10 [...] -o out.h265

Feed vspipe to ffmpeg§

vspipe -c y4m script.vpy - | ffmpeg -i - [...] out.mp4

Pass arg to Vapoursynth script from vspipe§

vspipe --arg "source=./input.mp4" --info script.vpy -

The arg takes the place of a python variable, so it works with something like the following script:

import vapoursynth as vs
core = vs.core
clip = core.lsmas.LWLibavSource(source) # Note that 'source' is read from the --arg param

# ... do processing here


Note: The --info just quickly validates that the passed arg is legit, and prints out the video statistics. You'll remove it when actually feeding to something like ffmpeg.