Show Script Subtitles

I've used the Closed Caption/Subtitles option to add subtitles to some of my scripted shows to display the product names as the product is being fired. There are several different subtitle formats and different software/video players can interpret the subtitles differently. I chose a .srt format that works well with YouTube.

I've written a little AWK script that will take a Finale generic csv export or a cobra csv script and generate a subtitles file that can be added to your video.

If you look at the following video and turn on the "CC" closed captions, you can see an example:

It's written in AWK which is easy to run on a Linux machine, but not so easy to run on a Windows machine.

Since most people can't easily run the AWK script. I made another script (email bot) that runs on my Linux box that looks for email periodically. It will take your script, automatically generate the subtitles file and email it back to you.

2022-04-08  - UPDATE

It appears google has broken the email script again. It also sounds like the will no longer allow the password authentication my script is currently using starting in May to improve security. So for now, the email option is probably not working to automatically process the subtitles. If you want me to run it manually, you can email the script to me. chris at duesman.net.

I've cleaned up some of my @duesman.net google email accounts. I moved the Subtitle email to it's own GMAIL account. The address has changed to Subtitle.Duesman@gmail.com

Here's how it works.

Send an email to Subtitle.Duesman@gmail.com with a subject of  "generate-subtitles" (otherwise the email is ignored).

Inside the email, you can include the following lines:

TimeOffset: 3

Email: YOUR@EMAILADRESS

Then attach the Cobra.csv script or Finale generic export csv file (as an attachment).

Here's a link that should open your mail up with some of that info already setup: LINK

The TimeOffset number can be negative or positive. It's the number of seconds to adjust the subtitles.

The Email is your email address to send the subtitles file. If you don't include this, we'll try to decipher who the email came from and just use that address.

My linux box checks for new emails every 10 mins or so. It will grab the email, generate the subtitle file and send it as an attachement back to the email address provided.

You might need to try a few TimeOffset values to get the subtitles to sync up with your video.  Here's how it should work. 

Say your script has 5 seconds of silence before the show starts. The first cue could be at 00:05.00.

Say your video has 8 seconds before the show starts. If we didn't adjust the offset, the subtitles would start 5 seconds into the video and not be in sync with the fireworks.

The TimeOffset is added to the cue time. So if the fireworks in the video starts at 8 seconds and you have 5 seconds of silence in the script, you should set the offset to 3. The TimeOffset will be added to each cue's time. So the first subtitle would be at 00:08.00. (5+3)

You can do a negative TimeOffset as well. Say your script had a 10 second silence (pre-roll), but your video only included 4 seconds before the first cue. You'd want to set the offset to -6. So the first subtitle would be at 00:04.00 (10-6).

The TimeOffset can be partial seconds as well like 4.5

Subtitles are generated in the SubRip (.srt) format. (it's documented at https://en.wikipedia.org/wiki/SubRip )

The script will group together up to 5 effects and total the qty of each effect. This helps handle cues that fire quickly (much faster than normal subtitles are done).

For example the following script subset (this is from a Finale generic csv export):

FIRING_HEADER_ROW,Time Cue Number,Ignition Event Time,Number Of Devices,Unused1,Unused2,Chain Identifier,Lockout Identifier,Device Delay,Prefire Delay,Effect Name,Caliber,Category,Angles,Position Name,Animation Description,Module Description,Module Address,Slat Address,Pin Address,Unused4,Firing Notes,Product ID,Manufacturer Product ID,Animation ID,Location Primary,Location Secondary,Price Per Device,Unused8,Unused9,Mortar Caliber,Track Identifier

FIRING_DATA_ROW,,10.60,1,,,,,0.00,0.30,WSF-20 White Strobe 20s,20mm,Other,|,L-Board,,18r2,01,,11,,,,,http://www.finalefireworks.com/api/fireworks/1459426,,,,,,,

FIRING_DATA_ROW,,10.60,1,,,,,0.00,0.30,WSF-20 White Strobe 20s,20mm,Other,|,R-Board,,18r2,11,,11,,,,,http://www.finalefireworks.com/api/fireworks/1459426,,,,,,,

FIRING_DATA_ROW,,10.60,1,,,,,0.00,0.30,WSF-20 White Strobe 20s,20mm,Other,|,LC-Board,,18r2,03,,12,,,,,http://www.finalefireworks.com/api/fireworks/1459426,,,,,,,

FIRING_DATA_ROW,,10.60,1,,,,,0.00,0.30,WSF-20 White Strobe 20s,20mm,Other,|,Center Board,,18r2,04,,16,,,,,http://www.finalefireworks.com/api/fireworks/1459426,,,,,,,

FIRING_DATA_ROW,,10.60,1,,,,,0.00,0.30,WSF-20 White Strobe 20s,20mm,Other,|,RC-Board,,18r2,08,,12,,,,,http://www.finalefireworks.com/api/fireworks/1459426,,,,,,,

FIRING_DATA_ROW,,10.70,1,,,,,0.00,0.30,RCS30A C11 30mm Silver Cascade Comet,30mm,Comets,/ 20,LC-Board,,18r2,03,,2,,,,,http://www.finalefireworks.com/api/fireworks/1448764,,,,,,,

FIRING_DATA_ROW,,10.70,1,,,,,0.00,0.30,RCS30A C11 30mm Silver Cascade Comet,30mm,Comets,/ 20,RC-Board,,18r2,08,,3,,,,,http://www.finalefireworks.com/api/fireworks/1448764,,,,,,,

FIRING_DATA_ROW,,13.55,1,,,,,0.00,0.30,RCS30A C11 30mm Silver Cascade Comet,30mm,Comets,\ -20,LC-Board,,18r2,03,,1,,,,,http://www.finalefireworks.com/api/fireworks/1448764,,,,,,,

FIRING_DATA_ROW,,13.55,1,,,,,0.00,0.30,RCS30A C11 30mm Silver Cascade Comet,30mm,Comets,\ -20,RC-Board,,18r2,08,,1,,,,,http://www.finalefireworks.com/api/fireworks/1448764,,,,,,,

FIRING_DATA_ROW,,16.35,1,,,,,0.00,0.30,RCS30A C11 30mm Silver Cascade Comet,30mm,Comets,/ 20,LC-Board,,18r2,03,,3,,,,,http://www.finalefireworks.com/api/fireworks/1448764,,,,,,,

FIRING_DATA_ROW,,16.35,1,,,,,0.00,0.30,RCS30A C11 30mm Silver Cascade Comet,30mm,Comets,\ -20,RC-Board,,18r2,08,,2,,,,,http://www.finalefireworks.com/api/fireworks/1448764,,,,,,,

FIRING_DATA_ROW,,19.48,1,,,,,0.00,0.30,DM371 - Red Strobe Pistil Brocade Crown Mine,"1.75""",Mines,|,LC-Rack,,18r2,02,,1,,,,,http://www.finalefireworks.com/api/fireworks/1451658,,,,,,,

FIRING_DATA_ROW,,20.19,1,,,,,0.00,0.30,DM371 - Red Strobe Pistil Brocade Crown Mine,"1.75""",Mines,/ 1,RC-Rack,,18r2,09,,10,,,,,http://www.finalefireworks.com/api/fireworks/1451658,,,,,,,

FIRING_DATA_ROW,,21.15,1,,,,,0.00,0.30,PFS045X Red Flame - 60 Secs,"2""",Other,|,L-Board,,18r2,01,,9,,,,,http://www.finalefireworks.com/api/fireworks/1459407,,,,,,,

FIRING_DATA_ROW,,21.15,1,,,,,0.00,0.30,PFS045X Red Flame - 60 Secs,"2""",Other,|,R-Board,,18r2,11,,9,,,,,http://www.finalefireworks.com/api/fireworks/1459407,,,,,,,

FIRING_DATA_ROW,,21.15,1,,,,,0.00,0.30,PFS045X Red Flame - 60 Secs,"2""",Other,|,LC-Board,,18r2,03,,9,,,,,http://www.finalefireworks.com/api/fireworks/1459407,,,,,,,

FIRING_DATA_ROW,,21.15,1,,,,,0.00,0.30,PFS045X Red Flame - 60 Secs,"2""",Other,|,Center Board,,18r2,04,,14,,,,,http://www.finalefireworks.com/api/fireworks/1459407,,,,,,,

FIRING_DATA_ROW,,21.15,1,,,,,0.00,0.30,PFS045X Red Flame - 60 Secs,"2""",Other,|,RC-Board,,18r2,08,,9,,,,,http://www.finalefireworks.com/api/fireworks/1459407,,,,,,,

FIRING_DATA_ROW,,21.45,1,,,,,0.00,2.00,Atom Splitter - 9 Shot,20mm,Cakes,|,Center Board,,18r2,04,,2,,,,,http://www.finalefireworks.com/api/fireworks/1496228,,,,,,,

would generate these 5 subtitles

1

00:00:05,800 --> 00:00:08,650

5 x WSF-20 White Strobe 20s

2 x RCS30A C11 30mm Silver Cascade Comet

2

00:00:08,750 --> 00:00:11,450

2 x RCS30A C11 30mm Silver Cascade Comet

3

00:00:11,550 --> 00:00:14,550

2 x RCS30A C11 30mm Silver Cascade Comet

4

00:00:14,680 --> 00:00:16,240

2 x DM371 - Red Strobe Pistil Brocade Crown Mine

5

00:00:16,340 --> 00:00:19,340

5 x PFS045X Red Flame - 60 Secs

Atom Splitter - 9 Shot

Once you have your .srt subtitles file, you can add it to an existing YouTube video. 

You could also likely use it with media players or use it add to your video. (Those instructions would be very specific to your media player or video editing software.) YouTube is easy.

There are numerous youtube videos and websites that describe how to add the subitles to your YouTube video. (Just google "youtube add subtitles"). 

Here's one with just text instructions: https://support.google.com/youtube/answer/2734796?hl=en   (you'd want to follow the "Upload a file" option and select "With Timing")

The instructions vary a bit if you're using the Classic or the new YouTube Studio. It can be done in either.

An easier way to get add the subtitles to YouTube might be to just click on the 3 "..." dots below your video. You should see an "Add translations" option that will take you right into the option to setup/add some closed captions to your video.

If you see anything weird in the subtitles, let me know. My script has 2 additional variables that I could adjust if needed. I currently set each subtitle to display for 3 seconds and max items of 5.

A Finale generic export could provide a little more detail than the Cobra script. Finale has a "Number of Devices" that is included in the quantity count that the Cobra script might not include.

If someone wants it I could also add an option to include something like "Product ID" from finale.

If you want the subtitles in a different subtitle format, there are sites out there like https://gotranscript.com/subtitle-converter that will convert the .srt file to other formats.

2020-07-05 - I made some updates the script. Instead of always grouping product into 3 second subtitles, it will not group them into shorter subtitles when needed. It will also include a .1 second gap between the subtitles (which is helpful if you have the same item or group of items being shot several times in a row). With the gap, the subtitles (if the same) will appear to blink rather than stay solid to indicate the same pattern is being repeated.

2020-07-07 - I cleaned up the script a bit. (It evolved a bit since it was initially created.) I exposed a few more of the optional variables. I've added the script below. If you have a linux server or a machine that is capable of running AWK scripts, you can download it and try to run it locally. Here's the syntax:

# awk -v TimeOffset=-5 -f subtitles.awk < Script_Export.csv > subtitles.srt  

#

# or passing additional optional variables:

# awk -v TimeOffset=-5 -v MinSubtitleLength=1 -v MaxSubtitleLength=3 -v MaxSubtitleCount=5 -f subtitles.awk < Script_Export.csv > subtitles.srt  

#

# Where

#

#  TimeOffset is the number of seconds to add/subtract to the script firing time to match the video. (Default is 0) 

#

#  MinSubtitleLength is the min number of seconds a subtitle is displayed in seconds when cues a close to each other. (Default is 1)

#

#  MaxSubtitleLength is the max number of seconds a subtitle is displayed in seconds when cues are not close to each other. (Default is 3)

#

#  MaxSubtitleCount is the max number of like prodcuts that will be combined into one subtitle. (Default is 5)

#

#  MinSubtitleGap is the min number of seconds between subtitles. (Default is .1)

The email bot is only passing in the TimeOffset specified as subtitle_offset:  in the email. (Hindsight, I should have matched the variables names.) If someone wants to adjust the other values and can't run the script themselves, let me know and I'll see if I can add those to the email bot. 

2020-07-21 - Added parsing of email to grab values for MinSubtitleLength,  MaxSubtitleLength,  MaxSubtitleCount, and MinSubtitleGap. Added EventTimeField, EventDescField and EventQtyField to specify which comma seperated field to parse those values from when using a non-standard or older script format. I found an older Finale script that uses EventTimeField: 3    EventDescField: 11     EventQtyField: 4  but does not start with "FIRING_DATA_ROW".