Skip to content

A cross-platform PowerShell script that enhances encoding workflows with ffmpeg & VapourSynth.

License

Notifications You must be signed in to change notification settings

patrickenfuego/FFEncoder

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GitHub release (latest SemVer) GitHub GitHub last commit GitHub issues Encoder

FFEncoder

FFEncoder is a cross-platform PowerShell script and module that is meant to make high definition video encoding workflows easier. FFEncoder uses ffmpeg, ffprobe, VapourSynth, Mkvtoolnix, the x264 H.264 encoder, and the x265 H.265 HEVC encoder to compress, filter, and multiplex multimedia files for streaming or archiving.

Dynamic Metadata such as Dolby Vision and/or HDR10+ is fully supported.



About

FFEncoder is a simple script that allows you to pass dynamic parameters to ffmpeg without needing to modify complicated CLI arguments for each source. As much as I love the ffmpeg suite, it can be complicated to learn and use; the syntax is extensive, and many of the arguments are not easy to remember unless you use them often. The goal of FFEncoder is to take common encoding workflows and make them easier, while continuing to leverage the power and flexibility of the ffmpeg tool chain.

Capability can be further expanded with the VapourSynth frameserver. FFEncoder fully supports audio, subtitle, and chapter options and will mux the streams together for you after the encode finishes. Other than video filtering options, every parameter available works with VapourSynth scripts.

Check out the wiki for additional information.


Dependencies

For Windows users, PowerShell 7.x is a supplemental installation and will will be installed alongside PowerShell 5.1

NOTE: PowerShell 7.3 completely changed the way string arguments are parsed with third party executables. I have updated the code to support this, and it should be backward compatible to version 7.0.0. If issues are found, please let me know

  • ffmpeg / ffprobe
  • PowerShell v. 7.0 or newer
  • Mkvtoolnix (optional, but highly recommended)
  • VapourSynth (optional)
  • Dolby Encoding Engine (DEE) (optional)

For users with PowerShell 7.2 or newer, the script uses ANSI output in certain scenarios to enhance the console experience.


Dependency Installation & Setup

Expand

You can compile ffmpeg manually from source on all platforms, which allows you to select additional libraries (like Fraunhofer's libfdk AAC encoder). Some features of this script are unavailable unless these libraries are included. For more information, see here.

Windows

To download ffmpeg, navigate to the ffmpeg downloads page and install one of the prebuilt Windows exe packages. I recommend the builds provided by Gyan.

To install the latest version of PowerShell 7, follow the instructions provided by Microsoft here.

Linux

You can install ffmpeg using your distro's package manager (apt/yum/pacman/zypper):

apt install ffmpeg

To install PowerShell 7, see Microsoft's instructions for your distribution here.

macOS

The easiest way to install ffmpeg and PowerShell 7 is through the Homebrew package manager:

brew install ffmpeg

One of the other benefits of using Homebrew is that you can easily install a build that includes non-free libraries like fdk_aac:

brew install ffmpeg --with-fdk-aac

To install PowerShell, run the following command using Homebrew:

brew install --cask powershell

Adding Contents to PATH

The following binaries are expected to be available via system PATH in order for the script to work properly:

  • ffmpeg
  • ffprobe
  • x265 (Dolby Vision Only)
  • mkvextract, mkvmerge, mkvpropedit (optional, but recommended)
    • These should be added to PATH automatically when you install MkvToolNix
  • Dolby Encoding Engine, AKA dee (Optional)

Adding contents to PATH is relatively straightforward and platform dependent. Below are some examples of how you can add software to your system PATH:

# Whatever the path is to your ffmpeg install
$ffmpeg = 'C:\Users\SomeUser\Software\ffmpeg.exe'
$ffprobe = 'C:\Users\SomeUser\Software\ffprobe.exe'
$newPath = $env:PATH + ";$ffmpeg;$ffprobe"
[Environment]::SetEnvironmentVariable('PATH', $newPath, 'User')
# Now close and reopen PowerShell to update

Here is a quick example using bash/zsh on Linux/macOS:

# Set this equal to wherever ffmpeg is
ffmpeg="/home/someuser/software/ffmpeg"
# If you're using zsh (mac default), replace .bashrc with .zshrc
echo "export PATH=${ffmpeg}:${PATH}" >> ~/.bashrc
# Source the file to update
source ~/.bashrc

Features

Auto-Cropping

NOTE: FFEncoder uses modulus 2 rounding to detect black borders. I've found this to be the most consistent choice for the majority content. If you do not want the script to auto-crop your video, you may pass override crop values via the -FFMpegExtra parameter (see here for more info)

FFEncoder will auto-crop your video, and works similarly to programs like Handbrake with more emphasis on accuracy. The script analyzes up to 6 separate segments of the source simultaneously, collects the output, and saves it to a file which is used to determine cropping values for encoding.


Automatic HDR Metadata

FFEncoder will automatically fetch and fill HDR metadata before encoding begins. This includes:

NOTE: Color Range (Limited) and Chroma Subsampling (4:2:0) are currently hard coded as they are the same for all Blu-Ray sources. If you need dynamic parameters, put in a feature request and I will add them.

  • Mastering Display Color Primaries
  • Pixel format
  • Color Space (Matrix Coefficients)
  • Color Primaries
  • Color Transfer Characteristics
  • Maximum/Minimum Luminance
  • Maximum Content Light Level
  • Maximum Frame Average Light Level
  • HDR10+ Metadata
    • WARNING: Depending on the source, the metadata ordering may be incorrect after extraction. Evaluate the generated JSON file manually and use the -HDR10PlusSkipReorder parameter if necessary to correct this
  • Dolby Vision Metadata
    • Automatically edits the generated RPU file to ensure the metadata is accurate
    • Requires x265 (mods are fine) to be available via PATH because ffmpeg still doesn't handle RPU files correctly, even in version 5. If there is more than one x265* option in PATH, the first option returned is selected
    • Currently, only profile 8.1 is supported due it it's backwards compatibility with HDR10
    • It is recommended to have mkvmerge/mkvextract available. The script will multiplex tracks back together after encoding

Rate Control Options

FFEncoder supports the following rate control options:

  • Constant Rate Factor (CRF) - CRF encoding targets a specific quality level throughout, and isn't concerned with file size. Lower CRF values will result in a higher perceived quality and bitrate. For those familiar with Handbrake, this is essentially the same as RF
    • For high quality encodes, CRF 17-19 is generally considered a good starting range.
    • If file size is more important than quality, CRF 20-23 is a good starting range
  • Average Bitrate (Not Adaptive Bitrate) - This is also sometimes referred to as Variable Constrained Bitrate encoding. Average bitrate encoding targets a specific output file size, and isn't concerned with quality. There are 2 varieties of ABR encoding that FFEncoder supports:
    • 1-Pass - This option uses a single pass, and isn't aware of the complexities of future frames and can only be scaled based on the past. Lower quality than 2-pass, but faster
    • 2-Pass - 2-Pass encoding uses a first pass to calculate bitrate distribution, which is then used to allocate bits more accurately on the second pass
  • Constant QP - Forces a constant quantization parameter value throughout the entire encode in the form of an integer value (0 - 51). This is useful for testing as well as comparing the efficacy of encoders
    • NOTE: Forcing a constant QP will generally result in poor compression efficiency, and thus it is not recommended for general use (unless you know what you're doing)

VMAF Comparison

The script can compare two files using Netflix's Video Multi-Method Assessment Fusion (VMAF) as a quality measurement.

The machine Learning model files are already provided, and Frames-Per-Second (FPS), resolution/cropping, and scaling are handled automatically; libvmaf requires that these parameters be identical before it will run.

Additionally, you may add SSIM and PSNR measurements as well during the same VMAF run - see the wiki for full details.


MKV Tag Generator

If the selected output format is Matroska (MKV), you can use the parameter -GenerateMKVTagFile (or its alias, -CreateTagFile) to dynamically pull down metadata from TMDB, create a valid XML file, and multiplex it into the output file. This allows you to add useful metadata to your container for things like Plex and Emby to detect, or add other cool properties like Directors, Writers, and Actors for your own reference; any parameter that is available via the TMDB API can be added to your container.

To use this parameter, you will need a valid TMDB API key. See the wiki for more information.


Usage

Configuration Files

Three configuration files, ffmpeg.ini, encoder.ini, and script.ini, are included and can be leveraged to set frequently used options. These files are located in the config directory and are loaded each time the script runs.

See the wiki for more information.

Parameters

FFEncoder can accept the following parameters from the command line:

Mandatory

An Asterisk * denotes that the parameter is mandatory only for its given parameter set (for example, you can choose either -CRF or -VideoBitrate for rate control, but not both):

Parameter Name Default Mandatory Alias Description Mandatory For
InputPath N/A True I, Source, Reference The path to the source file, i.e. remux. Also acts as the reference path for VMAF comparisons All
OutputPath N/A True O, Encode, Distorted The path of the the encoded output file, or the encoded (distorted) file path during VMAF comparisons All
CRF N/A *True C Rate control parameter that targets a specific quality level. Ranges from 0.0 to 51.0. Lower values result in higher quality Rate Control
ConstantQP N/A *True QP Constant quantizer rate control mode. Forces a consistent QP throughout the encode. Generally not recommended outside of testing. Rate Control
VideoBitrate N/A *True VBitrate Rate control parameter that targets a specific bitrate. Can be used as an alternative to CRF when file size is a priority Rate Control
ScaleKernel None *True ResizeKernel Scaling/resizing filter to use. See Rescaling Video for more info Scaling
Unsharp None *True U Enable unsharp filter and set search range, in the form <luma|chroma|yuv>_<small|medium|large> or custom=<filter> Sharpen/Blur
CompareVMAF N/A *True None Flag to enable a VMAF comparison on two video files VMAF

Utility

Parameter Name Default Mandatory Alias Description
Help False False H, ? Switch to display help information, including examples and parameter descriptions
RemoveFiles False False Del, RM Switch that deletes extra files generated by the script (crop file, log file, etc.). Does not delete the input, output, or report file (if created)
GenerateReport False False Report, GR Switch that generates a report file of the encode. Data is pulled from the log file and written in a reading friendly format
GenerateMKVTagFile False False CreateTagFile Generates an MKV tag file using the TMDB API (key required). See the wiki
Verbose False False None CmdletBinding switch to enable verbose logging - cascaded down to relevant functions for additional information. Useful for debugging
ExitOnError False False Exit Switch that forcibly exits the script on certain non-terminating errors that prompt for re-input. Can be used to prevent blocking during automation
EnablePSNR False False PSNR Enables an additional Peak Signal-to-Noise (PSNR) measurement during VMAF comparisons
EnableSSIM False False SSIM Specify the resizing kernel used for upscaling/downscaling encodes for comparison
VMAFResizeKernel BiCubic False VMAFKernel Enables an additional Structural Similarity Index (SSIM) measurement during VMAF comparisons
DisableProgress False False NoProgressBar Switch to disable the progress bar during encoding

Audio & Subtitles

See Audio Options and Subtitle Options in the wiki for more info

Using deew requires some initial configuration before it will work properly. See the wiki for more info

Parameter Name Default Mandatory Alias Description
Audio Copy False A Audio preference for the primary stream
AudioBitrate Codec False AB, ABitrate Specifies the bitrate for -Audio (primary stream). Compatible with Dolby DEE, AAC, FDK AAC, AC3, EAC3, and DTS
Stereo False False 2CH, ST Switch to downmix the first audio track to stereo
Audio2 None False A2 Audio preference for the secondary stream
AudioBitrate2 Codec False AB2, ABitrate2 Specifies the bitrate for -Audio2 (secondary stream). Compatible with Dolby DEE, AAC, FDK AAC, AC3, EAC3, and DTS
Stereo2 False False 2CH2, ST2 Switch to downmix the second audio track to stereo
Subtitles Default False S, Subs Subtitle passthrough preference

Video Filtering

See the Mandatory section above for parameters needed to enable certain filters

Parameter Name Default Mandatory Alias Description
Deinterlace Disabled False DI Switch to enable deinterlacing of interlaced content using yadif
NLMeans Disabled False NL High quality de-noising filter. Accepts a hashtable containing 5 values. See here for more info
Scale bilinear False ScaleType, SF Scaling/resizing filter to use. See Rescaling Video for more info
Resolution Source Dependent False Res, R Scaling resolution. See Rescaling Video for more info
UnsharpStrength luma_mild False UStrength Specify the unsharp filters strength, in the form <sharpen|blur>_<mild|medium|strong>

Encoder Config

Parameter Name Default Mandatory Alias Description
Encoder x265 False Enc Specifies which encoder to use - x264 or x265
FirstPassType Default False PassType, FTP Tuning option for two pass encoding. See Two Pass Encoding Options for more info
SkipDolbyVision False False NoDV, SDV Switch to disable Dolby Vision encoding, even if metadata is present
SkipHDR10Plus False False No10P, NTP Switch to disable HDR10+ encoding, even if metadata is present
HDR10PlusSkipReorder False False SkipReorder Switch to correct improper HDR10+ metadata ordering on some sources. You must verify yourself if this is required or not
TestFrames 0 (Disabled) False T, Test Integer value representing the number of test frames to encode. When -TestStart is not set, encoding starts at 00:01:30 so that title screens are skipped
TestStart Disabled False Start, TS Starting point for test encodes. Accepts formats 00:01:30 (sexagesimal time), 200f (frame start), 200t (decimal time in seconds)
VapourSynthScript Disabled False VSScript, VPY Path to VapourSynth script. Video filtering parameters are ignored when enabled, and must be done in the vpy script

Universal Encoder Settings

NOTE: Encoder means the default is specific to the encoder used. System is based on system hardware

Parameter Name Default Mandatory Alias Description
AqMode 2 False AQM x265 Adaptive Quantization setting. Ranges from 0 - 4. See the x265 Docs for more info on AQ Modes and how they work
AqStrength 1.00 False AQS Adjusts the adaptive quantization offsets for AQ. Raising AqStrength higher than 2 will drastically affect the QP offsets, and can lead to high bitrates
Deblock -2, -2 False DBF Deblock filter. The first value controls strength, and the second value controls threshold. Passed as an array in the form (alpha, beta)
BFrames Preset False B The number of consecutive B-Frames within a GOP. This is especially helpful for test encodes to determine the ideal number of B-Frames to use
Level None False Level, L Specify the encoder level for device compatibility. Default is unset, and will be chosen by the encoder based on rate control. Affects VBV options (see below)
Merange Preset False MR Sets the motion estimation search range. Higher values result in a better motion vector search during inter-frame prediction
NoiseReduction Encoder False NR Fast Noise reduction filter. For x265, the first value represents intra frames, and the second value inter frames; values range from 0-2000
Pass 2 False None The number of passes the encoder will perform on ABR encodes. Used with the -VideoBitrate parameter. Default is 2-Pass
Preset Slow False P The x265 preset to be used. Ranges from placebo (slowest) to ultrafast (fastest). See x265 documentation for more info on preset options
PsyRd Encoder False PsyRDO Psycho-visual enhancement. Strongly favor similar energy over blur. For x264, you can set psy-RDO & psy-trellis (i.e. 1.00,0.04) or psyRDO only
PsyRdoq Preset False PsyTrellis Psycho-visual enhancement. Favors high AC energy in the reconstructed image. For x264, this can be used to set psy-trellis separately from psy-RDO
QComp 0.60 False Q Sets the quantizer curve compression factor, which effects the bitrate variance throughout the encode. x265: Must be between 0.50 and 1.0. x264: Between 0 and 1
RCLookahead Preset False RCL, Lookahead Sets the rate control lookahead option. Larger values use more memory, but can improve compression efficiency
Ref Preset False None Sets the number of reference frames to use. Default value is based on the encoder preset. For x264, this might affect hardware compatibility
Subme Preset False Subpel, SPM The amount of subpel motion refinement to perform. At values larger than 2, chroma residual cost is included. Has a significant performance impact
Threads System False FrameThreads Set the number of threads. More threads equate to faster encoding. System default is based on the number of logical CPU cores
Tree 1 (Enabled) False CUTree, MBTree Enable or disable encoder-specific lowres motion vector lookahead algorithm. 1 is enabled, 0 is disabled. Best disabled for noisy content
VBV Level False None Video buffering verifier. Default is based on the encoder level (except DoVi, which defaults to level 5.1). Requires 2 arguments: (vbv-bufsize, vbv-maxrate)

x265 Only Settings

Parameter Name Default Mandatory Alias Description
BIntra Preset False BINT Enables the evaluation of intra modes in B slices. Has a minor impact on performance
LimitTU 0 False LTU Limits the TU recursion depth based on the value passed. Acceptable values are 0 - 4. Settings are not linear, and have different impacts
TuDepth 1, 1 False TU Transform Unit recursion depth. Accepted values are 1-4. First value represents intra depth, and the second value inter depth, i.e. (tu-intra-depth, tu-inter-depth)
StrongIntraSmoothing 1 (on) False SIS Enable/disable strong-intra-smoothing. Accepted values are 1 (on) and 0 (off)

Extra

See here for examples of how to use these parameters

Parameter Name Default Mandatory Alias Description
FFMpegExtra N/A False FE Pass additional settings to ffmpeg as a generic array of single and multi-valued elements. Useful for options not covered by other parameters
EncoderExtra N/A False XE Pass additional settings to the specified encoder as a hashtable of values. Useful for options not covered by other parameters

Acknowledgements

This section contains acknowledgements for the authors of tools distributed with this project. All credit goes to them!

  • dovi_tool - Developed by quietvoid
  • hdr10plus_tool - Developed by quietvoid
  • deew - While this project contains a modified, custom compiled version of deew, the original project was developed by pcroland

Special Mention

Not distributed with the project, although used frequently in various pieces of the automation for those who have it installed. An invaluable tool for any video enthusiast (consider contributing to their development!):