Timestamp Calculator (For the L1 News)

Problem

Whenever @GrantyBoy does the timestamps for the news, he scrubs through each of the 3 videos to get timestamps for articles. When he does the patreon/floatplane version, he puts all the videos together. The problem with this, is that all of the timestamps for episode 2 and 3 are different now since it’s 1 whole video.

He’s been using this website to manually calculate what each timestamp should be for this long-format version.

E.g., so if episode 1 was 45 minutes and 12 seconds long, he’d put that number in the top, then add each timestamp from episode 2 to the bottom. Then repeat for episode 3.

So, needless to say that takes a long time and it’s soooo tedious. I didn’t realize how tedious it was until I had to do it for the news last week!

I had to help him out.


Solution

Here’s my solution with an actual news txt file for you to try out:

Test News Episode TXT File
test.txt (3.1 KB)

RAR Download
Timestamp Calculator.rar (76.1 KB)

1
2

Visual Basic

I’ve never used Visual Basic so I thought I’d challenge myself to do something different and give it a go. Literally nothing was available online/apparently no one has done this sort of thing before lol

Figuring out syntax since I’m used to C# was pretty straight forward, but the hardest part was figuring out how to loop and parse the numbers for the calculation.

Splitting Timestamps / Making Arrays

I discovered I could just split a current line with no conditions in a do-while loop, and that would make an array entry everytime there was a " " space.

Dim currentLine = reader.ReadLine()
lineArray(i) = currentLine

inputArray = Split(currentLine)

Then, the 1st entry would always be the timestamp.

Dim baseTime() = Split(inputArray(0), ":")

Woo! I could split it into hours, minutes, and seconds:

If baseTime.Length = 2 Then
    baseTimeMin = Convert.ToInt32(baseTime(0))
    baseTimeSec = Convert.ToInt32(baseTime(1))
ElseIf baseTime.Length = 3 Then
    baseTimeHour = Convert.ToInt32(baseTime(0))
    baseTimeMin = Convert.ToInt32(baseTime(1))
    baseTimeSec = Convert.ToInt32(baseTime(2))
End If

Adding timestamps together

I’ve figured out adding two timestamps together really isn’t that hard.

You just need to add them together then deal with the numbers over 59 being carried.

After thinking about it for a few minutes, it made sense that division would give me the carried number, then the remainder to stay would be whatever the x modulus 60 is:

'Basic time logic
Dim calcTimeHour = addByHour + baseTimeHour
Dim calcTimeMin = addByMin + baseTimeMin
Dim calcTimeSec = addBySec + baseTimeSec

'Carrying time logic
If calcTimeSec > 59 Then
    calcTimeMin = calcTimeMin + Math.Floor(calcTimeSec / 60)
    calcTimeSec = calcTimeSec Mod 60
End If

If calcTimeMin > 59 Then
    calcTimeHour = calcTimeHour + Math.Floor(calcTimeMin / 60)
    calcTimeMin = calcTimeMin Mod 60
End If

Formatting results

Isn’t formatting always fun? /s

I was able to put everything together for the output box to be displayed correctly, buuuut it was kind of a jigsaw puzzle lol:

'Formatting timestamps Output
If calcTimeHour = 0 Then
    If calcTimeSec < 10 Then
        rtbOutput.AppendText(calcTimeMin & ":0" & calcTimeSec)
    Else
        rtbOutput.AppendText(calcTimeMin & ":" & calcTimeSec)
    End If
ElseIf calcTimeHour <> 0 Then
    rtbOutput.AppendText(calcTimeHour & ":")
    If calcTimeMin < 10 Then
        rtbOutput.AppendText("0" & calcTimeMin & ":")
    Else
        rtbOutput.AppendText(calcTimeMin & ":")
    End If
    If calcTimeSec < 10 Then
        rtbOutput.AppendText("0" & calcTimeSec)
    Else
        rtbOutput.AppendText(calcTimeSec)
    End If
End If

rtbOutput.AppendText(" - ")

'Format words after timestamps
For i = 2 To inputArray.Length - 1
    rtbOutput.AppendText(inputArray(i) + " ")
Next

Exception handling

Clicking the Calculate button without a file opened
The exceptions for invalid inputs were pretty well done I think.

When the calculate button is pressed, I needed to check if a TXT file had been opened. Otherwise, without an input to reference we’d receive an error.

So I created a little function to test for that:

Private Function TimestampFileOpened() As Boolean
    Try
        Dim reader As New StreamReader(locateFile)
        Return True
    Catch ex As Exception
        MessageBox.Show("Error: No file opened. Cannot calculate.")
        Return False
    End Try
End Function

“locateFile” is referring to the variable the open function would’ve stored the file path to:

'file filter
OpenFileDialog.Filter = "Text FILE | *.txt"

'Open timestamp file
If OpenFileDialog.ShowDialog = DialogResult.OK Then

    locateFile = OpenFileDialog.FileName
    Dim fileOpened = System.IO.File.ReadAllText(locateFile)
    fileLength = fileOpened.Length

Clicking the Calculate button with an invalid amount to add

I split the amount to add’s input with a colon as the delimiter.

I knew if the array was a length of 2, the user enetered a minute:second.
Likewise, if the array length was 3 I knew the user entered an hour:minute:second

If the length was anything else, or the convert to int expression failed, a correct time was not entered:

Try
    If addByArray.Length = 2 Then
        addByMin = Convert.ToInt32(addByArray(0))
        addBySec = Convert.ToInt32(addByArray(1))
    ElseIf addByArray.Length = 3 Then
        addByHour = Convert.ToInt32(addByArray(0))
        addByMin = Convert.ToInt32(addByArray(1))
        addBySec = Convert.ToInt32(addByArray(2))
    Else
        MessageBox.Show("Error: Invalid input.")
        Return
    End If
Catch ex As Exception
    MessageBox.Show("Error: Invalid input.")
    Return
End Try

Lastly, I just needed to check if the entered time was less than 60.

If addByHour > 59 Or addByMin > 59 Or addBySec > 59 Then
    MessageBox.Show("Error: Invalid time.")
    Return
End If

That’s about it! Well, that’s all the interesting bits. Just a cute little project to help a friend/wanted to share and document.

9 Likes

Nice. I’m not a watcher of these former news episodes (sorry!) but I appreciate helping someone out this way.

BTW:

You may want to reread that last bit :stuck_out_tongue: (yeah, just a minor typo :shushing_face: )

1 Like

Thank you xD LOL

Wow! Nice job. :100:

1 Like

But isn’t it much simpler than it seems?

In the old days of the sub scene, when divx/xvid was popular, outside the English zone people made subtitles for movies, which then had to be adapted to different 1/2/3CD versions. For this purpose, good tools have been created for quick and simple text adaptation according to the needs of the part and correct matching.

Instead of doing it manually, you could also start with the long version, based on it we create times, then divide it into three parts and divide the text file into parts as well and improve the time synchronization, even with visual help.
The only variable that changes when dividing a video is the start/beginning moment and this can be corrected by any better subtitle synchronization tool which will automatically correct all times in relation to the relative start time that we set.

1 Like

What do you mean here?

This seems pretty tomato/tomatoe here. He still has to go through and get the timestamps for all of them, so whether you’re adding or dividing you have to click a few buttons to get the desired results.

Any relatively modern program designed to synchronize subtitles with the image, for example Subtitle Edit.
Any old or without many features may have limitations in the quality of automation.

I was referring more to your approach to the “reinventing the wheel” issue. There is nothing wrong with your piece of code to accomplish the task, but what struck me more was that a similar task could have been accomplished without it. :slight_smile: So, looking at the timeline, before you created your code, the solution to the matter already existed, i.e. the saying “reinventing the wheel”. :slight_smile:
w

However, I am not suggesting this as an alternative better or worse solution, I am just pointing out that this “wheel” already existed. :slight_smile:

I see what you’re saying xD I figured something already existed that could help, but I was mainly doing it as a fun challenge for myself

3 Likes

Its cool that you went the extra mile to do proper exception handling for an internal app. Thanks for sharing.

2 Likes

Thank you! I’ve actually added more exception handling, to the point it’s all fleshed out. I didn’t update it but now it’s pretty impossible to break it :stuck_out_tongue:

Just finished up the L0 video so had to come see how you do it.

1 Like

Awesome! Just lmk if you have any questions :slight_smile: