-
-
Save phyoewaipaing/d2b67892aad9b6c5a040bd9518ebf653 to your computer and use it in GitHub Desktop.
Shift .srt Subtitle Time Track
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.SYNOPSIS | |
Script that will shift the offset time of movie subtile file. | |
.DESCRIPTION | |
This script will shift the time offset of movie subtitle file. This is useful when your video soundtrack is fast or lagged to your subtitle. If your video soundtrack is faster by 3.5 seconds, | |
then you need to forward the subtitle to 3 minutes and 500 milliseconds. | |
You can delay or advance the subtitle track in hour, minutes, seconds or even in milliseconds and all subtitle lines in the file will be automatically adjusted. | |
If destination file name is not specified, then it will use the source file name plus '(new)' as the destination file name. | |
This script need to be run in windows powershell. It will also show the time elapsed for conversion process. It supports subtitle files in plain text format such as .srt file and .txt files. | |
Author: Phyoe Wai Paing | |
Country: Myanmar(Burma) | |
Released Date: 05/11/2017 | |
Example usage: | |
.\Shift-Subtitle -SourceFile The.Godfather.Part.I.1972.720p.BrRip.x264.YIFY.srt -DestFile The.God.Father.1972.srt -sec -5 | |
It will delay the every subtitle line in the source file by 5 seconds and save to file The.God.Father.1972.srt | |
You need to put the minus sign (-) at the front of time value, if you want to adjust the subtitle time lagged to the soundtrack. | |
You can ignore or put the plus sign (+) at the front of time value, if you adjust the subtitle time fast over the soundtrack. | |
.EXAMPLE | |
.\Shift-Subtitle -SourceFile Gone-With-The-Wind-1939.srt -min +2 -sec +5 -ms 300 | |
It will advance the every subtitle line in the source file by 2 minutes, 5 seconds and 300 milliseconds and save to file as 'Gone-With-The-Wind-1939(new).srt' | |
You can ignore the plus sign (+) for forward operations. | |
.PARAMETER -SourceFile | |
The name or the full path of the file you want to convert. | |
.PARAMETER -DestFile | |
The name of the destination file you want to save. | |
.PARAMETER -hr | |
The number of hours you want to move forward or backward. The maximum acceptable value is 10. | |
.PARAMETER -min | |
The number of minutes you want to move forward or backward. The maximum acceptable value is 600. | |
.PARAMETER -sec | |
The number of seconds you want to move forward or backward. The maximum acceptable value is 36000. | |
.PARAMETER -ms | |
The number of milliseconds you want to move forward or backward. The maximum acceptable value is 36000000. | |
.LINK | |
You can find this script and more at: https://www.scriptinghouse.com/ | |
#> | |
param ([parameter(Mandatory=$True,Position=0)][string]$SourceFile,[parameter(Mandatory=$False,Position=1)][string]$DestFile,[int]$hr,[int]$min,[long]$sec,[long]$ms) | |
If ( $hr -gt 10 -OR $min -gt 600 -OR $sec -gt 36000 -OR $ms -gt 36000000) | |
{ | |
Write-host -fore red "The Time Value is too large to accept. Time value limit has the following settings." | |
Write-host -fore yellow "The number of hours that can accept: 10 hr`nThe number of minutes that can accept: 600 min`nThe number of seconds that can accept:36000 sec `nThe number of milli-seconds that can accept: 36000000 ms" | |
} | |
elseif ( $SourceFile.Length -eq 0 ) | |
{ | |
Write-host -fore red "Source File path is empty. Please input the correct file." | |
} | |
elseif (-Not(Test-Path $SourceFile)) | |
{ | |
Write-host -fore red "File path is invalid. Please input the correct file location." | |
} | |
elseif ( !$hr -AND !$min -AND !$sec -AND !$ms) | |
{ | |
Write-host -fore red "Please put at least one parameter for time offset. You can use the minus sign (-) for lagged time offset." | |
Write-host -fore yellow "eg: `n.\Shift_Subtitle -SourceFile -sec +2" | |
Write-host -fore yellow ".\Shift_Subtitle -SourceFile -sec -2" | |
Write-host -fore yellow ".\Shift_Subtitle -SourceFile -min 1 -sec 2" | |
} | |
elseif ( '.srt','.txt' -match (gci $SourceFile).Extension -AND (Get-Content $SourceFile).Length -gt10 ) | |
{ | |
$Job_ScriptBlock = { | |
param ([string]$SourceFile,[string]$DestFile,[system.timespan]$ToAddTimeSpan) | |
Function Get-FinalTime | |
{ | |
param([string]$InitialTime,[system.timespan]$ToAddTimeSpan ) | |
Try { | |
$FinalTime = "{0:HH:mm:ss,fff}" -f ( [datetime]([timespan]($InitialTime.replace(',','.')) + $ToAddTimeSpan).Ticks ) ## Create the timespan from current time string, add to another timespan and format the output | |
Return $FinalTime; | |
} | |
Catch | |
{ | |
Write-host -fore Red "`nError: Cannot accept the lagged time larger than the initial value. Please input the lower value than -$InitialTime."; | |
Exit; | |
} | |
} | |
$Content = Get-Content $SourceFile | |
#### Get the Start Time and End time of the srt file ### | |
$StartTimeArray = $Content | foreach { If ($_ -match "^(\d){2}:(\d){2}:(\d){2},(\d){3}") { $Matches[0] } } | |
$EndTimeArray = $Content | foreach { If ($_ -match "(\d){2}:(\d){2}:(\d){2},(\d){3}$") { $Matches[0] } } | |
$StartTimeChangedContent = $Content | foreach { | |
### Loop each line & if the start-time (extracted from regular expression) matches one of the $StartTimeArray, then call the function to add the time-offset ### | |
If ( $StartTimeArray -match $(if ($_ -match "^(\d){2}:(\d){2}:(\d){2},(\d){3}") { $Matches[0] } ) ) | |
{ $_.Replace( $Matches[0], (Get-FinalTime $Matches[0] $ToAddTimeSpan ) ) } | |
else | |
{$_ } | |
} | |
$EndTimeChangedContent = $StartTimeChangedContent | foreach { | |
### Loop each line & if the end-time (extracted from regular expression) matches one of the $EndTimeArray, then call the function to add the time-offset ### | |
If ( $EndTimeArray -match $(if ($_ -match "(\d){2}:(\d){2}:(\d){2},(\d){3}$") { $Matches[0] } ) ) | |
{ $_.Replace( $Matches[0], (Get-FinalTime $Matches[0] $ToAddTimeSpan ) ) } | |
else | |
{$_ } | |
} | |
### Get Source File info to create the destination file ### | |
$FileInfo = gci $SourceFile | |
$FileDirectory = $FileInfo.Directory | |
$FileNameOnly = $FileInfo.BaseName | |
$FileExtension = $FileInfo.Extension | |
If ($DestFile -AND $DestFile.IndexOf('\') -eq -1) | |
{ | |
## If the dest file exist and if dest file doesn't contain full path, then use the current source file directory ## | |
$EndTimeChangedContent | Out-File $FileDirectory\$DestFile | |
Write-host -fore green "`nCompleted and writing to file $FileDirectory\$DestFile" | |
} | |
elseif ($DestFile.IndexOf('\') -eq 2) | |
{ | |
$EndTimeChangedContent | Out-File $DestFile | |
Write-host -fore green "`nCompleted and writing to file $DestFile" | |
} | |
else | |
{ | |
$EndTimeChangedContent | Out-File "$FileDirectory\$FileNameOnly(New)$FileExtension" | |
Write-host -fore green "`nCompleted and writing to file $FileDirectory\$FileNameOnly(New)$FileExtension" | |
} | |
} | |
$ToAddTimeSpan = (New-TimeSpan -Hours $hr -Minutes $min -Seconds $sec) + [timespan]::FromMilliseconds($ms) | |
### Start Job with parameters source file path, destination path,and offset time | |
$job = Start-Job -ScriptBlock $Job_ScriptBlock -ArgumentList (gci $SourceFile).FullName,$DestFile,$ToAddTimeSpan | |
#### If the millisecond option is specified then put the decimal places ### | |
if ($ms -AND $ToAddTimeSpan.Milliseconds -ne 0) | |
{ $TimeOffsetDisplay = $ToAddTimeSpan.ToString() -replace ".{4}$" } | |
else | |
{ $TimeOffsetDisplay = $ToAddTimeSpan.tostring() } | |
$Direction = If ($ToAddTimeSpan.TotalMilliseconds -lt 0) { "Backward"} else { "Forward"} ## Put the direction variable depending on the sign of $ToAddTimeSpan ## | |
$Timer= [Diagnostics.Stopwatch]::StartNew() ## Start the timer to calculate the run time | |
write-host -fore yellow "`nShifting Subtitle Time $Direction ($TimeOffsetDisplay) in $SourceFile " -NoNewline; | |
### Display the dotted line and check the job status at 1 sec intervals ### | |
do { write-host "." -NoNewline; Start-Sleep 1 } | |
while ($job.State -ne "Completed"); | |
$job | Receive-Job; | |
$Timer.stop() | |
Write-host "Total time elapsed: $($Timer.elapsed.seconds) sec" | |
Remove-Job $job; | |
} | |
else | |
{ | |
Write-host -fore red "Source File Size is empty or has incorrect file extension. Please check the file." | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment