Compare commits

..

5 Commits

22 changed files with 1240 additions and 86 deletions

View File

@ -1,5 +1,4 @@
# Automated HEVC-Video-Converter
# Automated HEVC-Video-Converter 1.0
A PowerShell script for converting video to the HEVC video format using GPU hardware acceleration with NVEnc for Windows. A PowerShell script for converting video to the HEVC video format using GPU hardware acceleration with NVEnc for Windows.
@ -20,21 +19,23 @@ _Results vary and depend on the input video's format, bitrate etc._
- Recent nvidia graphics card ([see: NVENC support matrix](https://developer.nvidia.com/video-encode-decode-gpu-support-matrix)) - Recent nvidia graphics card ([see: NVENC support matrix](https://developer.nvidia.com/video-encode-decode-gpu-support-matrix))
- Latest nvidia graphics drivers - Latest nvidia graphics drivers
## Encoding ## Encoding
During encoding (conversion), high **CPU** and **GPU** usage is normal. Make sure that you only run the script if no other graphics processes are running on the computer. (Example computer games) During encoding (conversion), high **CPU** and **GPU** usage is normal. Make sure that you only run the script if no other graphics processes are running on the computer. (Example computer games)
The script converts the files next to the original with '-HEVC' at the end or by replacing the string x264 (old) in the file name with x265. The script converts the files next to the original with '-HEVC' at the end or by replacing the string x264 (old) in the file name with x265.
After conversion, a test of the new video file is performed to ensure its integrity. After conversion, a test of the new video file is performed to ensure its integrity.
If this test is successful, the old file is deleted. If this test is successful, the old file is deleted.
If not, the failed conversion file is deleted and logged. If not, the failed conversion file is deleted and logged.
## Script Usage ## Script Usage
1. Clone this repository on your computer 1. Clone this repository on your computer
2. Download the latest NVEnc for Windows: https://github.com/rigaya/NVEnc/releases 2. Download the latest NVEnc for Windows: https://github.com/rigaya/NVEnc/releases
3. Extract the files to "video-in-place-hevc-converter\encoder\" and replace the old files. 3. Extract the files to "video-in-place-hevc-converter\encoder\" and replace the old files.
4. Edit the $videoPath variable in the PowerShell file to point to the folder of your "video files" to convert. (**ATTENTION: The ending-slash must be preserved in the path specification!**) 4. Edit the $videoPath variable in the PowerShell file to point to the folder of your "video files" to convert. (**ATTENTION: The ending-slash must be preserved in the path specification!**)
5. Execute **convert_Videos.ps1** to convert the video files under the specified path to HEVC. 5. Execute **convert_Videos.ps1** to convert the video files under the specified path to HEVC.
## Extra Content (\_extras folder)
- **manually_review_videos.ps1** - Redoes the review process using the "review_needed.log" -> before useing set the "$logFolderName" variable in file.

View File

@ -0,0 +1,304 @@
# Converts videos back to x264 for given path: (Video resolution is same as source up to 8K)
# Converter: https://github.com/rigaya/NVEnc/releases
# Forces a higher resolution with ffmpeg than actually intended for the x264 standard.
# Workaround to createn non-standart 8K x254 videos.
#-----------------------------------------------------------------------
# Edit the $videoPath variable to point to your video-files folder:
$videoPath = 'Z:\__VR_SP_CONTENT\_data'
#-----------------------------------------------------------------------
$forceReviewAll = $false # If set to $true all failed conversions are reviewed even those that are obviously corrupt.
$ffmpegBin = "$PSScriptRoot\ffmpeg\ffmpeg.exe"
$fileTester = "$PSScriptRoot\..\mediainfo.exe"
$reviewPlayer = "C:\Program Files\VideoLAN\VLC\vlc.exe"
#############################################################################################################
# Testing and conversion preparations #
#############################################################################################################
if(!(Test-Path $ffmpegBin -PathType leaf))
{
Write-Host "ffmpeg.exe not found, please check path in `"$ffmpegBin`"." -ForegroundColor Yellow
Read-Host -Prompt "Press Enter to exit"
exit
}
# Get video list from provided path:
$videos = Get-ChildItem -LiteralPath $videoPath -Name -Recurse -Include ('*.mp4', '*.mkv') #('*.avi', '*.mp4', '*.mkv') - avi currently doesn't work.
# Instantiating used variables:
$videoID = 1
$convertedVideos = 0
$notConvertedVideos = 0
$failedVideos = 0
# Square brackets are used as wildcards in Powershell.
# To recognize this as normal text, the LogWite function uses the -LiteralPath parameter instead of the -Path parameter.
$logFolderName = $((Get-Date).tostring("yyyy-MM-dd") + ' - [run started at ' + (Get-Date).tostring("HH-mm") + ']')
$count = $videos.Count
if($videos.Count -lt 1)
{
Write-Host "No videos found in: $videoPath" -ForegroundColor Red
Read-Host -Prompt "Press Enter to exit"
exit
}
# Log write function:
Function LogWrite
{
Param ([string]$logstring)
Add-content -LiteralPath $Logfile -value $logstring
}
# Create new log directory:
New-Item -itemType Directory -Path $PSScriptRoot\..\logs\ -Name $logFolderName > $null
# Calculates the total size of the given directory in GB:
Write-Host "Inizialization in progress.."
$folderSizeInGB = "{0:N2} GB" -f ((Get-ChildItem $videoPath -Recurse | Measure-Object -Property Length -Sum -ErrorAction Stop).Sum / 1GB)
Clear-Host # Clears the upper message from the window
#############################################################################################################
# END - Testing and conversion preparations
#############################################################################################################
# Main conversion process #
#############################################################################################################
Write-Host "Found $count videos with a total size of $folderSizeInGB - starting converter.." -ForegroundColor Cyan
Write-Host
Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
foreach($video in $videos)
{
$video = $video.Replace("`"", "")
$inputFile = $videoPath + "\" + $video
# Pre-file-check if "HEVC" exist in filename skip filechecking:
if ($video -match "HEVC")
{
$codec = "HEVC"
} else {
# Get and check File info for codec, if it's already HEVC: - JSON query: (['media']['track'][1]['Format'])
$fileDetails = cmd /c $fileTester $inputFile --Output=JSON | ConvertFrom-Json
$codec = $fileDetails.media.track[1].Format
}
# If not already HEVC, convert video using NVEncC64:
if($codec -eq "HEVC")
{
# Configure new file naming:
if ($video -match "265")
{
$outputFile = $videoPath + "\" + $video.Replace("265", "264")
} else {
$outputFile = $videoPath + "\" + $video.Insert(($video.Length - 4), '-x264')
}
Write-Host "Analyzing video ($videoID of $count), starting convertion of number: $($convertedVideos + 1) please wait.." -ForegroundColor Magenta
Write-Host "$video `nto:`n$outputFile" -ForegroundColor White
Write-Host
# If the Subtitles should not be copied, delete the "--sub-copy 1,2" argument.
#$arguments = "--input `"$inputFile`" --codec AVC --audio-copy 1,2,3,4 --sub-copy 1,2,3,4 --profile $profile --output `"$outputFile`""
$arguments = "-i `"$inputFile`" -c:v libx264 -preset fast -crf 18 -c:a copy -map 0 -map_metadata 0 -movflags +faststart -pix_fmt yuv420p `"$outputFile`""
Start-Process $ffmpegBin -ArgumentList $arguments -WindowStyle Minimized
#$processName = 'NVEncC64'
$processName = 'ffmpeg'
Start-Sleep -Seconds 1
# Sets to use 3 cores (always set to one less core that your CPU has)
# 2 Cores = 3, 3 Cores = 7, 4 cores = 15, 5 cores = 31, 6 cores = 63
# Code to calculate for your CPU:
# $noOfCores = Get-WmiObject Win32_Processor | Measure-Object NumberOfLogicalProcessors -Sum
# $noOfCores.Sum = $noOfCores.Sum - 1
# [math]::Pow(2,$($noOfCores).Sum) - 1
#
$process = Get-Process $processName; $process.ProcessorAffinity=7
Start-Sleep -Seconds 2
# Sets priorty to High
# Values: High, AboveNormal, Normal, BelowNormal, Low
$process = Get-Process -Id $process.Id
$process.PriorityClass = 'High'
# Waits for process to complete
$processID = (Get-Process $processName).id
Wait-Process -Id $processID
if(Test-Path -LiteralPath $outputFile)
# Specifies a path to be tested. Unlike Path, the value of the LiteralPath parameter is used exactly as it is typed.
#No characters are interpreted as wildcard characters.
{
Write-Host "CONVERSION DONE! FILE: `"$outputFile`" FOUND" -ForegroundColor Yellow
Start-Sleep -Seconds 4
# Check if File is valid; the duration of video must be the same! (['media']['track'][0]['Duration']):
$fileDetails_new = cmd /c $fileTester $outputFile --Output=JSON | ConvertFrom-Json
# This code gets the duration and splits it in two parts, only the part before the "." is needed:
$StreamSize_old,$notused = $($fileDetails.media.track[0].Duration).split('.')
$StreamSize_new,$notused = $($fileDetails_new.media.track[0].Duration).split('.')
Write-Host
Write-Host "Old Duration was: $StreamSize_old `nnew Duration is: $StreamSize_new" -ForegroundColor White
Write-Host
if ($StreamSize_new -eq $StreamSize_old)
{
# Delete old video File!
Write-Host "Conversion Successful! - Deleting old file.."
Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
Remove-Item -LiteralPath $inputFile
$convertedVideos = $convertedVideos + 1
$Logfile = "$PSScriptRoot\..\logs\$logFolderName\successfully_converted.log"
LogWrite "$outputFile"
} else
{
if (($StreamSize_new -eq $($StreamSize_old - 1)) -or ($($StreamSize_new - 1) -eq $StreamSize_old))
{
# Newly converted file does not match exactly the old duration. But diffrence its not more than 1 sec!
Write-Host "Conversion Done! - Streamsize is not exactly the same. But still OK - Ignoring!"
Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
Remove-Item -LiteralPath $inputFile
$convertedVideos = $convertedVideos + 1
$Logfile = "$PSScriptRoot\..\logs\$logFolderName\successfully_converted.log"
LogWrite "$outputFile"
} elseif (($StreamSize_new -ge $($StreamSize_old - 20)) -or ($($StreamSize_new - 20) -ge $StreamSize_old))
{
# New converted file has been converted but with up to max 20 seconds deviation!
Write-Host "Conversion Done! - But streamsize is not the same. - Please review!"
Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
$review = $true
$convertedVideos = $convertedVideos + 1
$Logfile = "$PSScriptRoot\..\logs\$logFolderName\review_needed.log"
LogWrite "$inputFile,$outputFile"
} else
{
if ($forceReviewAll)
{
# Mark probably corrupted file for review
Write-Host "Conversion Failed! - Marked for review! because it is desired."
Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
$review = $true
$convertedVideos = $convertedVideos + 1
$Logfile = "$PSScriptRoot\..\logs\$logFolderName\review_needed.log"
LogWrite "$inputFile,$outputFile"
} else
{
# Delete obviously corrupt File!
Write-Host "Conversion Failded! - Deleting new converted file.." -ForegroundColor Red
Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
Remove-Item -LiteralPath $outputFile
$failedVideos = $failedVideos + 1
$notConvertedVideos = $notConvertedVideos + 1
$Logfile = "$PSScriptRoot\..\logs\$logFolderName\error_during_conversion.log"
LogWrite "$inputFile,$StreamSize_new,$StreamSize_old,"
}
}
}
}
} else
{
# Alert if video doesn't need conversion:
Write-Host "Analyzing video ($videoID of $count) - skip" -ForegroundColor Magenta
Write-Host "$video is already in correct format!" -ForegroundColor Green
Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
# Increments not converted video counter:
$notConvertedVideos = $notConvertedVideos + 1
$Logfile = "$PSScriptRoot\..\logs\$logFolderName\skipped_files.log"
LogWrite "$inputFile"
}
# Increments video counter:
$videoID = $videoID + 1
$outputFile = "" # Resets the variable to nothing, that in case of an error the old file is not affected.
}
#############################################################################################################
# END - Main conversion process
#############################################################################################################
# Evaluation part of the conversion script #
#############################################################################################################
if ($review)
{
$reviewFiles = Get-content -LiteralPath "$PSScriptRoot\..\logs\$logFolderName\review_needed.log" | Measure-Object Line
$ReviewCount = $reviewFiles.Lines
Write-Host "There are $ReviewCount files to review.." -ForegroundColor Yellow
Read-Host -Prompt "Press Enter to start reviewing first file"
Write-Host
Write-Host "################################################################################################"
$review_count = 1
foreach($review_pair in Get-Content -LiteralPath "$PSScriptRoot\..\logs\$logFolderName\review_needed.log")
{
$oldFile,$newFile = $review_pair.split(',')
Write-Host "Playing $review_count converted file: $newFile"
Write-Host
# Starting VLC Player with the file to review
Start-Process $reviewPlayer -ArgumentList `"$newFile`"
Start-Sleep -Seconds 6
# Wait until player is closed.
$processID = (Get-Process "vlc").id
Wait-Process -Id $processID
$msg = 'Do you want to keep the newly converted file and delete the old? (N for deleting NEW-file) [Y/N]'
do {
$response = Read-Host -Prompt $msg
} until (($response -eq 'n') -or ($response -eq 'y'))
if ($response -eq 'y')
{
Write-Host "delete old file, keep newly converted.."
$to_delete = $oldFile
} else
{
Write-Host "delete newly converted, keep old file"
$to_delete = $newFile
$failedVideos = $failedVideos + 1
$convertedVideos = $convertedVideos - 1
}
Write-Host "DELETED: $to_delete" -ForegroundColor Red
Remove-Item -LiteralPath $to_delete
Write-Host "------------------------------------------------------------------------------------------------"
Start-Sleep -Seconds 2
}
}
Write-Host "Final calculations are in progress.."
$folderSizeInGB2 = "{0:N2} GB" -f ((Get-ChildItem $videoPath -Recurse | Measure-Object -Property Length -Sum -ErrorAction Stop).Sum / 1GB)
if($notConvertedVideos -eq 0)
{
Write-Host "Finished converted $convertedVideos out of $count videos." -ForegroundColor Green
} else
{
if($failedVideos -eq 0)
{
Write-Host "Finished converted $convertedVideos out of $count videos. - $notConvertedVideos where not converted because of already correct codec!" -ForegroundColor Green
} else
{
Write-Host "Finished converted $convertedVideos out of $count videos. - $notConvertedVideos where not converted because error or already correct codec!!" -ForegroundColor Green
Write-Host "$failedVideos have failed!" -ForegroundColor Red
}
}
Write-Host "Directory size before conversion: $folderSizeInGB"
Write-Host "Directory size after conversion: $folderSizeInGB2"
Read-Host -Prompt "Press Enter to exit"
#############################################################################################################
# END - conversion script

View File

@ -0,0 +1,326 @@
# Converts videos back to x264 for VR playback for given path:
# Converter: https://github.com/rigaya/NVEnc/releases
# Maximum VR Video Dimensions for Oculus Go are: 3840x2048 pixel!! Higher resolution ends with blackscreen!
# Maximum resolution for x264 codec is = 4096x4096 pixel!
#-----------------------------------------------------------------------
# Edit the $videoPath variable to point to your video-files folder:
$videoPath = 'Z:\__VR_SP_CONTENT\_data'
#-----------------------------------------------------------------------
$debug = $true
$forceReviewAll = $false # If set to $true all failed conversions are reviewed even those that are obviously corrupt.
$forceReconvertAllToMatchVRresolution = $true; # only x264 videos AND videos not bigger than 3840x2048 pixel are playable on the Oculus Go.
$NVEncoder = "$PSScriptRoot\..\encoder\NVEncC64.exe"
$fileTester = "$PSScriptRoot\..\mediainfo.exe"
$reviewPlayer = "C:\Program Files\VideoLAN\VLC\vlc.exe"
#############################################################################################################
# Testing and conversion preparations #
#############################################################################################################
if(!(Test-Path $NVEncoder -PathType leaf))
{
Write-Host "NVEncC64.exe not found, please check path in `"$NVEncoder`"." -ForegroundColor Yellow
Read-Host -Prompt "Press Enter to exit"
exit
}
# Get video list from provided path:
$videos = Get-ChildItem -LiteralPath $videoPath -Name -Recurse -Include ('*.mp4', '*.mkv') #('*.avi', '*.mp4', '*.mkv') - avi currently doesn't work.
# Instantiating used variables:
$videoID = 1
$convertedVideos = 0
$notConvertedVideos = 0
$failedVideos = 0
# Square brackets are used as wildcards in Powershell.
# To recognize this as normal text, the LogWite function uses the -LiteralPath parameter instead of the -Path parameter.
$logFolderName = $((Get-Date).tostring("yyyy-MM-dd") + ' - [run started at ' + (Get-Date).tostring("HH-mm") + ']')
$count = $videos.Count
if($videos.Count -lt 1)
{
Write-Host "No videos found in: $videoPath" -ForegroundColor Red
Read-Host -Prompt "Press Enter to exit"
exit
}
# Log write function:
Function LogWrite
{
Param ([string]$logstring)
Add-content -LiteralPath $Logfile -value $logstring
}
# Create new log directory:
New-Item -itemType Directory -Path $PSScriptRoot\..\logs\ -Name $logFolderName > $null
# Calculates the total size of the given directory in GB:
Write-Host "Inizialization in progress.."
$folderSizeInGB = "{0:N2} GB" -f ((Get-ChildItem $videoPath -Recurse | Measure-Object -Property Length -Sum -ErrorAction Stop).Sum / 1GB)
Clear-Host # Clears the upper message from the window
#############################################################################################################
# END - Testing and conversion preparations
#############################################################################################################
# Main conversion process #
#############################################################################################################
Write-Host "Found $count videos with a total size of $folderSizeInGB - starting converter.." -ForegroundColor Cyan
Write-Host
Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
foreach($video in $videos)
{
$video = $video.Replace("`"", "")
$inputFile = $videoPath + "\" + $video
# Get and check File info for codec and resolution, if it's already HEVC: - JSON query: (['media']['track'][1]['Format'])
$fileDetails = cmd /c $fileTester $inputFile --Output=JSON | ConvertFrom-Json
$codec = $fileDetails.media.track[1].Format
$reconvert = $false
$resolution_width = $fileDetails.media.track[1].Width
$resolution_height = $fileDetails.media.track[1].Height
if($resolution_width -gt '3840') # max resolution for x264 = 4096
{
if ($forceReconvertAllToMatchVRresolution)
{
$reconvert = $true
}
$new_resolution_width = '3840'
$new_resolution_height = $resolution_height / $resolution_width * $new_resolution_width
if ($new_resolution_height -gt '2048')
{
$new_resolution_width = $new_resolution_width / $new_resolution_height * '2048'
$new_resolution_height = '2048'
}
}
# If not already x264 or reconvert, converting video using NVEncC64:
if(($codec -eq "HEVC") -or ($reconvert))
{
# Configure new file naming:
if ($video -match "265")
{
$outputFile = $videoPath + "\" + $video.Replace("265", "264")
} else {
$outputFile = $videoPath + "\" + $video.Insert(($video.Length - 4), '-x264')
}
Write-Host "Analyzing video ($videoID of $count), starting convertion of number: $($convertedVideos + 1) please wait.." -ForegroundColor Magenta
Write-Host "$video `nto:`n$outputFile" -ForegroundColor White
Write-Host
# If the Subtitles should not be copied, delete the "--sub-copy 1,2" argument.
$arguments = "--input `"$inputFile`" --codec AVC --audio-copy 1,2,3,4 --sub-copy 1,2,3,4 --profile high --output-res $($new_resolution_width)x$($new_resolution_height) --output `"$outputFile`""
if ($debug)
{
Write-Host "Starting conversion of next file with the following command:"
Write-Host "$NVEncoder $arguments" -ForegroundColor Green
}
Start-Process $NVEncoder -ArgumentList $arguments -WindowStyle Minimized
$processName = 'NVEncC64'
Start-Sleep -Seconds 1
# Sets to use 3 cores (always set to one less core that your CPU has)
# 2 Cores = 3, 3 Cores = 7, 4 cores = 15, 5 cores = 31, 6 cores = 63
# Code to calculate for your CPU:
# $noOfCores = Get-WmiObject Win32_Processor | Measure-Object NumberOfLogicalProcessors -Sum
# $noOfCores.Sum = $noOfCores.Sum - 1
# [math]::Pow(2,$($noOfCores).Sum) - 1
#
$process = Get-Process $processName; $process.ProcessorAffinity=7
Start-Sleep -Seconds 2
# Sets priorty to High
# Values: High, AboveNormal, Normal, BelowNormal, Low
$process = Get-Process -Id $process.Id
$process.PriorityClass = 'High'
# Waits for process to complete
$processID = (Get-Process $processName).id
Wait-Process -Id $processID
if(Test-Path -LiteralPath $outputFile)
# Specifies a path to be tested. Unlike Path, the value of the LiteralPath parameter is used exactly as it is typed.
#No characters are interpreted as wildcard characters.
{
Write-Host "CONVERSION DONE! FILE: `"$outputFile`" FOUND" -ForegroundColor Yellow
Start-Sleep -Seconds 4
# Check if File is valid; the duration of video must be the same! (['media']['track'][0]['Duration']):
$fileDetails_new = cmd /c $fileTester $outputFile --Output=JSON | ConvertFrom-Json
# This code gets the duration and splits it in two parts, only the part before the "." is needed:
$StreamSize_old,$notused = $($fileDetails.media.track[0].Duration).split('.')
$StreamSize_new,$notused = $($fileDetails_new.media.track[0].Duration).split('.')
Write-Host
Write-Host "Old Duration was: $StreamSize_old `nnew Duration is: $StreamSize_new" -ForegroundColor White
Write-Host
if ($StreamSize_new -eq $StreamSize_old)
{
# Delete old video File!
Write-Host "Conversion Successful! - Deleting old file.."
Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
Remove-Item -LiteralPath $inputFile
$convertedVideos = $convertedVideos + 1
$Logfile = "$PSScriptRoot\..\logs\$logFolderName\successfully_converted.log"
LogWrite "$outputFile"
} else
{
if (($StreamSize_new -eq $($StreamSize_old - 1)) -or ($($StreamSize_new - 1) -eq $StreamSize_old))
{
# Newly converted file does not match exactly the old duration. But diffrence its not more than 1 sec!
Write-Host "Conversion Done! - Streamsize is not exactly the same. But still OK - Ignoring!"
Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
Remove-Item -LiteralPath $inputFile
$convertedVideos = $convertedVideos + 1
$Logfile = "$PSScriptRoot\..\logs\$logFolderName\successfully_converted.log"
LogWrite "$outputFile"
} elseif (($StreamSize_new -ge $($StreamSize_old - 20)) -or ($($StreamSize_new - 20) -ge $StreamSize_old))
{
# New converted file has been converted but with up to max 20 seconds deviation!
Write-Host "Conversion Done! - But streamsize is not the same. - Please review!"
Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
$review = $true
$convertedVideos = $convertedVideos + 1
$Logfile = "$PSScriptRoot\..\logs\$logFolderName\review_needed.log"
LogWrite "$inputFile,$outputFile"
} else
{
if ($forceReviewAll)
{
# Mark probably corrupted file for review
Write-Host "Conversion Failed! - Marked for review! because it is desired."
Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
$review = $true
$convertedVideos = $convertedVideos + 1
$Logfile = "$PSScriptRoot\..\logs\$logFolderName\review_needed.log"
LogWrite "$inputFile,$outputFile"
} else
{
# Delete obviously corrupt File!
Write-Host "Conversion Failded! - Deleting new converted file.." -ForegroundColor Red
Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
Remove-Item -LiteralPath $outputFile
$failedVideos = $failedVideos + 1
$notConvertedVideos = $notConvertedVideos + 1
$Logfile = "$PSScriptRoot\..\logs\$logFolderName\error_during_conversion.log"
LogWrite "$inputFile,$StreamSize_new,$StreamSize_old,"
}
}
}
}
} else
{
# Alert if video doesn't need conversion:
Write-Host "Analyzing video ($videoID of $count) - skip" -ForegroundColor Magenta
Write-Host "$video is already in correct format!" -ForegroundColor Green
Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
# Increments not converted video counter:
$notConvertedVideos = $notConvertedVideos + 1
$Logfile = "$PSScriptRoot\..\logs\$logFolderName\skipped_files.log"
LogWrite "$inputFile"
}
# Increments video counter:
$videoID = $videoID + 1
$outputFile = "" # Resets the variable to nothing, that in case of an error the old file is not affected.
}
#############################################################################################################
# END - Main conversion process
#############################################################################################################
# Evaluation part of the conversion script #
#############################################################################################################
if ($review)
{
$reviewFiles = Get-content -LiteralPath "$PSScriptRoot\..\logs\$logFolderName\review_needed.log" | Measure-Object Line
$ReviewCount = $reviewFiles.Lines
Write-Host "There are $ReviewCount files to review.." -ForegroundColor Yellow
Read-Host -Prompt "Press Enter to start reviewing first file"
Write-Host
Write-Host "################################################################################################"
$review_count = 1
foreach($review_pair in Get-Content -LiteralPath "$PSScriptRoot\..\logs\$logFolderName\review_needed.log")
{
$oldFile,$newFile = $review_pair.split(',')
Write-Host "Playing $review_count converted file: $newFile"
Write-Host
# Starting VLC Player with the file to review
Start-Process $reviewPlayer -ArgumentList `"$newFile`"
Start-Sleep -Seconds 6
# Wait until player is closed.
$processID = (Get-Process "vlc").id
Wait-Process -Id $processID
$msg = 'Do you want to keep the newly converted file and delete the old? (N for deleting NEW-file) [Y/N]'
do {
$response = Read-Host -Prompt $msg
} until (($response -eq 'n') -or ($response -eq 'y'))
if ($response -eq 'y')
{
Write-Host "delete old file, keep newly converted.."
$to_delete = $oldFile
} else
{
Write-Host "delete newly converted, keep old file"
$to_delete = $newFile
$failedVideos = $failedVideos + 1
$convertedVideos = $convertedVideos - 1
}
Write-Host "DELETED: $to_delete" -ForegroundColor Red
Remove-Item -LiteralPath $to_delete
Write-Host "------------------------------------------------------------------------------------------------"
Start-Sleep -Seconds 2
}
}
Write-Host "Final calculations are in progress.."
$folderSizeInGB2 = "{0:N2} GB" -f ((Get-ChildItem $videoPath -Recurse | Measure-Object -Property Length -Sum -ErrorAction Stop).Sum / 1GB)
if($notConvertedVideos -eq 0)
{
Write-Host "Finished converted $convertedVideos out of $count videos." -ForegroundColor Green
} else
{
if($failedVideos -eq 0)
{
Write-Host "Finished converted $convertedVideos out of $count videos. - $notConvertedVideos where not converted because of already correct codec!" -ForegroundColor Green
} else
{
Write-Host "Finished converted $convertedVideos out of $count videos. - $notConvertedVideos where not converted because error or already correct codec!!" -ForegroundColor Green
Write-Host "$failedVideos have failed!" -ForegroundColor Red
}
}
Write-Host "Directory size before conversion: $folderSizeInGB"
Write-Host "Directory size after conversion: $folderSizeInGB2"
Read-Host -Prompt "Press Enter to exit"
#############################################################################################################
# END - conversion script

View File

@ -0,0 +1,332 @@
# Converts videos back to x264 for VR playback for given path:
# Converter: https://github.com/FFmpeg/FFmpeg
# Maximum VR Video Dimensions for Oculus Go are: 3840x2048 pixel!! Higher resolution ends with blackscreen!
# Maximum resolution for x264 codec is = 4096x4096 pixel!
#-----------------------------------------------------------------------
# Edit the $videoPath variable to point to your video-files folder:
$videoPath = 'Z:\__VR_SP_CONTENT\__TODO'
#-----------------------------------------------------------------------
$debug = $true
$forceReviewAll = $false # If set to $true all failed conversions are reviewed even those that are obviously corrupt.
$forceReconvertAllToMatchVRresolution = $true; # only x264 videos AND videos not bigger than 3840x2048 pixel are playable on the Oculus Go.
$ffmpegBin = "$PSScriptRoot\ffmpeg\ffmpeg.exe"
$fileTester = "$PSScriptRoot\..\mediainfo.exe"
$reviewPlayer = "C:\Program Files\VideoLAN\VLC\vlc.exe"
#############################################################################################################
# Testing and conversion preparations #
#############################################################################################################
if(!(Test-Path $ffmpegBin -PathType leaf))
{
Write-Host "ffmpeg.exe not found, please check path in `"$ffmpegBin`"." -ForegroundColor Yellow
Read-Host -Prompt "Press Enter to exit"
exit
}
# Get video list from provided path:
$videos = Get-ChildItem -LiteralPath $videoPath -Name -Recurse -Include ('*.mp4', '*.mkv') #('*.avi', '*.mp4', '*.mkv') - avi currently doesn't work.
# Instantiating used variables:
$videoID = 1
$convertedVideos = 0
$notConvertedVideos = 0
$failedVideos = 0
# Square brackets are used as wildcards in Powershell.
# To recognize this as normal text, the LogWite function uses the -LiteralPath parameter instead of the -Path parameter.
$logFolderName = $((Get-Date).tostring("yyyy-MM-dd") + ' - [run started at ' + (Get-Date).tostring("HH-mm") + ']')
$count = $videos.Count
if($videos.Count -lt 1)
{
Write-Host "No videos found in: $videoPath" -ForegroundColor Red
Read-Host -Prompt "Press Enter to exit"
exit
}
# Log write function:
Function LogWrite
{
Param ([string]$logstring)
Add-content -LiteralPath $Logfile -value $logstring
}
# Create new log directory:
New-Item -itemType Directory -Path $PSScriptRoot\..\logs\ -Name $logFolderName > $null
# Calculates the total size of the given directory in GB:
Write-Host "Inizialization in progress.."
$folderSizeInGB = "{0:N2} GB" -f ((Get-ChildItem $videoPath -Recurse | Measure-Object -Property Length -Sum -ErrorAction Stop).Sum / 1GB)
Clear-Host # Clears the upper message from the window
#############################################################################################################
# END - Testing and conversion preparations
#############################################################################################################
# Main conversion process #
#############################################################################################################
Write-Host "Found $count videos with a total size of $folderSizeInGB - starting converter.." -ForegroundColor Cyan
Write-Host
Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
foreach($video in $videos)
{
$video = $video.Replace("`"", "")
$inputFile = $videoPath + "\" + $video
# Get and check File info for codec and resolution, if it's already HEVC: - JSON query: (['media']['track'][1]['Format'])
$fileDetails = cmd /c $fileTester $inputFile --Output=JSON | ConvertFrom-Json
$codec = $fileDetails.media.track[1].Format
$reconvert = $false
$resolution_width = $fileDetails.media.track[1].Width
$resolution_height = $fileDetails.media.track[1].Height
if($resolution_width -gt '3840') # max resolution for x264 = 4096
{
if ($forceReconvertAllToMatchVRresolution)
{
$reconvert = $true
}
$new_resolution_width = '3840'
$new_resolution_height = $resolution_height / $resolution_width * $new_resolution_width
if ($new_resolution_height -gt '2048')
{
$new_resolution_width = $new_resolution_width / $new_resolution_height * '2048'
$new_resolution_height = '2048'
}
}
# If not already x264 or reconvert, converting video using ffmpeg:
if(($codec -eq "HEVC") -or ($reconvert))
{
# Configure new file naming:
if ($video -match "265")
{
$outputFile = $videoPath + "\" + $video.Replace("265", "264")
} else {
$outputFile = $videoPath + "\" + $video.Insert(($video.Length - 4), '-x264')
}
Write-Host "Analyzing video ($videoID of $count), starting convertion of number: $($convertedVideos + 1) please wait.." -ForegroundColor Magenta
Write-Host "$video `nto:`n$outputFile" -ForegroundColor White
Write-Host
$rescale = ""
if ($reconvert)
{
$rescale = "-s $($new_resolution_width)x$($new_resolution_height)"
}
# If the Subtitles should not be copied, delete the "--sub-copy 1,2" argument.
$arguments = "-i `"$inputFile`" -c:v libx264 -preset fast -crf 18 -c:a copy -map 0 -map_metadata 0 -movflags +faststart -pix_fmt yuv420p $rescale `"$outputFile`""
if ($debug)
{
Write-Host "Starting conversion of next file with the following command:"
Write-Host "$ffmpegBin $arguments" -ForegroundColor Green
}
Start-Process $ffmpegBin -ArgumentList $arguments -WindowStyle Minimized
$processName = 'ffmpeg'
Start-Sleep -Seconds 1
# Sets to use 3 cores (always set to one less core that your CPU has)
# 2 Cores = 3, 3 Cores = 7, 4 cores = 15, 5 cores = 31, 6 cores = 63
# Code to calculate for your CPU:
$noOfCores = Get-WmiObject Win32_Processor | Measure-Object NumberOfLogicalProcessors -Sum
$noOfCores.Sum = $noOfCores.Sum - 1
[Int]$processorAffinity = [math]::Pow(2,$($noOfCores).Sum) - 1
#
$process = Get-Process $processName; $process.ProcessorAffinity=$processorAffinity
#Start-Sleep -Seconds 2
# Sets priorty to High
# Values: High, AboveNormal, Normal, BelowNormal, Low
$process = Get-Process -Id $process.Id
$process.PriorityClass = 'High'
# Waits for process to complete
$processID = (Get-Process $processName).id
Wait-Process -Id $processID
if(Test-Path -LiteralPath $outputFile)
# Specifies a path to be tested. Unlike Path, the value of the LiteralPath parameter is used exactly as it is typed.
#No characters are interpreted as wildcard characters.
{
Write-Host "CONVERSION DONE! FILE: `"$outputFile`" FOUND" -ForegroundColor Yellow
Start-Sleep -Seconds 4
# Check if File is valid; the duration of video must be the same! (['media']['track'][0]['Duration']):
$fileDetails_new = cmd /c $fileTester $outputFile --Output=JSON | ConvertFrom-Json
# This code gets the duration and splits it in two parts, only the part before the "." is needed:
$StreamSize_old,$notused = $($fileDetails.media.track[0].Duration).split('.')
$StreamSize_new,$notused = $($fileDetails_new.media.track[0].Duration).split('.')
Write-Host
Write-Host "Old Duration was: $StreamSize_old `nnew Duration is: $StreamSize_new" -ForegroundColor White
Write-Host
if ($StreamSize_new -eq $StreamSize_old)
{
# Delete old video File!
Write-Host "Conversion Successful! - Deleting old file.."
Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
Remove-Item -LiteralPath $inputFile
$convertedVideos = $convertedVideos + 1
$Logfile = "$PSScriptRoot\..\logs\$logFolderName\successfully_converted.log"
LogWrite "$outputFile"
} else
{
if (($StreamSize_new -eq $($StreamSize_old - 1)) -or ($($StreamSize_new - 1) -eq $StreamSize_old))
{
# Newly converted file does not match exactly the old duration. But diffrence its not more than 1 sec!
Write-Host "Conversion Done! - Streamsize is not exactly the same. But still OK - Ignoring!"
Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
Remove-Item -LiteralPath $inputFile
$convertedVideos = $convertedVideos + 1
$Logfile = "$PSScriptRoot\..\logs\$logFolderName\successfully_converted.log"
LogWrite "$outputFile"
} elseif (($StreamSize_new -ge $($StreamSize_old - 20)) -or ($($StreamSize_new - 20) -ge $StreamSize_old))
{
# New converted file has been converted but with up to max 20 seconds deviation!
Write-Host "Conversion Done! - But streamsize is not the same. - Please review!"
Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
$review = $true
$convertedVideos = $convertedVideos + 1
$Logfile = "$PSScriptRoot\..\logs\$logFolderName\review_needed.log"
LogWrite "$inputFile,$outputFile"
} else
{
if ($forceReviewAll)
{
# Mark probably corrupted file for review
Write-Host "Conversion Failed! - Marked for review! because it is desired."
Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
$review = $true
$convertedVideos = $convertedVideos + 1
$Logfile = "$PSScriptRoot\..\logs\$logFolderName\review_needed.log"
LogWrite "$inputFile,$outputFile"
} else
{
# Delete obviously corrupt File!
Write-Host "Conversion Failded! - Deleting new converted file.." -ForegroundColor Red
Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
Remove-Item -LiteralPath $outputFile
$failedVideos = $failedVideos + 1
$notConvertedVideos = $notConvertedVideos + 1
$Logfile = "$PSScriptRoot\..\logs\$logFolderName\error_during_conversion.log"
LogWrite "$inputFile,$StreamSize_new,$StreamSize_old,"
}
}
}
}
} else
{
# Alert if video doesn't need conversion:
Write-Host "Analyzing video ($videoID of $count) - skip" -ForegroundColor Magenta
Write-Host "$video is already in correct format!" -ForegroundColor Green
Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
# Increments not converted video counter:
$notConvertedVideos = $notConvertedVideos + 1
$Logfile = "$PSScriptRoot\..\logs\$logFolderName\skipped_files.log"
LogWrite "$inputFile"
}
# Increments video counter:
$videoID = $videoID + 1
$outputFile = "" # Resets the variable to nothing, that in case of an error the old file is not affected.
}
#############################################################################################################
# END - Main conversion process
#############################################################################################################
# Evaluation part of the conversion script #
#############################################################################################################
if ($review)
{
$reviewFiles = Get-content -LiteralPath "$PSScriptRoot\..\logs\$logFolderName\review_needed.log" | Measure-Object Line
$ReviewCount = $reviewFiles.Lines
Write-Host "There are $ReviewCount files to review.." -ForegroundColor Yellow
Read-Host -Prompt "Press Enter to start reviewing first file"
Write-Host
Write-Host "################################################################################################"
$review_count = 1
foreach($review_pair in Get-Content -LiteralPath "$PSScriptRoot\..\logs\$logFolderName\review_needed.log")
{
$oldFile,$newFile = $review_pair.split(',')
Write-Host "Playing $review_count converted file: $newFile"
Write-Host
# Starting VLC Player with the file to review
Start-Process $reviewPlayer -ArgumentList `"$newFile`"
Start-Sleep -Seconds 6
# Wait until player is closed.
$processID = (Get-Process "vlc").id
Wait-Process -Id $processID
$msg = 'Do you want to keep the newly converted file and delete the old? (N for deleting NEW-file) [Y/N]'
do {
$response = Read-Host -Prompt $msg
} until (($response -eq 'n') -or ($response -eq 'y'))
if ($response -eq 'y')
{
Write-Host "delete old file, keep newly converted.."
$to_delete = $oldFile
} else
{
Write-Host "delete newly converted, keep old file"
$to_delete = $newFile
$failedVideos = $failedVideos + 1
$convertedVideos = $convertedVideos - 1
}
Write-Host "DELETED: $to_delete" -ForegroundColor Red
Remove-Item -LiteralPath $to_delete
Write-Host "------------------------------------------------------------------------------------------------"
Start-Sleep -Seconds 2
}
}
Write-Host "Final calculations are in progress.."
$folderSizeInGB2 = "{0:N2} GB" -f ((Get-ChildItem $videoPath -Recurse | Measure-Object -Property Length -Sum -ErrorAction Stop).Sum / 1GB)
if($notConvertedVideos -eq 0)
{
Write-Host "Finished converted $convertedVideos out of $count videos." -ForegroundColor Green
} else
{
if($failedVideos -eq 0)
{
Write-Host "Finished converted $convertedVideos out of $count videos. - $notConvertedVideos where not converted because of already correct codec!" -ForegroundColor Green
} else
{
Write-Host "Finished converted $convertedVideos out of $count videos. - $notConvertedVideos where not converted because error or already correct codec!!" -ForegroundColor Green
Write-Host "$failedVideos have failed!" -ForegroundColor Red
}
}
Write-Host "Directory size before conversion: $folderSizeInGB"
Write-Host "Directory size after conversion: $folderSizeInGB2"
Read-Host -Prompt "Press Enter to exit"
#############################################################################################################
# END - conversion script

View File

@ -0,0 +1,115 @@
# Converts videos to HEVC for given path:
# https://github.com/rigaya/NVEnc/releases
#-----------------------------------------------------------------------
# Edit the $videoPath variable to point to your video-files folder:
$videoPath = 'Z:\__VR_SP_CONTENT\_data'
#-----------------------------------------------------------------------
$fileTester = "$PSScriptRoot\..\mediainfo.exe"
#############################################################################################################
# Testing and conversion preparations #
#############################################################################################################
# Get video list from provided path:
$videos = Get-ChildItem -LiteralPath $videoPath -Name -Recurse -Include ('*.mp4', '*.mkv') #('*.avi', '*.mp4', '*.mkv') - avi currently doesn't work.
# Instantiating used variables:
$videoID = 1
$convertedVideos = 0
$notConvertedVideos = 0
# Square brackets are used as wildcards in Powershell.
# To recognize this as normal text, the LogWite function uses the -LiteralPath parameter instead of the -Path parameter.
$logFolderName = $((Get-Date).tostring("yyyy-MM-dd") + ' - [preList - convert HEVC to x264 created at ' + (Get-Date).tostring("HH-mm") + ']')
$count = $videos.Count
if($videos.Count -lt 1)
{
Write-Host "No videos found in: $videoPath" -ForegroundColor Red
Read-Host -Prompt "Press Enter to exit"
exit
}
# Log write function:
Function LogWrite
{
Param ([string]$logstring)
Add-content -LiteralPath $Logfile -value $logstring
}
# Create new log directory:
New-Item -itemType Directory -Path $PSScriptRoot\ -Name $logFolderName > $null
Clear-Host # Clears the upper message from the window
#############################################################################################################
# END - Testing and conversion preparations
#############################################################################################################
# Main conversion process #
#############################################################################################################
Write-Host "Found $count videos with a total size of $folderSizeInGB - starting generation of list.." -ForegroundColor Cyan
Write-Host
Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
foreach($video in $videos)
{
$video = $video.Replace("`"", "")
$inputFile = $videoPath + "\" + $video
# Pre-file-check if "HEVC" exist in filename skip filechecking:
if ($video -match "HEVC")
{
$codec = "HEVC"
} else {
# Get and check File info for codec, if it's already HEVC: - JSON query: (['media']['track'][1]['Format'])
$fileDetails = cmd /c $fileTester $inputFile --Output=JSON | ConvertFrom-Json
$codec = $fileDetails.media.track[1].Format
}
# If not already HEVC, convert video using NVEncC64:
if($codec -eq "HEVC")
{
# Configure new file naming:
if ($video -match "265")
{
$outputFile = $videoPath + "\" + $video.Replace("265", "264")
} else {
$outputFile = $videoPath + "\" + $video.Insert(($video.Length - 4), '-x264')
}
Write-Host "Analyzing video ($videoID of $count), needs conversion - number: $($convertedVideos + 1)" -ForegroundColor Magenta
Write-Host "$video `nto:`n$outputFile" -ForegroundColor White
Write-Host
Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
$convertedVideos = $convertedVideos + 1
$Logfile = "$PSScriptRoot\$logFolderName\needs_conversion.log"
LogWrite "$outputFile"
} else
{
# Alert if video doesn't need conversion:
Write-Host "Analyzing video ($videoID of $count) - skip" -ForegroundColor Magenta
Write-Host "$video is already in correct format!" -ForegroundColor Green
Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
# Increments not converted video counter:
$notConvertedVideos = $notConvertedVideos + 1
$Logfile = "$PSScriptRoot\$logFolderName\already_correct_codec.log"
LogWrite "$inputFile"
}
# Increments video counter:
$videoID = $videoID + 1
$outputFile = "" # Resets the variable to nothing, that in case of an error the old file is not affected.
}
#############################################################################################################
Read-Host -Prompt "Press Enter to exit"
#############################################################################################################
# END - conversion script

4
_extras/ffmpeg/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore

View File

@ -0,0 +1,68 @@
# Review converted videos:
#-----------------------------------------------------------------------
# Edit the $logFolderName variable to point to your desired logs folder:
#$logFolderName = "24-06-2020 - [run started at 17-31]"
$logFolderName = "2020-10-03 - [run started at 11-29]"
#-----------------------------------------------------------------------
$reviewPlayer = "C:\Program Files\VideoLAN\VLC\vlc.exe"
#############################################################################################################
# Evaluation part of the conversion script #
#############################################################################################################
if(!(Test-Path $reviewPlayer -PathType leaf))
{
Write-Host "vlc.exe not found, is the player installed? please check path in `"$reviewPlayer`"." -ForegroundColor Yellow
Read-Host -Prompt "Press Enter to exit"
exit
}
$reviewFiles = Get-content -LiteralPath "$PSScriptRoot\..\logs\$logFolderName\review_needed.log" | Measure-Object Line
$ReviewCount = $reviewFiles.Lines
Write-Host "There are $ReviewCount files to review.." -ForegroundColor Yellow
Write-Host
$review_count = 1
foreach($review_pair in Get-Content -LiteralPath "$PSScriptRoot\..\logs\$logFolderName\review_needed.log")
{
$oldFile,$newFile = $review_pair.split(',')
Write-Host "Playing $review_count converted file: $newFile"
Write-Host
# Starting VLC Player with the file to review
Start-Process $reviewPlayer -ArgumentList `"$newFile`"
Start-Sleep -Seconds 6
# Wait until player is closed.
$processID = (Get-Process "vlc").id
Wait-Process -Id $processID
$msg = 'Do you want to keep the newly converted file and delete the old? (N for deleting NEW-file) [Y/N]'
do {
$response = Read-Host -Prompt $msg
} until (($response -eq 'n') -or ($response -eq 'y'))
if ($response -eq 'y')
{
Write-Host "delete old file, keep newly converted.."
$to_delete = $oldFile
} else
{
Write-Host "delete newly converted, keep old file"
$to_delete = $newFile
$failedVideos = $failedVideos + 1
$convertedVideos = $convertedVideos - 1
}
Write-Host "DELETED: $to_delete" -ForegroundColor Red
Remove-Item -LiteralPath $to_delete
Write-Host "------------------------------------------------------------------------------------------------"
Start-Sleep -Seconds 2
}
Read-Host -Prompt "Press Enter to exit"
#############################################################################################################
# END - conversion script

View File

@ -4,12 +4,13 @@
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Edit the $videoPath variable to point to your video-files folder: # Edit the $videoPath variable to point to your video-files folder:
$videoPath = 'M:\1_movies\_main.movies\' #$videoPath = 'M:\1_movies\_main.movies'
#$videoPath = 'M:\2_serien\_main.series\' $videoPath = 'M:\2_serien\_main.series'
#$videoPath = 'M:\3_dokus'
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# HEVC profiles: main, main10, main444 # HEVC profiles: main, main10, main444
$profile = 'main10' $hevc_profile = 'main10'
$forceReviewAll = $false # If set to $true all failed conversions are reviewed even those that are obviously corrupt. $forceReviewAll = $false # If set to $true all failed conversions are reviewed even those that are obviously corrupt.
$NVEncoder = "$PSScriptRoot\encoder\NVEncC64.exe" $NVEncoder = "$PSScriptRoot\encoder\NVEncC64.exe"
@ -19,11 +20,10 @@ $reviewPlayer = "C:\Program Files\VideoLAN\VLC\vlc.exe"
############################################################################################################# #############################################################################################################
# Testing and conversion preparations # # Testing and conversion preparations #
############################################################################################################# #############################################################################################################
if(!(Test-Path $NVEncoder -PathType leaf)) if (!(Test-Path $NVEncoder -PathType leaf)) {
{ Write-Host "NVEncC64.exe not found, please check path in `"$NVEncoder`"." -ForegroundColor Yellow
Write-Host "NVEncC64.exe not found, please check path in `"$NVEncoder`"." -ForegroundColor Yellow
Read-Host -Prompt "Press Enter to exit" Read-Host -Prompt "Press Enter to exit"
exit exit
} }
# Get video list from provided path: # Get video list from provided path:
@ -36,20 +36,18 @@ $notConvertedVideos = 0
$failedVideos = 0 $failedVideos = 0
# Square brackets are used as wildcards in Powershell. # Square brackets are used as wildcards in Powershell.
# To recognize this as normal text, the LogWite function uses the -LiteralPath parameter instead of the -Path parameter. # To recognize this as normal text, the LogWite function uses the -LiteralPath parameter instead of the -Path parameter.
$logFolderName = $((Get-Date).tostring("dd-MM-yyyy") + ' - [run started at ' + (Get-Date).tostring("HH-mm") + ']') $logFolderName = $((Get-Date).tostring("yyyy-MM-dd") + ' - [run started at ' + (Get-Date).tostring("HH-mm") + ']')
$count = $videos.Count $count = $videos.Count
if($videos.Count -lt 1) if ($videos.Count -lt 1) {
{ Write-Host "No videos found in: $videoPath" -ForegroundColor Red
Write-Host "No videos found in: $videoPath" -ForegroundColor Red Read-Host -Prompt "Press Enter to exit"
Read-Host -Prompt "Press Enter to exit"
exit exit
} }
# Log write function: # Log write function:
Function LogWrite Function LogWrite {
{ Param ([string]$logstring)
Param ([string]$logstring) Add-content -LiteralPath $Logfile -value $logstring
Add-content -LiteralPath $Logfile -value $logstring
} }
# Create new log directory: # Create new log directory:
New-Item -itemType Directory -Path $PSScriptRoot\logs\ -Name $logFolderName > $null New-Item -itemType Directory -Path $PSScriptRoot\logs\ -Name $logFolderName > $null
@ -70,44 +68,41 @@ Write-Host
Write-Host Write-Host
Write-Host "------------------------------------------------------------------------------------------------" Write-Host "------------------------------------------------------------------------------------------------"
foreach($video in $videos) foreach ($video in $videos) {
{
# Check filename for '-HVEC' string and skip filetester if true to make it run faster with lots of files already converted $video = $video.Replace("`"", "")
if(! $video -match "-HVEC") $inputFile = $videoPath + "\" + $video
{
$video = $video.Replace("`"", "") # Pre-file-check if "HEVC" exist in filename skip filechecking:
$inputFile = $videoPath + $video if ($video -match "HEVC") {
$codec = "HEVC"
}
else {
# Get and check File info for codec, if it's already HEVC: - JSON query: (['media']['track'][1]['Format']) # Get and check File info for codec, if it's already HEVC: - JSON query: (['media']['track'][1]['Format'])
$fileDetails = cmd /c $fileTester $inputFile --Output=JSON | ConvertFrom-Json $fileDetails = cmd /c $fileTester $inputFile --Output=JSON | ConvertFrom-Json
$codec = $fileDetails.media.track[1].Format $codec = $fileDetails.media.track[1].Format
#echo $codec
} else {}
$codec = 'HVEC'
} }
# If not already HEVC, convert video using NVEncC64: # If not already HEVC, convert video using NVEncC64:
if($codec -ne "HEVC") if ($codec -ne "HEVC") {
{
# Configure new file naming: # Configure new file naming:
if ($video -match "264") if ($video -match "264") {
{ $outputFile = $videoPath + "\" + $video.Replace("264", "265")
$outputFile = $videoPath + $video.Replace("264", "265") }
} else { else {
$outputFile = $videoPath + $video.Insert(($video.Length - 4), '-HEVC') $outputFile = $videoPath + "\" + $video.Insert(($video.Length - 4), '-HEVC')
} }
Write-Host "Analyzing video ($videoID of $count), starting convertion of number: $($convertedVideos + 1) please wait.." -ForegroundColor Magenta Write-Host "Analyzing video ($videoID of $count), starting convertion of number: $($convertedVideos + 1) please wait.." -ForegroundColor Magenta
Write-Host "$video `nto:`n$outputFile" -ForegroundColor White Write-Host "$video `nto:`n$outputFile" -ForegroundColor White
Write-Host Write-Host
# If the Subtitles should not be copied, delete the "--sub-copy 1,2" argument. # If the Subtitles should not be copied, delete the "--sub-copy 1,2" argument.
$arguments = "--input `"$inputFile`" --codec hevc --audio-copy 1,2,3,4,5,6 --sub-copy 1,2,3,4,5,6 --profile $profile --output `"$outputFile`"" $arguments = "--input `"$inputFile`" --codec hevc --audio-copy 1,2,3,4 --sub-copy 1,2,3,4 --profile $hevc_profile --output `"$outputFile`""
Start-Process $NVEncoder -ArgumentList $arguments -WindowStyle Minimized Start-Process $NVEncoder -ArgumentList $arguments -WindowStyle Minimized
$processName = 'NVEncC64' $processName = 'NVEncC64'
Start-Sleep -Seconds 8 Start-Sleep -Seconds 1
# Sets to use 3 cores (always set to one less core that your CPU has) # Sets to use 3 cores (always set to one less core that your CPU has)
# 2 Cores = 3, 3 Cores = 7, 4 cores = 15, 5 cores = 31, 6 cores = 63 # 2 Cores = 3, 3 Cores = 7, 4 cores = 15, 5 cores = 31, 6 cores = 63
# Code to calculate for your CPU: # Code to calculate for your CPU:
@ -115,8 +110,8 @@ foreach($video in $videos)
# $noOfCores.Sum = $noOfCores.Sum - 1 # $noOfCores.Sum = $noOfCores.Sum - 1
# [math]::Pow(2,$($noOfCores).Sum) - 1 # [math]::Pow(2,$($noOfCores).Sum) - 1
# #
$process = Get-Process $processName; $process.ProcessorAffinity=7 $process = Get-Process $processName; $process.ProcessorAffinity = 7
Start-Sleep -Seconds 8 Start-Sleep -Seconds 2
# Sets priorty to High # Sets priorty to High
# Values: High, AboveNormal, Normal, BelowNormal, Low # Values: High, AboveNormal, Normal, BelowNormal, Low
$process = Get-Process -Id $process.Id $process = Get-Process -Id $process.Id
@ -127,10 +122,9 @@ foreach($video in $videos)
Wait-Process -Id $processID Wait-Process -Id $processID
if(Test-Path -LiteralPath $outputFile) if (Test-Path -LiteralPath $outputFile)
# Specifies a path to be tested. Unlike Path, the value of the LiteralPath parameter is used exactly as it is typed. { # Specifies a path to be tested. Unlike Path, the value of the LiteralPath parameter is used exactly as it is typed.
#No characters are interpreted as wildcard characters. #No characters are interpreted as wildcard characters.
{
Write-Host "CONVERSION DONE! FILE: `"$outputFile`" FOUND" -ForegroundColor Yellow Write-Host "CONVERSION DONE! FILE: `"$outputFile`" FOUND" -ForegroundColor Yellow
Start-Sleep -Seconds 4 Start-Sleep -Seconds 4
@ -138,15 +132,14 @@ foreach($video in $videos)
$fileDetails_new = cmd /c $fileTester $outputFile --Output=JSON | ConvertFrom-Json $fileDetails_new = cmd /c $fileTester $outputFile --Output=JSON | ConvertFrom-Json
# This code gets the duration and splits it in two parts, only the part before the "." is needed: # This code gets the duration and splits it in two parts, only the part before the "." is needed:
$StreamSize_old,$notused = $($fileDetails.media.track[0].Duration).split('.') $StreamSize_old, $notused = $($fileDetails.media.track[0].Duration).split('.')
$StreamSize_new,$notused = $($fileDetails_new.media.track[0].Duration).split('.') $StreamSize_new, $notused = $($fileDetails_new.media.track[0].Duration).split('.')
Write-Host Write-Host
Write-Host "Old Duration was: $StreamSize_old `nnew Duration is: $StreamSize_new" -ForegroundColor White Write-Host "Old Duration was: $StreamSize_old `nnew Duration is: $StreamSize_new" -ForegroundColor White
Write-Host Write-Host
if ($StreamSize_new -eq $StreamSize_old) if ($StreamSize_new -eq $StreamSize_old) {
{
# Delete old video File! # Delete old video File!
Write-Host "Conversion Successful! - Deleting old file.." Write-Host "Conversion Successful! - Deleting old file.."
Write-Host Write-Host
@ -155,22 +148,33 @@ foreach($video in $videos)
$convertedVideos = $convertedVideos + 1 $convertedVideos = $convertedVideos + 1
$Logfile = "$PSScriptRoot\logs\$logFolderName\successfully_converted.log" $Logfile = "$PSScriptRoot\logs\$logFolderName\successfully_converted.log"
LogWrite "$outputFile" LogWrite "$outputFile"
} else }
{ else {
if (($StreamSize_new -eq $($StreamSize_old - 1)) -or ($($StreamSize_new - 1) -eq $StreamSize_old)) if (($StreamSize_new -eq $($StreamSize_old - 1)) -or ($($StreamSize_new - 1) -eq $StreamSize_old)) {
{ # Newly converted file does not match exactly the old duration. But diffrence its not more than 1 sec!
# Newly converted file does not match exactly the old duration! Write-Host "Conversion Done! - Streamsize is not exactly the same. But still OK - Ignoring!"
Write-Host "Conversion Done! - But streamsize is not exactly the same. - Please review!" Write-Host
Write-Host "------------------------------------------------------------------------------------------------"
Remove-Item -LiteralPath $inputFile
$convertedVideos = $convertedVideos + 1
$Logfile = "$PSScriptRoot\logs\$logFolderName\successfully_converted.log"
LogWrite "$outputFile"
}
elseif (($StreamSize_new -ge $($StreamSize_old - 20)) -or ($($StreamSize_new - 20) -ge $StreamSize_old)) {
# New converted file has been converted but with up to max 20 seconds deviation!
Write-Host "Conversion Done! - But streamsize is not the same. - Please review!"
Write-Host Write-Host
Write-Host "------------------------------------------------------------------------------------------------" Write-Host "------------------------------------------------------------------------------------------------"
$review = $true $review = $true
$convertedVideos = $convertedVideos + 1 $convertedVideos = $convertedVideos + 1
$Logfile = "$PSScriptRoot\logs\$logFolderName\review_needed.log" $Logfile = "$PSScriptRoot\logs\$logFolderName\review_needed.log"
LogWrite "$inputFile,$outputFile" LogWrite "$inputFile,$outputFile"
} else
{
if ($forceReviewAll) }
{ else {
if ($forceReviewAll) {
# Mark probably corrupted file for review # Mark probably corrupted file for review
Write-Host "Conversion Failed! - Marked for review! because it is desired." Write-Host "Conversion Failed! - Marked for review! because it is desired."
Write-Host Write-Host
@ -179,8 +183,8 @@ foreach($video in $videos)
$convertedVideos = $convertedVideos + 1 $convertedVideos = $convertedVideos + 1
$Logfile = "$PSScriptRoot\logs\$logFolderName\review_needed.log" $Logfile = "$PSScriptRoot\logs\$logFolderName\review_needed.log"
LogWrite "$inputFile,$outputFile" LogWrite "$inputFile,$outputFile"
} else }
{ else {
# Delete obviously corrupt File! # Delete obviously corrupt File!
Write-Host "Conversion Failded! - Deleting new converted file.." -ForegroundColor Red Write-Host "Conversion Failded! - Deleting new converted file.." -ForegroundColor Red
Write-Host Write-Host
@ -194,8 +198,8 @@ foreach($video in $videos)
} }
} }
} }
} else }
{ else {
# Alert if video doesn't need conversion: # Alert if video doesn't need conversion:
Write-Host "Analyzing video ($videoID of $count) - skip" -ForegroundColor Magenta Write-Host "Analyzing video ($videoID of $count) - skip" -ForegroundColor Magenta
Write-Host "$video is already in correct format!" -ForegroundColor Green Write-Host "$video is already in correct format!" -ForegroundColor Green
@ -218,15 +222,18 @@ foreach($video in $videos)
############################################################################################################# #############################################################################################################
# Evaluation part of the conversion script # # Evaluation part of the conversion script #
############################################################################################################# #############################################################################################################
if ($review) if ($review) {
{ $reviewFiles = Get-content -LiteralPath "$PSScriptRoot\logs\$logFolderName\review_needed.log" | Measure-Object Line
Write-Host "There are some files to review.. Starting reviewing first file." $ReviewCount = $reviewFiles.Lines
Write-Host "There are $ReviewCount files to review.." -ForegroundColor Yellow
Read-Host -Prompt "Press Enter to start reviewing first file"
Write-Host Write-Host
Write-Host "################################################################################################"
$review_count = 1 $review_count = 1
foreach($review_pair in Get-Content -LiteralPath "$PSScriptRoot\logs\$logFolderName\review_needed.log") foreach ($review_pair in Get-Content -LiteralPath "$PSScriptRoot\logs\$logFolderName\review_needed.log") {
{ $oldFile, $newFile = $review_pair.split(',')
$oldFile,$newFile = $review_pair.split(',')
Write-Host "Playing $review_count converted file: $newFile" Write-Host "Playing $review_count converted file: $newFile"
Write-Host Write-Host
@ -243,19 +250,18 @@ if ($review)
$response = Read-Host -Prompt $msg $response = Read-Host -Prompt $msg
} until (($response -eq 'n') -or ($response -eq 'y')) } until (($response -eq 'n') -or ($response -eq 'y'))
if ($response -eq 'y') if ($response -eq 'y') {
{
Write-Host "delete old file, keep newly converted.." Write-Host "delete old file, keep newly converted.."
$to_delete = $oldFile $to_delete = $oldFile
} else }
{ else {
Write-Host "delete newly converted, keep old file" Write-Host "delete newly converted, keep old file"
$to_delete = $newFile $to_delete = $newFile
$failedVideos = $failedVideos + 1 $failedVideos = $failedVideos + 1
$convertedVideos = $convertedVideos - 1 $convertedVideos = $convertedVideos - 1
} }
Write-Host "DELETED: $to_delete" -ForegroundColor Red Write-Host "DELETED: $to_delete" -ForegroundColor Red
#Remove-Item -LiteralPath $to_delete Remove-Item -LiteralPath $to_delete
Write-Host "------------------------------------------------------------------------------------------------" Write-Host "------------------------------------------------------------------------------------------------"
Start-Sleep -Seconds 2 Start-Sleep -Seconds 2
} }
@ -263,16 +269,14 @@ if ($review)
Write-Host "Final calculations are in progress.." Write-Host "Final calculations are in progress.."
$folderSizeInGB2 = "{0:N2} GB" -f ((Get-ChildItem $videoPath -Recurse | Measure-Object -Property Length -Sum -ErrorAction Stop).Sum / 1GB) $folderSizeInGB2 = "{0:N2} GB" -f ((Get-ChildItem $videoPath -Recurse | Measure-Object -Property Length -Sum -ErrorAction Stop).Sum / 1GB)
if($notConvertedVideos -eq 0) if ($notConvertedVideos -eq 0) {
{
Write-Host "Finished converted $convertedVideos out of $count videos." -ForegroundColor Green Write-Host "Finished converted $convertedVideos out of $count videos." -ForegroundColor Green
} else }
{ else {
if($failedVideos -eq 0) if ($failedVideos -eq 0) {
{
Write-Host "Finished converted $convertedVideos out of $count videos. - $notConvertedVideos where not converted because of already correct codec!" -ForegroundColor Green Write-Host "Finished converted $convertedVideos out of $count videos. - $notConvertedVideos where not converted because of already correct codec!" -ForegroundColor Green
} else }
{ else {
Write-Host "Finished converted $convertedVideos out of $count videos. - $notConvertedVideos where not converted because error or already correct codec!!" -ForegroundColor Green Write-Host "Finished converted $convertedVideos out of $count videos. - $notConvertedVideos where not converted because error or already correct codec!!" -ForegroundColor Green
Write-Host "$failedVideos have failed!" -ForegroundColor Red Write-Host "$failedVideos have failed!" -ForegroundColor Red

Binary file not shown.

Binary file not shown.

BIN
encoder/avfilter-8.dll Normal file

Binary file not shown.

Binary file not shown.

BIN
encoder/avformat-59.dll Normal file

Binary file not shown.

Binary file not shown.

BIN
encoder/avutil-57.dll Normal file

Binary file not shown.

Binary file not shown.

BIN
encoder/libvmaf.dll Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
encoder/swresample-4.dll Normal file

Binary file not shown.