Skip to content

Instantly share code, notes, and snippets.

@brycesch
Last active March 22, 2019 16:38
Show Gist options
  • Save brycesch/10a6572529ebcd568261773651471550 to your computer and use it in GitHub Desktop.
Save brycesch/10a6572529ebcd568261773651471550 to your computer and use it in GitHub Desktop.
Ruby library to generate webvtt formatted transcripts from an array of timestamped words.
module Webvtt
DEFAULT_MAX_CHAR_LENGTH = 40
class Cue
attr_accessor :start, :end, :words
def initialize(words)
self.words = words
end
def to_s
"#{title}\n#{text}"
end
def title
"#{start_time} --> #{end_time}"
end
def text
self.words.map{|w| w['word']}.join(' ')
end
def start_time
Time.at(self.words.first['starts_at']).strftime("00:%M:%S.%L") #not using %H
end
def end_time
Time.at(self.words.last['ends_at']).strftime("00:%M:%S.%L")
end
end
class Vtt
attr_accessor :words, :max_line_length
def initialize(words, options={})
self.words = words
self.max_line_length = options[:max_line_length] || DEFAULT_MAX_CHAR_LENGTH
end
def cues
@cues ||= begin
all_cues = []
current_cue = []
line_length = 0
words.each do |word|
if (line_length + ' '.length + word['word'].length <= self.max_line_length)
current_cue << word
line_length = line_length + word['word'].length
else
all_cues << Cue.new(current_cue)
current_cue = [word]
line_length = 0
end
end
all_cues << Cue.new(current_cue) unless current_cue.empty?
all_cues
end
end
def to_s
@vtt ||= begin
lines = []
lines << "WEBVTT\n"
cues.each_with_index do |cue, i|
lines << (i+1).to_s
lines << "#{cue.to_s}\n"
end
lines.join("\n")
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment