Skip to content

Releases: patrickenfuego/FFEncoder

Bug Fixes & Audio Improvements

13 Jul 02:11
Compare
Choose a tag to compare

What's New

This release addresses some lingering bugs from 2.0.0. I also added a few small enhancements to existing features.

Bug Fixes

  • Fix crash bug with encoder process bar (casting exception)
  • Fix missing Dolby Vision variable in 2-pass encoding
  • Fix track title naming for externally encoded files
  • Fix bitrate console output for DEE, FLAC, and FDK AAC
  • Fix psy-trellis bug in x264 when the -PsyTrellis parameter is used (was not being set)
  • SAO turned back on by default for x265 - this was supposed to have been set in 2.0.0
  • Fix audio logic bug for named codecs ac3, dca and eac3

Updates

Stream Copy & Encode Anything

Now you can stream copy and encode any audio track in the background using either of the audio parameter pairs. Previously, this was restricted to DEE and stereo encoding for some reason, but it will now work for any audio. As with DEE and stereo, the track is added to the container once the final encode finishes (audio or video).

For Example:

# stream copy all audio tracks and background encode ac3 simultaneously
PS > .\FFEncoder.ps1 'in.mkv' -CRF 18 -Audio copyall -Audio2 ac3 -AudioBitrate2 640k -o 'out.mkv'

Updated Console Output

This is really small, but the console output has been modified with new Unicode characters for additional flair.

Major Bug Fixes for 2.0.0

25 Jun 04:24
Compare
Choose a tag to compare

What's New

This release is meant to address a few fairly significant bugs from the previous release, as well as some minor enhancements to new features and one existing feature.

Bug Fixes

Updated VMAF

When I initially added VMAF support, I forgot about re-scaling. Now upscaled/downscaled comparisons are working as expected.

I also added a new parameter, -LogFormat, where you can choose json, csv, xml, or sub. Previously, json was the hardcoded default, and is still the default if you don't pass a parameter value.

Fix DivideByZero Exception with Encoder Progress Bar

There was an edge case I found where regex was returning 0 while capturing the total number of frames in the source. This was causing a rather cryptic DivideByZero terminating error when setting the progress bar. This should be fixed.

Fix Incorrect Value for -Resolution Parameter

The parameter was not being set properly, and was always using a default value based on the source resolution. This was causing some wacky behavior with scaling, and has been fixed.

Fix Ctrl+C Intercept Behavior

One of the new, behind-the-scenes features of the previous release is the interception of the Ctrl+C command so that the script can exit gracefully if terminated early. In situations where it was not exiting gracefully, PowerShell was no longer detecting the key combination. This should now be fixed.

Updates

Improved Parsing for User-Defined Parameters with -GenerateMKVTagFile

I added some additional parsing for certain multi-valued properties like genres, which would have been returned as an object instead of a string before the change; this created some non-terminating errors, but the real issue was those metadata fields would be skipped over during tag file creation.

Subtitle Enhancements

New Language Codes

To start, I've added several new ISO 639-2 language codes for better subtitle support. New codes:

  • Arabic (ara)
  • Indonesian (ind)
  • Turkish (tur)
  • Vietnamese (vie)
  • Slovenian (slv)
  • Hindi (hin)
  • Hebrew (heb)
  • Bulgarian (bul)

Some languages have more than 1 ISO code, so I added a few extra to the argument list. Existing languages with new secondary codes:

  • Chinese (zho)
  • Greek (ell)
  • Dutch (nld)

See the wiki for a full list.

Language Negation

I've found myself wanting this feature many times in the past but kept pushing it off. Now, you can tell FFEncoder to copy all languages except the language you specify by prefixing the language code with a !. For example, !eng will copy all subtitles except English.

FFEncoder Version 2.0.0

21 Jun 15:57
46dcf85
Compare
Choose a tag to compare

The Next Big Update

It's been a while since I've worked on this as I've been quite busy, but this latest release should hopefully make up for it. I added so many things, I felt a full revision bump was needed.

x264 Support (Finally) with the -Encoder Parameter

NOTE: I did not add 10-Bit or UHD encoding support for x264. It's not industry standard, and nobody really uses it. If you attempt to encode a UHD HDR source with x264, a terminating error is thrown - use x265 instead.

As has been requested for quite some time, x264 support is finally here. This new parameter lets you specify x264 or x265.

It works much the same as x265 does, but since there is a lot of similar functionality with different option names, instead of creating new parameters, I've added aliases to existing ones or modified the parsing. For example:

-PsyRd

This parameter still behaves as expected in x265, but the type has been modified from [double] to [string] to support x264 syntax. In x264, psy-rd encapsulates 2 settings, psy-rdo and psy-trellis, and it can be used in the form <psy-rdo>,<psy-trellis>:

NOTE: The number of spaces before or after the comma separator doesn't matter - regex will account for this

# x264 - MUST use quotes with this format
PS > .\FFencoder.ps1 in.mkv -Encoder x264 -CRF 17 -PsyRd '1.10,0.01' -o out.mkv
# x265 still works the same as before
PS > .\FFencoder.ps1 in.mkv -Encoder x265 -CRF 17 -PsyRd 2.2 -o out.mkv

If you want, you can also use this to pass psy-rdo only, too, and use -PsyRdoq to pass psy-trellis. Both options use the encoder-specific default values for these unless modified.

-PsyRdoq / -PsyTrellis / -PsyRDO

Since psy-rdoq is essentially x265's implementation of psy-trellis, I've made -PsyTrellis an alias for -PsyRdoq and -PsyRDO an alias for -PsyRd, and you can use them to pass psy-trellis separately from psy-rdo - personally, I think this is the better way, but you can do it however you like:

# x264 - Split the options
PS > .\FFencoder.ps1 in.mkv -Encoder x264 -CRF 17 -PsyRDO 1.00 -PsyTrellis 0.01 -o out.mkv
# x265 still works the same as before
PS > .\FFencoder.ps1 in.mkv -Encoder x265 -CRF 17 -PsyRdoq 1.4 -o out.mkv

Note that PsyRdoq still defaults to the chosen preset value for x265.

-Threads / -FrameThreads

I renamed the parameter -FrameThreads to -Threads to be more universal. -FrameThreads is still an alias. Value ranges differ dramatically between encoders, but I did my best to include input validation before the script starts. Just be aware.

-x255Extra Renamed to -EncoderExtra

This one is fairly self-explanatory.


Universal Encoder Parameters

In the spirit of cross-compatibility, I've added several new parameters that are common to both encoders. most of these parameters use the preset value by default, but can be modified via parameter, too.

-Tree / -CUTree / -MBTree

As both encoders implement their own motion vector lookahead implementations, I created the general parameter name -Tree, with aliases -CUTree and -MBTree for the specific encoders. They are all equivalent, so there won't be any errors if you use -CUTree with x264 and vice versa.

-Ref

Specifies the number of references frames. This works more or less the same for both x264 and x265, with x264 being a bit more sensitive about hardware compatibility.

-Merange / -MR

Specifies the motion estimation search range. While each encoder uses different value ranges, the effect is the same. I did my best to constrain the possible inputs to cover both (16 - 96), but do watch out with x265 as you might get an error trying to use a value as high as 96 - I'm not sure, I've never tried. I've never seen a value higher than this used before with x264, and the documentation on what the range actually is was...elusive. If you need it updated, open an issue and I can resolve it quickly.

-RCLookahead / -Lookahead / -RCL

Controls the rate control lookahead buffer. I almost never modify this in x265 (I previously had it hardcoded), but in x264 I do often change it. Since it's common to both and the ranges are the same, it seemed like a logical addition.


New Features

I guess I was feeling a bit ambitious after being away for so long, and decided to add some cool quality of life features to the script as a whole.

Encoder Progress Bar

There is now an official progress bar that shows you your progress! It uses the number of frames encoded to show your current progress (pulled from the log), and you no longer need to run a separate command in a separate shell to see your progress (although I did not remove that as it still has far more info):

Progress Bar

To make this work, all encoding tasks now run as a background job, which are continuously monitored to provide progress bar updates. The progress function will check for updates every 1.5 seconds to limit the overhead on the UI.

Additionally, if you terminate the script early via Ctrl+C, the script will attempt to shut down gracefully by killing all running jobs before exiting.

If you're running a test encode, the frame value from -TestFrames will be used as the total count. For full encodes, the source is quickly scanned for a frame count without demuxing - be patient, this can take up to 30 seconds to load depending on the length of the source.

If you don't want a progress bar for whatever reason, you can disable it using the -DisableProgress switch parameter.

NOTE: The bar will be somewhat slower to update with HDR10+ encoding, as all the SEI messages really spam the log and create large gaps between frame counters. Just keep that in mind.

VMAF Support

Ever wanted to calculate VMAF easily without leaving the script? Now you can! I've added support for this very useful quality metric directly into the script, which operates as its own parameter set.

Simply pass it a source via -Source/-Reference (aliases for -InputPath) and an encode via -Encode/-Distorted (aliases for -OutputPath) to begin comparison. The machine Learning model files are already provided, and Frames-Per-Second (FPS) and resolution are calculated automatically.

Additionally, you may add SSIM and PSNR measurements as well during the same VMAF run using their respective switch parameters - see the README for more info.

Timed Input Prompts

Previously, certain errors would cause the script to exit with an error - I did this because the Read-Host cmdlet to accept user input still somehow does not provide a timeout option, and I didn't want to break automation with a prompt that sits there for all eternity if you aren't at your computer.

To remedy this, I built my own custom type using C# that is used as an input prompt with a timeout - it's dynamically loaded into memory with the function and not compiled to .dll because I wasn't sure how that would affect *NIX systems.

If you accidentally pass an incorrect option for a parameter (that can't be caught by parameter validation), you will be prompted for re-input. If you don't enter it in a reasonable amount of time, the script will throw a warning/error but move on instead of exiting in most cases.

Version Checking

This is one feature previous releases really lacked, and I decided to step it up for this one. The script will now verify your version of both PowerShell and FFEncoder, and prompt you to update or throw an error when applicable.

With FFEncoder, it will verify that the release you're running is the latest, and offer to download the latest using git if you are not. Now, you will never miss out on another update.

For PowerShell, it will verify that you're running the proper version and exit on an error if you are not. The module already requires PowerShell 7.0 or newer, but there might be situations where you switched to Windows PowerShell 5.1 and forgot to switch back - the script will kindly remind you of this. It will also check if you're running the latest version of PowerShell via an API call to GitHub, and warn you that you're missing out on some features if not.

Slick stuff, cool stuff, neat stuff - Garth Brooks

MKV Tag Generation with -GenerateMKVTagFile

I am a dedicated fan of the MKV container format, and have had a script that automatically generates tag files for a while now. If you aren't aware, a tag file is an XML file that contains additional metadata that can be added to the file; this data can be viewed in programs like MediaInfo, or parsed by media agents like Plex or Emby. It's a useful and cool thing to add to your files, and I'm happy to add the option to the script.

The parameter accepts a hashtable as input, and the only required argument is an API key. The script pulls metadata using the TMDB API, so you will need an API key for this to work (it's free to signup). For example:

# Generate a tag file
PS > .\FFencoder.ps1 in.mkv -Encoder x264 -CRF 17 -GenerateMKVTagFile @{APIKey='123456ABCDEFG'} -o out.mkv

The parameter calls an external script, MatroskaTagGenerator.ps1, and it's highly customizable. See the wiki for full details on what it can do and how to use it.


Updates

This release also comes with several updates/improvements to existing features.

Ov...

Read more

Dolby Encoding Engine Support

28 Feb 03:30
8627878
Compare
Choose a tag to compare

I'm excited to bring support for the official Dolby Encoding Engine as well as some other major bug fixes, enhancements, and binary updates.

What's New

Dolby Encoding Engine

The script now fully supports the Dee encoder! Shout out to pcroland for writing the python script to parse the XML fuckery employed by the engine before I could even blink. I've forked the repo and made some optimizations for FFEncoder, and plan to make more in the coming weeks.

Five new parameters have been added for Dolby Digital, Dolby Digital Plus, and True HD:

  • dee_dd / dee_ac3
  • dee_ddp / dee_eac3
  • dee_thd

The encoder is really slow, so it gets spun off into a separate process to encode alongside the primary process. The deew script is written in python, so I've automated the process of installing dependencies if you already have python installed (which is currently required to use it). One day I'll port it to PowerShell, but for now, it works.

Disclaimer - You have to get your own binary for dee, I'm not getting sued (and I'm not claiming to possess one)

NLMeans Support

I've also added direct support for nlmeans denoising via the parameter -NLMeans , which accepts a hashtable as a value with 5 properties:

  • s - Set denoising strength. Default is 1.0. Must be in range [1.0, 30.0].
  • p - Set patch size. Default is 7. Must be odd number in range [0, 99].
  • pc - Same as p but for chroma planes. The default value is 5
  • r - Set research size. Default is 3. Must be odd number in range [0, 99].
  • rc - Same as r but for chroma planes. The default value is 3

You're required to pass at least one of the above to activate the parameter. The remaining unpassed values will be filled with the defaults listed above (I changed some of them from the ffmpeg default to a more sane value). For example:

# This results in 2.0:7:7:3:3
PS > .\FFEncoder.ps1 C:\some\file.mkv -NLMeans @{s = 2; pc = 7} -o C:\some\out.mkv

More mkvmerge Integration

Up to this point, the script has primarily used ffmpeg as the main muxer/demuxer, with the exception of DV. Now, if you have the MKVToolnix suite installed, all muxing will go through mkvmerge instead. I've had issues with ffmpeg muxing over the years which is why I decided to do this. If you don't have it installed or you're using a different container format, it will continue to use ffmpeg.

New Track Titling

The script will now automatically name audio tracks for you based on the codec and channel count; if mkvmerge is used, it will also set the language if not already set. Small, but cool!

Other Stuff

I've updated the dovi binaries as there have been some nifty new enhancements.

Stream copy and stereo encoding

This has received quite a bit of work because it was really busted. I fixed a bug that threw an error saying The Alias Q is declared multiple times when stream copying and stereo encoding at the same time. I still have no idea what was causing it (because there was and is only 1 Q alias), but I've completely refactored the code for the better.

In addition, the script will now encode the stereo track in a separate process alongside the main encode if stream copying is used, which speeds things up a bit.

Bug Fixes

  • -ExitOnError parameter has been fixed when used with test parameters. It was previously being ignored
  • Fix for -TestStart parameter when a poster is attached to the container and a frame start is passed
  • Fixed broken console output for audio stuffs, specifically for echoing back bitrate per channel
  • Fix for -OutputPath when the output directory doesn't exist. The script will now try and create that directory structure before exiting on an error
  • The script will now warn when you attempt to transcode from one lossy codec to another lossy codec (but not stop you)

Upcoming

x264 support is nearly finished.

Improved Errors, Bug Fixes, & A New Look

31 Dec 02:02
Compare
Choose a tag to compare

This release was about adding more polish to the script and doing some much-needed cleanup on large chunks of the old codebase.

What's New

Improved Errors & Error Handling

Continuing some work I started in the last release, I've completely overhauled error handling and error messages in this release. I removed pretty much all of the throw statements and replaced them with errors that are more meaningful and don't suck. Errors now look a lot cleaner in the console as well due to the way they are handled in the call stack, but a lot more information is available (but hidden, PowerShell 7 style) for those who wish to dig deeper.

The script now checks for the host PowerShell version, and throws differing errors depending on the situation. Some examples:

  • PowerShell 7 is not installed
  • PowerShell 7 is installed but a different host version is being run

Some errors that were previously terminating errors have been modified with re-input prompts as well, so the script will not automatically crash.

-ExitOnError Parameter

If you'd prefer that the script crashes instead of prompting for re-input, you can use this parameter. I had automation in mind with this, so the script won't get stuck on an input screen, but will exit instead and continue on with the next encode.

Imrpoved Console Output

Logic was added to automatically set the console foreground and background colors for better compatibility with the output color scheme (no more weird bright blue backgrounds with black & green text). A neat new banner was added, as well, and the window title will now display 'FFEncoder'. Sweet.

New Parameters, Bug Fixes & Other Enhancements

18 Dec 05:41
Compare
Choose a tag to compare

This release comes with new parameters for managing the encoder, as well as bug fixes and other enhancements.

What's New

-LevelIDC

Specify the encoder level to use.

-VBV

Sets the buffer-related parameters, vbv-bufsize, vbv-maxrate.

The logic has been changed for how the encoder level is selected. Instead of forcing it, it will now be decided by the encoder unless modified by one or both of the parameters above.

-TestStart

Sets the starting point for a test encode. It can be set using:

  • Sexagesimal time format: 00:01:30 (default)
  • Starting frame using the f modifier: 500f
  • Starting time as a decimal value (in seconds) using the t modifier: 400.5t

Bugs & Enhancements

  • Fixed forced SAO for Dolby Vision encodes
  • Fixed crop value console display when resizing
  • Fixed bug where no default resolution or scale filter was set when user didn't pass any (but did pass -Scale)
  • Increased stream copy audio identifier range from 6 to 12
  • Improved performance in several Set-* functions
  • Removed PoshRSJobs

Utility Scripts

I added a few utility scripts that I find useful when used in conjunction with the main script.

Dolby Vision Support

02 Nov 01:14
Compare
Choose a tag to compare

This release comes with support for Dolby Vision encoding, two new utility parameters, and performance optimizations.

What's New

Dolby Vision Support

Encode with Dolby Vision! Supports profile 8.1 as it's backward compatible with HDR10. You must have an x265 binary available via PATH, because ffmpeg cannot handle RPU files.

-SkipDolbyVision

The name says it all. Skip Dolby Vision encoding, even if the source has DV metadata

-SkipHDR10Plus

Same as above

Other Stuff

  • Bugs squashed
  • Better support for parameter overriding - for those who don't like my hard-coded settings!

Dolby Vision Support

13 Oct 23:44
Compare
Choose a tag to compare
Dolby Vision Support Pre-release
Pre-release

This pre-release adds Dolby Vision encoding support for Windows, macOS, and Linux. I have tested it enough to know that it works, but not enough to say that it is 100% production-ready. To check out this release, clone the dvtest branch of the repository.

What's New

The script is now capable of encoding Dolby Vision! There are a few caveats, however:

  1. x265 is required for encoding, because ffmpeg does not support RPU files (yet). Due to the many varieties of x265 available (as well as the binary size), I chose not to include it with the package. Download your favorite branch of x265 to use, and make sure it is named x265 (not x265-b, for example). Also be sure that it is available via PATH
  2. Due to some severe memory leaks when piping ffmpeg to x265 in PowerShell, cmd.exe / bash are used to actually run the commands. This doesn't really affect speed or quality, but it does affect what type of logging and reporting options are available
  3. Because x265 encodes as an elementary hevc stream, mkvmerge or similar is required to mux the video stream back into the audio/subtitle container. If you have mkvmerge available on your system, the script will automatically use it; otherwise, it must be done manually. do not use ffmpeg to remux the streams! The DV metadata will be discarded
    • Due to timestamping issues from the hevc stream, test encode audio/subs are usually out of sync. I'm looking for ways to fix this
  4. The script only supports profile 8.1 for now, as it includes an HDR10 base layer. I hope to add new profiles in the future

New Parameters and Other Minor Enhancements

26 Sep 22:41
Compare
Choose a tag to compare

This release comes with a few new parameters as well as some quality of life enhancements for the script as a whole.


What's New

-TuDepth

An array that brings support for transform unit-related parameters. The first value represents intra depth, and the second value inter depth. (i.e. @(tu-intra-depth, tu-inter-depth))

-LimitTu

Exit condition for TU depth recursion, generally used with the -TuDepth parameter.

New Tuning Options for Two-Pass Encoding via the -FirstPassType Parameter

I've added 3 options for tuning the first pass of a two-pass encode. They are:

  • Default/d - Mirror options in the first and second pass. This is the slowest option, and also the script default
  • Custom/c - My own custom options that are meant to blend the speed of Fast with the quality of Default.
  • Fast/f - This is essentially the equivalent of the no-slow-firstpass argument in x265. As the name suggests, this is meant to speed things up during the first pass only

See README for full details on what arguments are affected.

-Verbose

This is technically a default parameter from the CmdletBinding() attribute of the script, but it is now cascaded down throughout the script module functions for some extra logging information. This is useful for verifying that parameter input is being parsed correctly (or if you just like more info!).

Crop Progress Bar

Sometimes, cropping can take a while (especially for 4K UHD sources with NAL data), so I've added a progress bar that updates as the parallel jobs finish. Neat!

Other Enhancements or Bug Fixes

  • Cropping durations have been reduced slightly for timestamps past the 01:50:00 mark on a sliding scale. This will reduce the amount of time it takes to crop really long sources
  • Windows default path has been updated to a more flexible value (thanks @ImportTaste)
  • Fixed bug with the Get-Content <Log_Path> display line once encoding starts. If a source had a single quote in the title, it broke the string interpolation. This has been fixed

Upcoming

  • Tonemapping! Still working on it.
  • Dolby Vision support

Resize/Rescale Support + Native HDR10+ Parsing

20 Sep 02:58
Compare
Choose a tag to compare

Added 3 new parameters for resizing/rescaling videos using ffmpeg's native scale parameter, as well as scale support from the libzimg library.

As a bonus, I've also integrated HDR10+ parsing directly into the script; no more external dependency needed! Works on all 3 supported operating systems.


What's New

Better support for overriding video filters via -FFMpegExtra.

All scaling parameters work with custom crop arguments passed via the -FFMpegExtra parameter. If you wish to override the default cropping function, simply pass crop arguments manually and the script will handle the rest.

-Scale

Upscale/downscale a video between 3 HD resolutions: 720p, 1080p, and 2160p. Accepted arguments are scale or zscale (custom compilation required).

-ScaleFilter

Scaling algorithm used. Includes all options available to scale and zscale, including lanczos, spline, and bilinear. Note that not all options work with each -Scale argument. See help docs or README for more info.

-Resolution

Rescale resolution. Accepted arguments are 720p, 1080p, or 2160p. The script will automatically convert to SAR based on crop values.

Native HDR10+ Parsing

As mentioned above, an external binary and PATH are no longer required for HDR10+ parsing. I've included Quietvoid's hdr10lus_tool binaries for Windows, Mac, and Linux, and the script will auto-detect what OS you are using.

Upcoming

I'm currently working on a robust tonemapping feature for HDR -> SDR conversions. Note that this feature will require libzimg to work properly, so be sure you have that included in your ffmpeg build.