Skip to content

Commit

Permalink
v4.1
Browse files Browse the repository at this point in the history
- Fixed bug with forced stereo audio track cloning (#54)
- Improved metadata title parsing
- Plex library no longer refreshes on "compliant mp4" condition, should save some CPU cycles
- Moov atom now always moved to the beginning of the file for quicker streaming (more info can be found @ https://www.adobe.com/devnet/video/articles/mp4_movie_atom.html for the curious)
- Fixed progress bar counter during interactive file discovery process
- Various minor code improvements
  • Loading branch information
BrianDMG committed Feb 14, 2020
1 parent 4a397af commit ad48031
Show file tree
Hide file tree
Showing 13 changed files with 73 additions and 28 deletions.
14 changes: 11 additions & 3 deletions conv2mp4-ps.ps1
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<#======================================================================================================================
conv2mp4-ps v4.0 - https://github.com/BrianDMG/conv2mp4-ps
conv2mp4-ps v4.1 - https://github.com/BrianDMG/conv2mp4-ps
This Powershell script will recursively search through a user-defined file path and convert all videos of user-specified
include_file_types to MP4 with H264 video and AAC audio using ffmpeg. If a conversion failure is detected, the script re-encodes
Expand Down Expand Up @@ -39,7 +39,9 @@ $cumulativeVideoDuration = [timespan]::fromseconds(0)

# Begin performing operations of files
ForEach ($file in $fileList) {

$title = $file.BaseName

$sourceFile = $file.DirectoryName + "\" + $file.BaseName + $file.Extension;

$fileSubDirs = ($file.DirectoryName).Substring($cfg.media_path.Length, ($file.DirectoryName).Length - $cfg.media_path.Length);
Expand Down Expand Up @@ -74,6 +76,7 @@ ForEach ($file in $fileList) {
Remove-Item $sourceFile -Force
Log "$($time.Invoke()) Already exists: $targetFileRenamed"
Log "$($time.Invoke()) Deleted: $sourceFile."
$duplicatesDeleted += @($sourceFile)
}
Else {
#Codec discovery to determine whether video, audio, or both needs to be encoded
Expand All @@ -91,29 +94,34 @@ ForEach ($file in $fileList) {
If ($file.Extension -ne ".mp4") {
Log "$($time.Invoke()) Video: $($getVideoCodec.ToUpper()), Audio: $($getAudioCodec.ToUpper()). Performing simple container conversion to MP4."
ConvertFile -ConvertType Simple -KeepSubs:$cfg.keep_subtitles
$simpleConversion += @($sourceFile)
$skipFile = $False
}
Else {
$getVideoDuration = "00:00:00"
$fileCompliant += @($sourceFile)
$skipFile = $True
}
}
# Video is already H264, Audio is not AAC
ElseIf ($getVideoCodec -eq 'h264' -AND $getAudioCodec -ne 'aac') {
Log "$($time.Invoke()) Video: $($getVideoCodec.ToUpper()), Audio: $($getAudioCodec.ToUpper()). Encoding audio to AAC"
ConvertFile -ConvertType Audio -KeepSubs:$cfg.keep_subtitles
$audioConversion += @($sourceFile)
$skipFile = $False
}
# Video is not H264, Audio is already AAC
ElseIf ($getVideoCodec -ne 'h264' -AND $getAudioCodec -eq 'aac') {
Log "$($time.Invoke()) Video: $($getVideoCodec.ToUpper()), Audio: $($getAudioCodec.ToUpper()). Encoding video to H264."
ConvertFile -ConvertType Video -KeepSubs:$cfg.keep_subtitles
$videoConversion += @($sourceFile)
$skipFile = $False
}
# Video is not H264, Audio is not AAC
ElseIf ($getVideoCodec -ne 'h264' -AND $getAudioCodec -ne 'aac') {
Log "$($time.Invoke()) Video: $($getVideoCodec.ToUpper()), Audio: $($getAudioCodec.ToUpper()). Encoding video to H264 and audio to AAC."
ConvertFile -ConvertType Both -KeepSubs:$cfg.keep_subtitles
$bothConversion += @($sourceFile)
$skipFile = $False
}

Expand All @@ -122,7 +130,7 @@ ForEach ($file in $fileList) {
}

# Refresh Plex libraries
If ($cfg.use_plex) {
If ($cfg.use_plex -AND (-Not($skipFile))) {
PlexRefresh
}

Expand Down Expand Up @@ -194,7 +202,7 @@ ForEach ($file in $fileList) {
}

#Running tally of session container duration (cumulative length of video processed)
$script:cumulativeVideoDuration = $script:cumulativeVideoDuration + $getVideoDuration
$script:cumulativeVideoDuration = $cumulativeVideoDuration + $getVideoDuration
}
} # End foreach loop

Expand Down
4 changes: 2 additions & 2 deletions docs/guidelines/CONTRIBUTING.md → docs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
## Contributing

* When contributing to this repository, please first discuss the change you wish to make by creating a new issue. Please label and assign your issue according to the **[issue guidelines](/docs/guidelines/ISSUE_TEMPLATE.md)**
* When contributing to this repository, please first discuss the change you wish to make by creating a new issue. Please label and assign your issue according to the **[issue guidelines](/docs/ISSUE_TEMPLATE.md)**

## Pull Request Process

* Before submitting your pull request, please review to the **[pull request guidelines](/docs/guidelines/PULL_REQUEST_TEMPLATE.md)**
* Before submitting your pull request, please review to the **[pull request guidelines](/docs/PULL_REQUEST_TEMPLATE.md)**
* The pull request will be merged once the code has been reviewed.

**Thanks for contributing!**
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#### **Review this checklist before filing an issue:**

- [ ] Is this something you can **debug and fix**? Send a [pull request](/docs/guidelines/PULL_REQUEST_TEMPLATE.md)! Bug fixes and documentation fixes are always welcome.
- [ ] Is this something you can **debug and fix**? Send a [pull request](/docs/PULL_REQUEST_TEMPLATE.md)! Bug fixes and documentation fixes are always welcome.
- [ ] Have a usage question? Please label your issue as "question".
- [ ] Have an idea for a feature? Please label your issue as "enhancement".

Expand Down
File renamed without changes.
3 changes: 1 addition & 2 deletions docs/guidelines/STRUCTURE.md → docs/STRUCTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
- **.gitignore**: list of files and directories to be ignored by git
- **conv2mp4-ps.ps1**: Main executable script
- **README.md**: Main readme documentation
- **docs**: Contains script documentation
- **guidelines**: Contains code contribution guidelines and templates
- **docs**: Contains script documentation, code contribution guidelines, and templates
- **files**: Contains all other script-related files
- **cfg**: Contains configuration-related files
- `config.template`
Expand Down
8 changes: 5 additions & 3 deletions files/func/CloneStereoStream.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ Function CloneStereoStream {
If ($copyStereo) {
mkdir $($prop.tmp_dir) -Force

$ffmpeg = Join-Path $cfg.fmmpeg_bin_dir "ffmpeg.exe"

#ffmpeg pull audio track from file
$ffmpegArgs = "-i "
$ffmpegArgs += "$targetFileRenamed "
$ffmpegArgs += "$targetFile "
$ffmpegArgs += "-vn "
$ffmpegArgs += "-acodec "
$ffmpegArgs += "copy "
Expand All @@ -26,7 +28,7 @@ Function CloneStereoStream {
$ffmpegCMD = cmd.exe /c "$ffmpeg $ffmpegArgs"

#Rename original source file, necessary to avoid corrupting by using same file as input and output
Move-Item $targetFileRenamed $tempFileName -Force
Move-Item $targetFile $tempFileName -Force

#ffmpeg inject stereo audio track back into file
$ffmpegArgs = "-y "
Expand All @@ -42,7 +44,7 @@ Function CloneStereoStream {
$ffmpegArgs += "copy "
$ffmpegArgs += "-metadata:s:a "
$ffmpegArgs += "handler=Stereo "
$ffmpegArgs += "$targetFileRenamed"
$ffmpegArgs += "$targetFile"
$ffmpegCMD = cmd.exe /c "$ffmpeg $ffmpegArgs"

Remove-Item $tempFileName -Force
Expand Down
7 changes: 7 additions & 0 deletions files/func/ConvertFile.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,15 @@ Function ConvertFile {
$ffArgs += "`"$sourceFile`" " #Input file
$ffArgs += "-threads " #Flag to set maximum number of threads (CPU) to use
$ffArgs += "6 " #Maximum number of threads (CPU) to use
$ffArgs += "-movflags"
$ffArgs += "+faststart"

If ($cfg.use_set_metadata_title){
$remove= $title | Select-String -Pattern '^(.*?)(19|20)[0-9]{2}(.*$)' | ForEach-Object { "$($_.matches.groups[3])" }
$title = $title -replace "$remove",''
$title = $title -replace '\W',' '
$title = $title -replace '(\d{4})$', '($1)';

$ffArgs += "-metadata " #Flag to specify key/value pairs for encoding metadata
$ffArgs += "title=`"$title`" " #Use $title variable as metadata 'Title'
}
Expand Down
9 changes: 6 additions & 3 deletions files/func/GetAudioStreams.ps1
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
Function GetAudioStreams {
$ffprobeArgs = "-i "
$ffprobeArgs += "`"$targetFileRenamed`" "
$ffprobe = Join-Path $cfg.fmmpeg_bin_dir "ffprobe.exe"

$ffprobeArgs += "-v "
$ffprobeArgs += "error "
$ffprobeArgs += "`"$targetFile`" "
$ffprobeArgs += "-show_entries "
$ffprobeArgs += "stream=channels "
$ffprobeArgs += "-select_streams "
Expand All @@ -11,7 +14,7 @@ Function GetAudioStreams {
[int[]] $audioStreamArray = cmd.exe /c "$ffprobe $ffprobeArgs"

#If last channel is not stereo, create one
If ($audioStreamArray[$audioStreamArray.Length-1] -ne 2) {
If ($audioStreamArray[$audioStreamArray.Length-1] -gt 2 ) {
return $True
}
#If not, skip stream clone
Expand Down
5 changes: 3 additions & 2 deletions files/func/PrintEncodeError.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ Function PrintEncodeError {
$fileSizeDelta = [Math]::Round($fileSizeDelta, 2)
Try {
Remove-Item -LiteralPath $targetFile -Force -ErrorAction Stop
Log "$($time.Invoke()) EXCEPTION: New file is over 25% smaller ($($fileSizeDelta)MB). $targetFile deleted."
Log "$($time.Invoke()) EXCEPTION: New file is over 25% smaller ($($fileSizeDelta)MB)."
Log "$($time.Invoke()) $targetFileRenamed deleted."
Log "$($time.Invoke()) FAILOVER: Re-encoding $sourceFile with Handbrake."
}
Catch {
Log "$($time.Invoke()) ERROR: $targetFile could not be deleted. Full error below."
Log "$($time.Invoke()) ERROR: $targetFileRenamed could not be deleted. Full error below."
Log $_
}
}
3 changes: 2 additions & 1 deletion files/func/PrintEncodeFailure.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ Function PrintEncodeFailure {
encodeFailure {
$script:failedEncodes += @($sourceFile)
Remove-Item $targetFile -Force -ErrorAction Stop
Log "$($time.Invoke()) ERROR: Failover threshold exceeded even after failover: ($($fileSizeDelta)MB). $targetFile deleted."
Log "$($time.Invoke()) ERROR: Failover threshold exceeded even after failover: ($($fileSizeDelta)MB)."
Log "$($time.Invoke()) $targetFileRenamed deleted."
Log "$($time.Invoke()) Deleted new file and retained $sourceFile."
}
}
Expand Down
26 changes: 24 additions & 2 deletions files/func/PrintStatistics.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,34 @@ Function PrintStatistics {
Try {
$averageConversionRate = $cumulativeVideoDuration.Ticks / $scriptExecutionDuration.Ticks
$averageConversionRate = [math]::Round($averageConversionRate, 2)
Log "Average conversion speed of $($averageConversionRate)x"
Log "Average conversion speed of $($averageConversionRate)x`n"
}
Catch {
Log "$_"
Log "No time elapsed."
Log "No time elapsed.`n"
}

#Print process type totals
If ($duplicatesDeleted.Count -ge 1) {
Log "Duplicates deleted: $($duplicatesDeleted.Count)"
}
If ($simpleConversion.Count -ge 1) {
Log "Simple container conversions: $($simpleConversion.Count)"
}
If ($videoConversion.Count -ge 1) {
Log "Video-only encodes: $($videoConversion.Count)"
}
If ($audioConversion.Count -ge 1) {
Log "Audio-only encodes: $($audioConversion.Count)"
}
If ($bothConversion.Count -ge 1) {
Log "Video and audio encodes: $($bothConversion.Count)"
}
If ($fileCompliant.Count -ge 1) {
Log "Compliant files: $($fileCompliant.Count)"
}


Log "`n$($prop.final_stat_divider)"
}
Else {
Expand Down
18 changes: 10 additions & 8 deletions files/init/buildqueue.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@ Write-Output "`nBuilding file list, please wait. This may take a while, especial
If ($cfg.use_ignore_list) {
$cfg.include_file_types += ", *.mp4"
$fileList = Get-ChildItem "$((Get-Item -Path $cfg.media_path).FullName)" -Include ( $cfg.include_file_types -split ',' ).trim() -Exclude $(Get-Content $prop.ignore_path) -Recurse |
ForEach-Object {
Write-Progress "`rFound $(@($fileList).indexOf($file)+1) file(s) so far..."
$_
}
ForEach-Object {$counter = 1} {
Write-Progress -Activity "Found $($counter) file(s) so far..." -Status "Processing..." -CurrentOperation "$($_.FullName)"
$_
$counter++
}
}
Else {
$fileList = Get-ChildItem "$((Get-Item -Path $cfg.media_path).FullName)" -Include ( $cfg.include_file_types -split ',' ).trim() -Recurse |
ForEach-Object {
Write-Progress "`rFound $(@($fileList).indexOf($file)+1) file(s) so far..."
$_
}
ForEach-Object {$counter = 1} {
Write-Progress -Activity "Found $($counter) file(s) so far..." -Status "Processing..." -CurrentOperation "$($_.FullName)"
$_
$counter++
}
}

PrintFileQueue
2 changes: 1 addition & 1 deletion files/prop/properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#Version
version=4.0
version=4.1
platform=ps

#URLs
Expand Down

0 comments on commit ad48031

Please sign in to comment.