Skip to content

Instantly share code, notes, and snippets.

@zhusee2
Last active December 15, 2015 21:28
Show Gist options
  • Save zhusee2/5325485 to your computer and use it in GitHub Desktop.
Save zhusee2/5325485 to your computer and use it in GitHub Desktop.
Convert subtitles of StarCraft II: Heart of the Swarm cinematic videos (.event) to SubRip format (.srt)

HOTS Subtitle Converter

Converts subtitles of StarCraft II: Heart of the Swarm cinematic videos (in .event format) to SubRip format (.srt)

Environment

Necessary libraries are required in main.html. This script use WebKit console interface to take commands and give outputs. Note that only Safari allow XHR on local files by default. You have to enable relevant options in Chrome or it should raise Allow Origin errors when attempt to read .event files. I haven't tried Firefox, but it sould be compatible with the console interface of Firefox.

How to Use

Put the relative path to the folder where your .event files are located in the last line of HOTSSubtitleConverter.coffee. Then run main.html and toggle your WebKit console. The converter should have been initialized as window.hotsConverter (or simply hotsConverter.) It contains an array of parsed subtitles. Run:

hotsConverter.convert(0);

where 0 can ususally be from 0 to 11 for Heart of the Swarm files. Each run will print subtitle in SubRip (.srt) format in console. Now you can copy them and paste to other text editors and save the subtitle files. Done!

class CinematicSubtitleConverter
constructor: (@file_path) ->
@subtitleFileNames = []
@_initSubtitleList()
convert: (index) ->
subtitlePath = "#{@file_path}/#{@subtitleFileNames[index]}"
subtitleFile = new CinematicSubtitle(subtitlePath)
console.log subtitleFile
_initSubtitleList: ->
for x in [1..10]
x = "0#{x}" if x < 10
@subtitleFileNames.push "cinematic_swarm#{x}.event"
@subtitleFileNames.push "cinematic_swarm_ascend.event"
@subtitleFileNames.unshift "cinematic_swarm_intro.event"
class CinematicSubtitle
constructor: (@path) ->
@version = 1
@fps = 24
@subtitleLines = []
$.get @path, (data) =>
results = data.split(/\n/)
@version = parseInt results[0].match(/[0-9]+/)
@fps = parseInt results[1].match(/[0-9]+/)
for string in results[2..]
@subtitleLines.push new CinematicSubtitleLine(string, @fps) if string != ""
@sort()
@toSubRip()
sort: ->
@subtitleLines.sort (a, b) ->
if a.startTimeRaw > b.startTimeRaw then 1 else -1
toSubRip: ->
result = ""
for i, line of @subtitleLines
result += "#{i}\n#{line.toSubRip()}\n\n"
console.log result
class CinematicSubtitleLine
constructor: (@rawString) ->
parseResult = @rawString.match(/subtitle ([0-9]+) ([0-9]+) \[\[(.+)\]\]/)
@startTimeRaw = parseInt parseResult[1]
@startTime = getTimeFrameString(parseResult[1])
@timeLength = getTimeFrameString(parseResult[2])
@endTime = getTimeFrameString(parseInt(parseResult[1]) + parseInt(parseResult[2]))
@text = removeFormat(parseResult[3])
toSubRip: ->
return "#{@startTime} --> #{@endTime}\n#{@text}"
removeFormat = (formatedString) ->
return formatedString.replace(/<[^>]+>/g, '')
getTimeFrameString = (millionSeconds) ->
remaining = millionSeconds % 1000
time = new Date(millionSeconds - 28800000)
return "#{time.toTimeString().split(' ')[0]},#{remaining}"
window.converter = new CinematicSubtitleConverter('SWOT Cinematic Videos')
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://coffeescript.org/extras/coffee-script.js"></script>
<script type="text/coffeescript" src="converter.coffee" async defer></script>
</head>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment