Первый коммит

This commit is contained in:
2024-09-01 16:44:03 +03:00
commit 9ebb84908a
2 changed files with 163 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
input/*
output/*

161
script.ps1 Normal file
View File

@ -0,0 +1,161 @@
# Variables
$ffmpegPath = (Get-Command ffmpeg -ErrorAction SilentlyContinue).Path
$ffprobePath = (Get-Command ffprobe -ErrorAction SilentlyContinue).Path
$inputDir = "./input"
$outputDir = "./output"
# Functions
# Function to get the bitrate of a video file using ffprobe
function Get-Bitrate {
param (
[string]$filePath
)
# Get bitrate from ffprobe
$bitrateOutput = & $ffprobePath -v error -select_streams v:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1:nokey=1 $filePath
if ([string]::IsNullOrEmpty($bitrateOutput) -or $bitrateOutput -eq "N/A") {
# If direct bitrate is not available, calculate bitrate based on file size and duration
$fileSize = (Get-Item $filePath).Length
$durationOutput = & $ffprobePath -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 $filePath
if ($fileSize -gt 0 -and $durationOutput -ne "N/A" -and $durationOutput -ne "") {
$duration = [float]$durationOutput
$bitrate = [math]::Round(($fileSize * 8) / $duration / 1000) # in kbps
return $bitrate
} else {
Write-Host "Unable to determine bitrate for $filePath."
return 1000
}
}
return [int]$bitrateOutput
}
# Function to get the duration of a video file using ffprobe
function Get-Duration {
param (
[string]$filePath
)
$durationOutput = & $ffprobePath -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 $filePath
if ($durationOutput -ne "N/A" -and $durationOutput -ne "") {
return [float]$durationOutput
} else {
Write-Host "Unable to determine duration for $filePath."
return $null
}
}
# Function to compress the video file until it is below the specified size
function Compress-File {
param (
[string]$inputFilePath,
[string]$outputFilePath,
[int]$initialBitrate,
[int]$maxSizeKB
)
$bitrate = $initialBitrate
$originalDuration = Get-Duration -filePath $file.FullName
$speedFactor = $originalDuration / 3
$outputFilePathTemp = "$outputFilePath.webm"
if ($speedFactor -le 1) {
$speedFactor = 1
}
do {
Write-Host Trying bitrate: ${bitrate}k
# Compress with the current bitrate
& $ffmpegPath -loglevel quiet -i $inputFilePath -t 3 -r 25 -filter:v "setpts=PTS/$speedFactor,scale=-1:512" -c:v libvpx-vp9 -b:v ${bitrate}k $outputFilePathTemp -y
# Check the size of the compressed file
$fileSize = (Get-Item $outputFilePathTemp).Length
$fileSizeKB = [math]::Round($fileSize / 1KB)
if ($fileSizeKB -le $maxSizeKB) {
# Rename the temporary file to the final output file name
if (Test-Path $outputFilePath) { Remove-Item -Path $outputFilePath -Force }
Rename-Item -Path $outputFilePathTemp -NewName (Split-Path $outputFilePath -Leaf)
return
}
$bitrateOffset = 100
if (($fileSizeKB / $maxSizeKB) -gt 2) {
$bitrateOffset = 100 * ($fileSizeKB / $maxSizeKB)
}
# Reduce the bitrate
$bitrate = [math]::Max([int]($bitrate - $bitrateOffset), 100) # Ensuring bitrate doesn't go below 100k
} while ($bitrate -gt 100)
# If bitrate falls too low, retain the last generated file
if (Test-Path $outputFilePathTemp) {
if (Test-Path $outputFilePath) { Remove-Item -Path $outputFilePath -Force }
Rename-Item -Path $outputFilePathTemp -NewName (Split-Path $outputFilePath -Leaf)
}
}
# Check if ffmpeg and ffprobe executables exist
if (-not $ffmpegPath -or -not $ffprobePath) {
Write-Host "ffmpeg or ffprobe is not installed on this system. Exiting..."
exit 1
}
# Check if the output directory exists, if not, create it
if (-not (Test-Path $outputDir)) {
New-Item -Path $outputDir -ItemType Directory -Force | Out-Null
}
# Process each file in the input directory
foreach ($file in Get-ChildItem -Path $inputDir -File) {
$outputFile = "$outputDir/$($file.BaseName).webm"
# Check if the file is a PNG or GIF
if ($file.Extension -notin ".png", ".gif") {
continue
}
Write-Host "Processing $($file.FullName)..."
# Convert the file to WebM format
if ($file.Extension -eq ".png") {
& $ffmpegPath -loglevel quiet -i $file.FullName -r 25 -vf "scale=-1:512" -c:v libvpx-vp9 -pix_fmt rgba $outputFile -y
}
if ($file.Extension -eq ".gif") {
# Get the original duration of the GIF
$originalDuration = Get-Duration -filePath $file.FullName
if ($originalDuration -gt 0) {
$speedFactor = $originalDuration / 3
if ($speedFactor -le 1) {
$speedFactor = 1
}
# Convert the file to WebM format
& $ffmpegPath -loglevel quiet -i $file.FullName -t 3 -r 25 -filter:v "setpts=PTS/$speedFactor,scale=-1:512" -c:v libvpx-vp9 $outputFile -y
} else {
Write-Host "Invalid duration for GIF $($file.FullName). Skipping..."
continue
}
# Check if the file size exceeds 256 KB (262144 bytes)
$fileSize = (Get-Item $outputFile).Length
if ($fileSize -gt 262144) {
Write-Host "File $($outputFile) exceeds 256 KB, compressing..."
# Get the initial bitrate of the WebM file
$initialBitrate = Get-Bitrate -filePath $outputFile
# Compress the file until it is below 256 KB
Compress-File -inputFilePath $file.FullName -outputFilePath $outputFile -initialBitrate $initialBitrate -maxSizeKB 256
}
}
}