Skip to content

Commit 4b709d6

Browse files
Merge pull request #9 from patrickenfuego/config-files
Config files and bug fixes merge
2 parents 56eccc7 + 6fbacd2 commit 4b709d6

10 files changed

+210
-40
lines changed

FFEncoder.ps1

+32-6
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,26 @@
4242
.EXAMPLE
4343
## Scale 2160p video down to 1080p using zscale and spline36 ##
4444
.\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"
45+
.EXAMPLE
46+
## Use a Vapoursynth script as input
47+
.\FFEncoder 'in.mkv' -VapourSynthScript "$HOME/script.vpy -CRF 18 -o 'out.mkv'"
4548
.INPUTS
46-
HD/FHD/UHD video file
49+
HD/FHD/UHD video file
50+
Vapoursynth Script
4751
.OUTPUTS
48-
crop.txt - File used for auto-cropping
49-
4K HDR encoded video file
52+
Crop file
53+
Log file(s)
54+
Encoded video file
5055
.NOTES
51-
For FFEncoder to work, the ffmpeg directory must be in your system PATH (consult your OS documentation for info on how to verify this)
56+
For script binaries to work, they must be included in the system PATH (consult OS documentation for more information):
57+
- ffmpeg
58+
- deew / dee
59+
- mkvmerge
60+
- mkvextract
61+
- x265
5262
5363
Be sure to include an extension at the end of your output file (.mkv, .mp4, .ts, etc.),
54-
or you may be left with a file that will not play
64+
or you may be left with a file that will not play (OS dependent).
5565
5666
.PARAMETER Help
5767
Displays help information for the script
@@ -217,6 +227,22 @@
217227
Deinterlacing filter using yadif. Currently only works with CRF encoding
218228
.PARAMETER GenerateReport
219229
Generates a user friendly report file with important encoding metrics pulled from the log file. File is saved with a .rep extension
230+
.PARAMETER GenerateMKVTagFile
231+
Generate an XML tag file for MKV containers using the TMDB API. Requires a valid TMDB API key
232+
.PARAMETER CompareVMAF
233+
Switch to enable a VMAF comparison. Mandatory to enable this feature
234+
.PARAMETER EnablePSNR
235+
VMAF option. Enables Peak Signal to Noise Ratio (PSNR) evaluation
236+
.PARAMETER EnableSSIM
237+
VMAF option. Enables Structural Similarity Index Measurement (SSIM) evaluation
238+
.PARAMETER LogFormat
239+
Specify the log format for VMAF. Options:
240+
- json
241+
- csv
242+
- sub
243+
- xml
244+
.PARAMETER VapourSynthScript
245+
Pass a VapourSynth script for filtering. Note that all filtering (including cropping) must be done in the VS script
220246
.lINK
221247
Check out the full documentation on GitHub - https://github.com/patrickenfuego/FFEncoder
222248
.LINK
@@ -633,7 +659,7 @@ param (
633659
[Parameter(Mandatory = $false, ParameterSetName = 'VMAF')]
634660
[ValidateSet('json', 'xml', 'csv', 'sub')]
635661
[Alias('LogType', 'VMAFLog')]
636-
[string]$LogFormat
662+
[string]$LogFormat = 'json'
637663
)
638664

639665
#########################################################

README.md

+8-3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ FFEncoder is a cross-platform PowerShell script and module that is meant to make
2323
- [VMAF Comparison](#vmaf-comparison)
2424
- [MKV Tag Generator](#mkv-tag-generator)
2525
- [Script Parameters](#script-parameters)
26+
- [Configuration Files](#configuration-files)
2627
- [Mandatory](#mandatory)
2728
- [Utility](#utility)
2829
- [Audio & Subtitles](#audio--subtitles)
@@ -51,15 +52,13 @@ Check out the [wiki](https://github.com/patrickenfuego/FFEncoder/wiki) for addit
5152
- Mkvtoolnix (optional, but highly recommended)
5253
- VapourSynth (optional)
5354

54-
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.
55-
5655
For users with PowerShell 7.2 or newer, the script uses ANSI output in certain scenarios to enhance the console experience.
5756

5857
---
5958

6059
## Dependency Installation
6160

62-
> 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)
61+
> 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).
6362
6463
### Windows
6564

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

163162
## Script Parameters
164163

164+
### Configuration Files
165+
166+
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.
167+
168+
See the wiki for more information.
169+
165170
FFEncoder can accept the following parameters from the command line:
166171

167172
### Mandatory

config/encoder.ini

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
; COMMENT
2+
; Encoder specific settings in key=value form
3+
4+
[x264]
5+
;open-gop=0
6+
7+
[x265]
8+
;open-gop=0

config/ffmpeg.ini

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
; COMMENT
2+
3+
[Arguments]
4+
; Settings that take arguments. Do not quote arguments:
5+
;-loglevel=panic
6+
7+
[NoArguments]
8+
; Settings that take no arguments:
9+
;-hide_banner

modules/FFTools/FFTools.psd1

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ PowerShellVersion = '7.0'
7070

7171
# 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.
7272
FunctionsToExport = 'Invoke-FFMpeg', 'Invoke-TwoPassFFMpeg', 'New-CropFile', 'Measure-CropDimensions', 'Remove-FilePrompt', 'Write-Report', 'Confirm-HDR10Plus',
73-
'Confirm-DolbyVision', 'Confirm-ScaleFilter', 'Invoke-MkvMerge', 'Invoke-DeeEncoder', 'Read-TimedInput', 'Invoke-VMAF'
73+
'Confirm-DolbyVision', 'Confirm-ScaleFilter', 'Invoke-MkvMerge', 'Invoke-DeeEncoder', 'Read-TimedInput', 'Invoke-VMAF', 'Read-Config'
7474

7575
# 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.
7676
# CmdletsToExport = @()
@@ -92,7 +92,7 @@ FileList = 'FFTools.psd1', 'FFTools.psm1', 'Private\Set-AudioPreference.ps1', 'P
9292
'Private\Get-HDRMetadata.ps1', 'Public\Invoke-FFMpeg.ps1', 'Public\Invoke-TwoPassFFMpeg.ps1', 'Public\New-CropFile.ps1', 'Public\Measure-CropDimensions.ps1', 'Public\Invoke-VMAF.ps1',
9393
'Private\ConvertTo-Stereo.ps1', 'Private\Set-PresetParameters.ps1', 'Private\Set-FFMPegArgs.ps1', 'Private\Set-VideoFilter.ps1', 'Private\Set-TestParameters.ps1',
9494
'Private\Confirm-Parameters.ps1', 'Private\Set-DVArgs.ps1', 'Utils\Invoke-DeeEncoder.ps1','Utils\Confirm-ScaleFilter.ps1','Utils\Write-Report.ps1',
95-
'Utils\Invoke-MkvMerge.ps1', 'Utils\Confirm-HDR10Plus.ps1', 'Utils\Confirm-DolbyVision.ps1', 'Utils\Remove-FilePrompt.ps1'
95+
'Utils\Invoke-MkvMerge.ps1', 'Utils\Confirm-HDR10Plus.ps1', 'Utils\Confirm-DolbyVision.ps1', 'Utils\Remove-FilePrompt.ps1', 'Utils\Read-Config.ps1'
9696

9797
# 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.
9898
PrivateData = @{

modules/FFTools/FFTools.psm1

+2-2
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ ___________ .__ __ .__ ______________________
133133
'@
134134

135135
# Current script release version
136-
[version]$release = '2.1.0'
136+
[version]$release = '2.2.0'
137137

138138

139139
#### End module variables ####
@@ -185,7 +185,7 @@ New-Alias -Name cropdim -Value Measure-CropDimensions -Force
185185
$ExportModule = @{
186186
Alias = @('iffmpeg', 'cropfile', 'cropdim')
187187
Function = @('Invoke-FFmpeg', 'Invoke-TwoPassFFmpeg', 'New-CropFile', 'Measure-CropDimensions', 'Remove-FilePrompt', 'Write-Report', 'Confirm-HDR10Plus',
188-
'Confirm-DolbyVision', 'Confirm-ScaleFilter', 'Invoke-MkvMerge', 'Invoke-DeeEncoder', 'Read-TimedInput', 'Invoke-VMAF')
188+
'Confirm-DolbyVision', 'Confirm-ScaleFilter', 'Invoke-MkvMerge', 'Invoke-DeeEncoder', 'Read-TimedInput', 'Invoke-VMAF', 'Read-Config')
189189
Variable = @('progressColors', 'warnColors', 'emphasisColors', 'errColors', 'osInfo', 'banner1', 'banner2', 'exitBanner', 'ScriptsDirectory',
190190
'release' )
191191
}

modules/FFTools/Private/Set-DVArgs.ps1

+1-8
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ function Set-DVArgs {
9696
[int[]]$VBV,
9797

9898
[Parameter(Mandatory = $false)]
99-
[array]$FFMpegExtra,
99+
[Generic.List[object]]$FFMpegExtra,
100100

101101
[Parameter(Mandatory = $false)]
102102
[hashtable]$EncoderExtra,
@@ -457,13 +457,6 @@ function Set-DVArgs {
457457
#>
458458

459459
if ($x265ExtraArray) { $x265BaseArray.AddRange($x265ExtraArray) }
460-
461-
switch ($x265ExtraArray) {
462-
{ $_ -notcontains '--open-gop' } { $x265BaseArray.Add('--no-open-gop') > $null }
463-
{ $_ -notcontains '--keyint' } { $x265BaseArray.AddRange(@('--keyint', 192)) }
464-
{ $_ -notcontains '--min-keyint' } { $x265BaseArray.AddRange(@('--min-keyint', 24)) }
465-
}
466-
467460

468461
($PresetParams.BIntra -eq 1) ?
469462
($x265BaseArray.Add('--b-intra') > $null) :

modules/FFTools/Private/Set-FFMpegArgs.ps1

+4-18
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ function Set-FFMpegArgs {
9999
[int[]]$VBV,
100100

101101
[Parameter(Mandatory = $false)]
102-
[array]$FFMpegExtra,
102+
[Generic.List[object]]$FFMpegExtra,
103103

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

140140
if ($PSBoundParameters['FFMpegExtra']) {
141-
$ffmpegExtraArray = [ArrayList]@()
141+
$ffmpegExtraArray = [Generic.List[object]]@()
142142
foreach ($arg in $FFMpegExtra) {
143143
if ($arg -is [hashtable]) {
144144
foreach ($entry in $arg.GetEnumerator()) {
@@ -152,20 +152,13 @@ function Set-FFMpegArgs {
152152
}
153153
}
154154

155-
$skip = @{}
156-
@('OpenGop', 'Keyint', 'MinKeyInt', 'Sao').ForEach({ $skip.$_ = $false })
157155
if ($PSBoundParameters['EncoderExtra']) {
158156
$encoderExtraArray = [ArrayList]@()
159157
foreach ($arg in $EncoderExtra.GetEnumerator()) {
160-
elseif ($arg.Name -eq 'open-gop') { $skip.OpenGOP = $true }
161-
elseif ($arg.Name -eq 'keyint') { $skip.Keyint = $true }
162-
elseif ($arg.Name -eq 'min-keyint') { $skip.MinKeyint = $true }
163-
else {
164-
$encoderExtraArray.Add("$($arg.Name)=$($arg.Value)") > $null
165-
}
158+
$encoderExtraArray.Add("$($arg.Name)=$($arg.Value)") > $null
166159
}
167160
}
168-
161+
169162
## Base Array Declarations ##
170163

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

304-
# Set hard coded defaults unless overridden
305-
switch ($skip) {
306-
{ $skip.OpenGOP -eq $false } { $encoderBaseArray.Add('open-gop=0') > $null }
307-
{ $skip.KeyInt -eq $false } { $encoderBaseArray.Add('keyint=192') > $null }
308-
{ $skip.MinKeyInt -eq $false } { $encoderBaseArray.Add('min-keyint=24') > $null }
309-
}
310-
311297
# Set video specific filter arguments unless VS is used
312298
if ([string]::IsNullOrEmpty($Paths.VPY)) {
313299
$vfHash = @{

modules/FFTools/Public/Invoke-FFMpeg.ps1

+50-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using namespace System.IO
2+
using namespace System.Collections
23

34
<#
45
.SYNOPSIS
@@ -165,7 +166,7 @@ function Invoke-FFMpeg {
165166
# Additional ffmpeg options
166167
[Parameter(Mandatory = $false)]
167168
[Alias('FE', 'FFExtra')]
168-
[array]$FFMpegExtra,
169+
[Generic.List[object]]$FFMpegExtra,
169170

170171
# Additional encoder-specific options
171172
[Parameter(Mandatory = $false)]
@@ -402,10 +403,58 @@ function Invoke-FFMpeg {
402403
<#
403404
BUILD FINAL ARGUMENT ARRAYS
404405
406+
Pull configuration file contents
405407
Set the base arguments
406408
Pass arguments to Set-FFMpegArgs or Set-DvArgs functions to prepare for encoding
407409
#>
408410

411+
412+
# Try to parse the config files
413+
try {
414+
# Read config file for additional options
415+
$config = Read-Config -Encoder $Encoder
416+
417+
# Add multi-valued ffmpeg config options to existing hash
418+
if ($config['FFMpegHash']) {
419+
if ($FFMpegExtra) {
420+
$index = $ffmpegExtra.FindIndex( {
421+
$args[0] -is [hashtable]
422+
} )
423+
424+
if ($index -ne -1) {
425+
# Catch error if duplicate keys are present
426+
$FFMpegExtra[$index] += $config['FFMpegHash']
427+
}
428+
else { $FFMpegExtra.Add($config['FFMpegHash']) }
429+
}
430+
else {
431+
$FFMpegExtra = @()
432+
$FFMpegExtra.Add($config['FFMpegHash'])
433+
}
434+
}
435+
436+
# Add single valued ffmpeg config options
437+
if ($config['FFMpegArray']) {
438+
if ($FFMpegExtra) { $ffmpegExtra.AddRange($config['FFMpegArray']) }
439+
else {
440+
$FFMpegExtra = @()
441+
$FFMpegExtra.AddRange($config['FFMpegArray'])
442+
}
443+
}
444+
445+
# Add encoder settings from config file
446+
if ($config['Encoder']) {
447+
if ($EncoderExtra) {
448+
$EncoderExtra += $config['Encoder']
449+
}
450+
else { $EncoderExtra = $config['Encoder'] }
451+
}
452+
}
453+
catch {
454+
$e = $_.Exception.Message
455+
Write-Error "Failed to parse the configuration file(s): $e"
456+
}
457+
409458
$baseArgs = @{
410459
Encoder = $Encoder
411460
Audio = $audio

0 commit comments

Comments
 (0)