Skip to content

Instantly share code, notes, and snippets.

@chiepomme
Last active July 18, 2022 14:26
Show Gist options
  • Save chiepomme/8c6546dda7203ecc1c73d91db5c6a7bb to your computer and use it in GitHub Desktop.
Save chiepomme/8c6546dda7203ecc1c73d91db5c6a7bb to your computer and use it in GitHub Desktop.
Encode a video file for discord regarding the nitro file limit with ffmpeg
@echo off
cd /d %~dp0
"C:\Program Files\PowerShell\7\pwsh.exe" -File Encode.ps1 %1
Param([String]$InputVideoPath)
$Dir = Split-Path $InputVideoPath -Parent
$Filename = Split-Path $InputVideoPath -LeafBase
$OutputVideoPath = "${Dir}\${Filename}-discord.mp4"
$VideoDurationSec = [double](ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "${InputVideoPath}")
# https://trac.ffmpeg.org/wiki/Encode/H.265#:~:text=about%20more%20options.-,Two%2DPass%20Encoding,-This%20method%20is
$TargetSizeMiB = 100
$KiBitsPerMiB = 8192
$TargetSizeKiBits = $TargetSizeMiB * $KiBitsPerMiB
$TargetBitrate = $TargetSizeKiBits / $VideoDurationSec
$TargetAudioBitrate = 128
$MaxVideoBitrate = 100000
$TargetVideoBitrate = [Math]::Min($MaxVideoBitrate, [int]($TargetBitrate - $TargetAudioBitrate))
$OneMiB = [Math]::Pow(2, 20)
for ($Scale = 1.0; $Scale -ge 0; $Scale -= 0.05)
{
$ScaledTargetVideoBitrate = [int]($TargetVideoBitrate * $Scale)
ffmpeg -y -i "${InputVideoPath}" -c:v libx264 -b:v ${ScaledTargetVideoBitrate}k -pass 1 -an "${OutputVideoPath}"
ffmpeg -y -i "${InputVideoPath}" -c:v libx264 -b:v ${ScaledTargetVideoBitrate}k -pass 2 -c:a aac -b:a ${TargetAudioBitrate}k "${OutputVideoPath}"
$EncodedVideoSizeMiB = (Get-Item "${OutputVideoPath}").length / $OneMiB
if ($EncodedVideoSizeMiB -le $TargetSizeMiB)
{
break;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment