Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save hym3242/341abd49d826936b0f63e148830fddc4 to your computer and use it in GitHub Desktop.
Save hym3242/341abd49d826936b0f63e148830fddc4 to your computer and use it in GitHub Desktop.
Recusively list medida files, use ffmpeg (with hwaccel qsv) to scrub the files (attempt to decode from start to end) to find errors
#$ErrorView = "Basic"
# Suppresses all errors globally in the script/session
#$ErrorActionPreference = "SilentlyContinue" #causes script to stuck at get-childitem
param(
[string]$rootfolderarg
)
function Sanitize-FileName {
param ([string]$fileName)
$invalidChars = [System.IO.Path]::GetInvalidFileNameChars()
foreach ($char in $invalidChars) {
$fileName = $fileName -replace [regex]::Escape($char), '_'
}
return $fileName
}
$ffmpegdir = "D:\ffmpeg-2024-09-26-git-f43916e217-full_build\bin"
# Define the folder to start searching for video files
$rootFolder = $rootfolderarg
# Define the folder where error reports will be stored
$errorReportFolder = "E:\ffmpeg_scrub_error_reports"
$warnReportFolder = "E:\ffmpeg_scrub_error_reports\warnings_non-mono-dts"
# Create the error report folder if it does not exist
if (!(Test-Path -Path $errorReportFolder)) {
New-Item -ItemType Directory -Path $errorReportFolder | Out-Null
}
# Define video file extensions to search for
$fileExtensions = @("*.mkv", "*.mp4", "*.webm", "*.avi", "*.divx")
#$fileExtensions = @("*.VOB")
#$fileExtensions = @("*.flac", "*.ape", "*.mp3")
# Recursively get all video files with the specified extensions
write-host "LISTING FILES..." -ForegroundColor darkgray -NoNewline
$videoFiles = Get-ChildItem -Path $rootFolder -Recurse -Include $fileExtensions | Sort-Object LastWriteTime #-Descending
#$videoFiles = $videoFiles | Where-Object { $_.LastWriteTime -gt '2023-04-14' }
$totalCnt = ($videoFiles | Measure-Object).count
write-host "DONE, TOTAL $totalCnt" -ForegroundColor DarkGray
$cleanCnt = 0
$warnCnt = 0
$errorCnt = 0
$processedCnt = 0
# Loop through each video file and check for errors using ffmpeg
foreach ($file in $videoFiles) {
$filePath = $file.FullName
$errorFileName = "ERRORS_$filePath.txt"
$errorFileName = Sanitize-FileName -fileName $errorFileName
$errorFilePath = "$errorReportFolder\$errorFileName"
$warnFileName = "WARN_NON-MONO-DTS_$filePath.txt"
$warnFileName = Sanitize-FileName -fileName $warnFileName
$warnFilePath = "$warnReportFolder\$warnFileName"
# Run ffmpeg command to check for errors
#write-host "PROBE: $filePath`r" -ForegroundColor DarkGray -nonewline
$filecodec = & "$ffmpegdir\ffprobe.exe" -v error -select_streams v:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$filePath" 2>$null
#write-host "CODEC: `'$filecodec`'" -ForegroundColor darkgray
Write-Host "START: $filePath`r" -ForegroundColor DarkGray -NoNewline
if ( $filecodec -eq "av1" -or [string]::IsNullOrEmpty($filecodec) ){
#write-host "DEBUG: NO HWACCEL" -ForegroundColor DarkGray
$ffmpegOutput = & "$ffmpegdir\ffmpeg.exe" -hide_banner -v repeat+error -i "$filePath" -f null - 2>&1 | ForEach-Object ToString
}else{
#write-host "DEBUG: HWACCEL QSV" -ForegroundColor DarkGray
$ffmpegOutput = & "$ffmpegdir\ffmpeg.exe" -hide_banner -v repeat+error -hwaccel qsv -i "$filePath" -f null - 2>&1 | ForEach-Object ToString
}
$ffmpegOutput = ($ffmpegOutput -split "`n" | Where-Object { $_ -notlike "*Unknown Metadata OBU type 6*" }) -join "`n"
# If there is any output from the ffmpeg command, save it to a file
if ($ffmpegOutput) {
#$ffmpegOutput | get-member
#write-host ( $ffmpegOutput ) -ForegroundColor darkgray
#write-host ( $ffmpegOutput | out-string) -ForegroundColor darkgray
#echo $ffmpegOutput
$allContainDTS = ($ffmpegOutput -split "`n" | ForEach-Object { $_ -like "*non monotonically increasing dts*" }) -notcontains $false
if( $allContainDTS ){
Write-Host "WARNG: $filePath" -ForegroundColor yellow
$ffmpegOutput | Out-String -Width 8000 -Stream | %{ $_.TrimEnd() } | Out-File -literalPath "$warnFilePath"
$warnCnt++
}else{
Write-Host "ERROR: $filePath" -ForegroundColor red
$ffmpegOutput | Out-String -Width 8000 -Stream | %{ $_.TrimEnd() } | Out-File -literalPath "$errorFilePath"
$errorCnt++
}
#Write-Host "OUTFFILE: $errorFilePath" -ForegroundColor DarkRed
} else {
Write-Host "CLEAN: $filePath." -ForegroundColor green
$cleanCnt++
}
$processedCnt++
$percentComplete = [math]::Round(($processedCnt / $totalCnt) * 100, 0)
$Host.UI.RawUI.WindowTitle = "$processedCnt/$totalCnt $percentComplete% CLEAN $cleanCnt WARN $warnCnt ERROR $errorCnt"
}#END foreach
write-host "`nCOMPLETE: TOTAL $totalCnt " -NoNewline
if($cleanCnt -eq 0) {Write-host "CLEAN $cleanCnt " -ForegroundColor darkgray -NoNewline} else {Write-host "CLEAN $cleanCnt " -ForegroundColor green -NoNewline}
if($warnCnt -eq 0) {write-host "WARN $warnCnt " -ForegroundColor darkgray -NoNewline} else {write-host "WARN $warnCnt " -ForegroundColor yellow -NoNewline}
if($errorCnt -eq 0) {Write-Host "ERROR $errorCnt" -ForegroundColor darkgray} else {Write-Host "ERROR $warnCnt" -ForegroundColor red}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment