Skip to content

Commit

Permalink
Merge pull request #9 from patrickenfuego/config-files
Browse files Browse the repository at this point in the history
Config files and bug fixes merge
  • Loading branch information
patrickenfuego authored Aug 15, 2022
2 parents 56eccc7 + 6fbacd2 commit 4b709d6
Show file tree
Hide file tree
Showing 10 changed files with 210 additions and 40 deletions.
38 changes: 32 additions & 6 deletions FFEncoder.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,26 @@
.EXAMPLE
## Scale 2160p video down to 1080p using zscale and spline36 ##
.\FFEncoder "$HOME\Videos\Ex.Machina.2014.DTS-HD.2160p.mkv" -Scale zscale -ScaleFilter spline36 -Res 1080p -CRF 18 -o "$HOME\Videos\Ex Machina (2014) DTS-HD 1080p.mkv"
.EXAMPLE
## Use a Vapoursynth script as input
.\FFEncoder 'in.mkv' -VapourSynthScript "$HOME/script.vpy -CRF 18 -o 'out.mkv'"
.INPUTS
HD/FHD/UHD video file
HD/FHD/UHD video file
Vapoursynth Script
.OUTPUTS
crop.txt - File used for auto-cropping
4K HDR encoded video file
Crop file
Log file(s)
Encoded video file
.NOTES
For FFEncoder to work, the ffmpeg directory must be in your system PATH (consult your OS documentation for info on how to verify this)
For script binaries to work, they must be included in the system PATH (consult OS documentation for more information):
- ffmpeg
- deew / dee
- mkvmerge
- mkvextract
- x265
Be sure to include an extension at the end of your output file (.mkv, .mp4, .ts, etc.),
or you may be left with a file that will not play
or you may be left with a file that will not play (OS dependent).
.PARAMETER Help
Displays help information for the script
Expand Down Expand Up @@ -217,6 +227,22 @@
Deinterlacing filter using yadif. Currently only works with CRF encoding
.PARAMETER GenerateReport
Generates a user friendly report file with important encoding metrics pulled from the log file. File is saved with a .rep extension
.PARAMETER GenerateMKVTagFile
Generate an XML tag file for MKV containers using the TMDB API. Requires a valid TMDB API key
.PARAMETER CompareVMAF
Switch to enable a VMAF comparison. Mandatory to enable this feature
.PARAMETER EnablePSNR
VMAF option. Enables Peak Signal to Noise Ratio (PSNR) evaluation
.PARAMETER EnableSSIM
VMAF option. Enables Structural Similarity Index Measurement (SSIM) evaluation
.PARAMETER LogFormat
Specify the log format for VMAF. Options:
- json
- csv
- sub
- xml
.PARAMETER VapourSynthScript
Pass a VapourSynth script for filtering. Note that all filtering (including cropping) must be done in the VS script
.lINK
Check out the full documentation on GitHub - https://github.com/patrickenfuego/FFEncoder
.LINK
Expand Down Expand Up @@ -633,7 +659,7 @@ param (
[Parameter(Mandatory = $false, ParameterSetName = 'VMAF')]
[ValidateSet('json', 'xml', 'csv', 'sub')]
[Alias('LogType', 'VMAFLog')]
[string]$LogFormat
[string]$LogFormat = 'json'
)

#########################################################
Expand Down
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ FFEncoder is a cross-platform PowerShell script and module that is meant to make
- [VMAF Comparison](#vmaf-comparison)
- [MKV Tag Generator](#mkv-tag-generator)
- [Script Parameters](#script-parameters)
- [Configuration Files](#configuration-files)
- [Mandatory](#mandatory)
- [Utility](#utility)
- [Audio & Subtitles](#audio--subtitles)
Expand Down Expand Up @@ -51,15 +52,13 @@ Check out the [wiki](https://github.com/patrickenfuego/FFEncoder/wiki) for addit
- Mkvtoolnix (optional, but highly recommended)
- VapourSynth (optional)

The script requires PowerShell 7.0 or newer on all systems as it utilizes new parallel processing features introduced in this version. Multi-threading prior to PowerShell 7 was prone to memory leaks which persuaded me to make the change.

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

---

## Dependency Installation

> You can compile ffmpeg manually from source on all platforms, which allows you to select additional libraries (like Fraunhofer's libfdk AAC encoder). For more information, see [here](https://trac.ffmpeg.org/wiki/CompilationGuide)
> 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](https://trac.ffmpeg.org/wiki/CompilationGuide).
### Windows

Expand Down Expand Up @@ -162,6 +161,12 @@ To use this parameter, you will need a valid TMDB API key. See [the wiki](https:

## Script Parameters

### Configuration Files

Two configuration files, `ffmpeg.ini` and `encoder.ini`, are included and can be used to set frequently used options not covered by script parameters. These files are located in the `config` directory and are loaded each time the script runs.

See the wiki for more information.

FFEncoder can accept the following parameters from the command line:

### Mandatory
Expand Down
8 changes: 8 additions & 0 deletions config/encoder.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
; COMMENT
; Encoder specific settings in key=value form

[x264]
;open-gop=0

[x265]
;open-gop=0
9 changes: 9 additions & 0 deletions config/ffmpeg.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
; COMMENT

[Arguments]
; Settings that take arguments. Do not quote arguments:
;-loglevel=panic

[NoArguments]
; Settings that take no arguments:
;-hide_banner
4 changes: 2 additions & 2 deletions modules/FFTools/FFTools.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ PowerShellVersion = '7.0'

# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
FunctionsToExport = 'Invoke-FFMpeg', 'Invoke-TwoPassFFMpeg', 'New-CropFile', 'Measure-CropDimensions', 'Remove-FilePrompt', 'Write-Report', 'Confirm-HDR10Plus',
'Confirm-DolbyVision', 'Confirm-ScaleFilter', 'Invoke-MkvMerge', 'Invoke-DeeEncoder', 'Read-TimedInput', 'Invoke-VMAF'
'Confirm-DolbyVision', 'Confirm-ScaleFilter', 'Invoke-MkvMerge', 'Invoke-DeeEncoder', 'Read-TimedInput', 'Invoke-VMAF', 'Read-Config'

# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
# CmdletsToExport = @()
Expand All @@ -92,7 +92,7 @@ FileList = 'FFTools.psd1', 'FFTools.psm1', 'Private\Set-AudioPreference.ps1', 'P
'Private\Get-HDRMetadata.ps1', 'Public\Invoke-FFMpeg.ps1', 'Public\Invoke-TwoPassFFMpeg.ps1', 'Public\New-CropFile.ps1', 'Public\Measure-CropDimensions.ps1', 'Public\Invoke-VMAF.ps1',
'Private\ConvertTo-Stereo.ps1', 'Private\Set-PresetParameters.ps1', 'Private\Set-FFMPegArgs.ps1', 'Private\Set-VideoFilter.ps1', 'Private\Set-TestParameters.ps1',
'Private\Confirm-Parameters.ps1', 'Private\Set-DVArgs.ps1', 'Utils\Invoke-DeeEncoder.ps1','Utils\Confirm-ScaleFilter.ps1','Utils\Write-Report.ps1',
'Utils\Invoke-MkvMerge.ps1', 'Utils\Confirm-HDR10Plus.ps1', 'Utils\Confirm-DolbyVision.ps1', 'Utils\Remove-FilePrompt.ps1'
'Utils\Invoke-MkvMerge.ps1', 'Utils\Confirm-HDR10Plus.ps1', 'Utils\Confirm-DolbyVision.ps1', 'Utils\Remove-FilePrompt.ps1', 'Utils\Read-Config.ps1'

# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
PrivateData = @{
Expand Down
4 changes: 2 additions & 2 deletions modules/FFTools/FFTools.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ ___________ .__ __ .__ ______________________
'@

# Current script release version
[version]$release = '2.1.0'
[version]$release = '2.2.0'


#### End module variables ####
Expand Down Expand Up @@ -185,7 +185,7 @@ New-Alias -Name cropdim -Value Measure-CropDimensions -Force
$ExportModule = @{
Alias = @('iffmpeg', 'cropfile', 'cropdim')
Function = @('Invoke-FFmpeg', 'Invoke-TwoPassFFmpeg', 'New-CropFile', 'Measure-CropDimensions', 'Remove-FilePrompt', 'Write-Report', 'Confirm-HDR10Plus',
'Confirm-DolbyVision', 'Confirm-ScaleFilter', 'Invoke-MkvMerge', 'Invoke-DeeEncoder', 'Read-TimedInput', 'Invoke-VMAF')
'Confirm-DolbyVision', 'Confirm-ScaleFilter', 'Invoke-MkvMerge', 'Invoke-DeeEncoder', 'Read-TimedInput', 'Invoke-VMAF', 'Read-Config')
Variable = @('progressColors', 'warnColors', 'emphasisColors', 'errColors', 'osInfo', 'banner1', 'banner2', 'exitBanner', 'ScriptsDirectory',
'release' )
}
Expand Down
9 changes: 1 addition & 8 deletions modules/FFTools/Private/Set-DVArgs.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ function Set-DVArgs {
[int[]]$VBV,

[Parameter(Mandatory = $false)]
[array]$FFMpegExtra,
[Generic.List[object]]$FFMpegExtra,

[Parameter(Mandatory = $false)]
[hashtable]$EncoderExtra,
Expand Down Expand Up @@ -457,13 +457,6 @@ function Set-DVArgs {
#>

if ($x265ExtraArray) { $x265BaseArray.AddRange($x265ExtraArray) }

switch ($x265ExtraArray) {
{ $_ -notcontains '--open-gop' } { $x265BaseArray.Add('--no-open-gop') > $null }
{ $_ -notcontains '--keyint' } { $x265BaseArray.AddRange(@('--keyint', 192)) }
{ $_ -notcontains '--min-keyint' } { $x265BaseArray.AddRange(@('--min-keyint', 24)) }
}


($PresetParams.BIntra -eq 1) ?
($x265BaseArray.Add('--b-intra') > $null) :
Expand Down
22 changes: 4 additions & 18 deletions modules/FFTools/Private/Set-FFMpegArgs.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ function Set-FFMpegArgs {
[int[]]$VBV,

[Parameter(Mandatory = $false)]
[array]$FFMpegExtra,
[Generic.List[object]]$FFMpegExtra,

# Extra encoder parameters passed by user
[Parameter(Mandatory = $false)]
Expand Down Expand Up @@ -138,7 +138,7 @@ function Set-FFMpegArgs {
## Unpack extra parameters ##

if ($PSBoundParameters['FFMpegExtra']) {
$ffmpegExtraArray = [ArrayList]@()
$ffmpegExtraArray = [Generic.List[object]]@()
foreach ($arg in $FFMpegExtra) {
if ($arg -is [hashtable]) {
foreach ($entry in $arg.GetEnumerator()) {
Expand All @@ -152,20 +152,13 @@ function Set-FFMpegArgs {
}
}

$skip = @{}
@('OpenGop', 'Keyint', 'MinKeyInt', 'Sao').ForEach({ $skip.$_ = $false })
if ($PSBoundParameters['EncoderExtra']) {
$encoderExtraArray = [ArrayList]@()
foreach ($arg in $EncoderExtra.GetEnumerator()) {
elseif ($arg.Name -eq 'open-gop') { $skip.OpenGOP = $true }
elseif ($arg.Name -eq 'keyint') { $skip.Keyint = $true }
elseif ($arg.Name -eq 'min-keyint') { $skip.MinKeyint = $true }
else {
$encoderExtraArray.Add("$($arg.Name)=$($arg.Value)") > $null
}
$encoderExtraArray.Add("$($arg.Name)=$($arg.Value)") > $null
}
}

## Base Array Declarations ##

#Primary array list initialized with global values
Expand Down Expand Up @@ -301,13 +294,6 @@ function Set-FFMpegArgs {
$ffmpegExtraArray.RemoveRange($i, 2)
}

# Set hard coded defaults unless overridden
switch ($skip) {
{ $skip.OpenGOP -eq $false } { $encoderBaseArray.Add('open-gop=0') > $null }
{ $skip.KeyInt -eq $false } { $encoderBaseArray.Add('keyint=192') > $null }
{ $skip.MinKeyInt -eq $false } { $encoderBaseArray.Add('min-keyint=24') > $null }
}

# Set video specific filter arguments unless VS is used
if ([string]::IsNullOrEmpty($Paths.VPY)) {
$vfHash = @{
Expand Down
51 changes: 50 additions & 1 deletion modules/FFTools/Public/Invoke-FFMpeg.ps1
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using namespace System.IO
using namespace System.Collections

<#
.SYNOPSIS
Expand Down Expand Up @@ -165,7 +166,7 @@ function Invoke-FFMpeg {
# Additional ffmpeg options
[Parameter(Mandatory = $false)]
[Alias('FE', 'FFExtra')]
[array]$FFMpegExtra,
[Generic.List[object]]$FFMpegExtra,

# Additional encoder-specific options
[Parameter(Mandatory = $false)]
Expand Down Expand Up @@ -402,10 +403,58 @@ function Invoke-FFMpeg {
<#
BUILD FINAL ARGUMENT ARRAYS
Pull configuration file contents
Set the base arguments
Pass arguments to Set-FFMpegArgs or Set-DvArgs functions to prepare for encoding
#>


# Try to parse the config files
try {
# Read config file for additional options
$config = Read-Config -Encoder $Encoder

# Add multi-valued ffmpeg config options to existing hash
if ($config['FFMpegHash']) {
if ($FFMpegExtra) {
$index = $ffmpegExtra.FindIndex( {
$args[0] -is [hashtable]
} )

if ($index -ne -1) {
# Catch error if duplicate keys are present
$FFMpegExtra[$index] += $config['FFMpegHash']
}
else { $FFMpegExtra.Add($config['FFMpegHash']) }
}
else {
$FFMpegExtra = @()
$FFMpegExtra.Add($config['FFMpegHash'])
}
}

# Add single valued ffmpeg config options
if ($config['FFMpegArray']) {
if ($FFMpegExtra) { $ffmpegExtra.AddRange($config['FFMpegArray']) }
else {
$FFMpegExtra = @()
$FFMpegExtra.AddRange($config['FFMpegArray'])
}
}

# Add encoder settings from config file
if ($config['Encoder']) {
if ($EncoderExtra) {
$EncoderExtra += $config['Encoder']
}
else { $EncoderExtra = $config['Encoder'] }
}
}
catch {
$e = $_.Exception.Message
Write-Error "Failed to parse the configuration file(s): $e"
}

$baseArgs = @{
Encoder = $Encoder
Audio = $audio
Expand Down
Loading

0 comments on commit 4b709d6

Please sign in to comment.