diff --git a/README.md b/README.md index 007201b..6cbf8e7 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ - -# Automated HEVC-Video-Converter 1.0 +# Automated HEVC-Video-Converter A PowerShell script for converting video to the HEVC video format using GPU hardware acceleration with NVEnc for Windows. @@ -20,17 +19,15 @@ _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)) - Latest nvidia graphics drivers - ## 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) 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. -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. - ## Script Usage 1. Clone this repository on your computer @@ -39,7 +36,6 @@ If not, the failed conversion file is deleted and logged. 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. +## Extra Content (\_extras folder) -## 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. \ No newline at end of file +- **manually_review_videos.ps1** - Redoes the review process using the "review_needed.log" -> before useing set the "$logFolderName" variable in file. diff --git a/convert_Videos.ps1 b/convert_Videos.ps1 index 9a8dcf3..27cc5cd 100644 --- a/convert_Videos.ps1 +++ b/convert_Videos.ps1 @@ -10,7 +10,7 @@ $videoPath = 'M:\2_serien\_main.series' #----------------------------------------------------------------------- # 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. $NVEncoder = "$PSScriptRoot\encoder\NVEncC64.exe" @@ -20,11 +20,10 @@ $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 +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 + exit } # Get video list from provided path: @@ -40,17 +39,15 @@ $failedVideos = 0 $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" +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 +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 @@ -71,30 +68,28 @@ Write-Host Write-Host Write-Host "------------------------------------------------------------------------------------------------" -foreach($video in $videos) -{ +foreach ($video in $videos) { - $video = $video.Replace("`"", "") - $inputFile = $videoPath + "\" + $video + $video = $video.Replace("`"", "") + $inputFile = $videoPath + "\" + $video # Pre-file-check if "HEVC" exist in filename skip filechecking: - if ($video -match "HEVC") - { + if ($video -match "HEVC") { $codec = "HEVC" - } else { + } + 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 -ne "HEVC") - { + if ($codec -ne "HEVC") { # Configure new file naming: - if ($video -match "264") - { + if ($video -match "264") { $outputFile = $videoPath + "\" + $video.Replace("264", "265") - } else { + } + else { $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 @@ -102,7 +97,7 @@ foreach($video in $videos) Write-Host # 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 --sub-copy 1,2,3,4 --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 @@ -115,7 +110,7 @@ foreach($video in $videos) # $noOfCores.Sum = $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 2 # Sets priorty to High # Values: High, AboveNormal, Normal, BelowNormal, Low @@ -127,10 +122,9 @@ foreach($video in $videos) 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. - { + 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 @@ -138,15 +132,14 @@ foreach($video in $videos) $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('.') + $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) - { + if ($StreamSize_new -eq $StreamSize_old) { # Delete old video File! Write-Host "Conversion Successful! - Deleting old file.." Write-Host @@ -155,10 +148,9 @@ foreach($video in $videos) $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)) - { + } + 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 @@ -168,8 +160,8 @@ foreach($video in $videos) $Logfile = "$PSScriptRoot\logs\$logFolderName\successfully_converted.log" LogWrite "$outputFile" - } elseif (($StreamSize_new -ge $($StreamSize_old - 20)) -or ($($StreamSize_new - 20) -ge $StreamSize_old)) - { + } + 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 @@ -180,10 +172,9 @@ foreach($video in $videos) LogWrite "$inputFile,$outputFile" - } else - { - if ($forceReviewAll) - { + } + else { + if ($forceReviewAll) { # Mark probably corrupted file for review Write-Host "Conversion Failed! - Marked for review! because it is desired." Write-Host @@ -192,8 +183,8 @@ foreach($video in $videos) $convertedVideos = $convertedVideos + 1 $Logfile = "$PSScriptRoot\logs\$logFolderName\review_needed.log" LogWrite "$inputFile,$outputFile" - } else - { + } + else { # Delete obviously corrupt File! Write-Host "Conversion Failded! - Deleting new converted file.." -ForegroundColor Red Write-Host @@ -207,8 +198,8 @@ foreach($video in $videos) } } } - } else - { + } + 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 @@ -231,8 +222,7 @@ foreach($video in $videos) ############################################################################################################# # Evaluation part of the conversion script # ############################################################################################################# -if ($review) -{ +if ($review) { $reviewFiles = Get-content -LiteralPath "$PSScriptRoot\logs\$logFolderName\review_needed.log" | Measure-Object –Line $ReviewCount = $reviewFiles.Lines @@ -242,9 +232,8 @@ if ($review) Write-Host "################################################################################################" $review_count = 1 - foreach($review_pair in Get-Content -LiteralPath "$PSScriptRoot\logs\$logFolderName\review_needed.log") - { - $oldFile,$newFile = $review_pair.split(',') + 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 @@ -261,12 +250,11 @@ if ($review) $response = Read-Host -Prompt $msg } until (($response -eq 'n') -or ($response -eq 'y')) - if ($response -eq 'y') - { + if ($response -eq 'y') { Write-Host "delete old file, keep newly converted.." $to_delete = $oldFile - } else - { + } + else { Write-Host "delete newly converted, keep old file" $to_delete = $newFile $failedVideos = $failedVideos + 1 @@ -281,16 +269,14 @@ if ($review) 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) -{ +if ($notConvertedVideos -eq 0) { Write-Host "Finished converted $convertedVideos out of $count videos." -ForegroundColor Green -} else -{ - if($failedVideos -eq 0) - { +} +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 - { + } + 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 diff --git a/encoder/NVEncC64.exe b/encoder/NVEncC64.exe index 93a6588..e176788 100644 Binary files a/encoder/NVEncC64.exe and b/encoder/NVEncC64.exe differ diff --git a/encoder/avcodec-58.dll b/encoder/avcodec-59.dll similarity index 68% rename from encoder/avcodec-58.dll rename to encoder/avcodec-59.dll index 383e0d2..6d95b17 100644 Binary files a/encoder/avcodec-58.dll and b/encoder/avcodec-59.dll differ diff --git a/encoder/avfilter-7.dll b/encoder/avfilter-7.dll deleted file mode 100644 index cb3abab..0000000 Binary files a/encoder/avfilter-7.dll and /dev/null differ diff --git a/encoder/avfilter-8.dll b/encoder/avfilter-8.dll new file mode 100644 index 0000000..2d5e8bd Binary files /dev/null and b/encoder/avfilter-8.dll differ diff --git a/encoder/avformat-58.dll b/encoder/avformat-58.dll deleted file mode 100644 index 0fd3072..0000000 Binary files a/encoder/avformat-58.dll and /dev/null differ diff --git a/encoder/avformat-59.dll b/encoder/avformat-59.dll new file mode 100644 index 0000000..b569580 Binary files /dev/null and b/encoder/avformat-59.dll differ diff --git a/encoder/avutil-56.dll b/encoder/avutil-56.dll deleted file mode 100644 index 1607281..0000000 Binary files a/encoder/avutil-56.dll and /dev/null differ diff --git a/encoder/avutil-57.dll b/encoder/avutil-57.dll new file mode 100644 index 0000000..af10e79 Binary files /dev/null and b/encoder/avutil-57.dll differ diff --git a/encoder/libass-9.dll b/encoder/libass-9.dll index f008e0f..4302a4b 100644 Binary files a/encoder/libass-9.dll and b/encoder/libass-9.dll differ diff --git a/encoder/libvmaf.dll b/encoder/libvmaf.dll new file mode 100644 index 0000000..03484b8 Binary files /dev/null and b/encoder/libvmaf.dll differ diff --git a/encoder/nvrtc-builtins64_101.dll b/encoder/nvrtc-builtins64_101.dll index 305c998..007af46 100644 Binary files a/encoder/nvrtc-builtins64_101.dll and b/encoder/nvrtc-builtins64_101.dll differ diff --git a/encoder/nvrtc64_101_0.dll b/encoder/nvrtc64_101_0.dll index be95aaa..9ab990e 100644 Binary files a/encoder/nvrtc64_101_0.dll and b/encoder/nvrtc64_101_0.dll differ diff --git a/encoder/swresample-3.dll b/encoder/swresample-3.dll deleted file mode 100644 index 6968fd7..0000000 Binary files a/encoder/swresample-3.dll and /dev/null differ diff --git a/encoder/swresample-4.dll b/encoder/swresample-4.dll new file mode 100644 index 0000000..e08dab0 Binary files /dev/null and b/encoder/swresample-4.dll differ