Add method to construct WebVTT files
Similar to JSON.Build
This commit is contained in:
parent
bb14f79496
commit
54fa59cbb0
2 changed files with 131 additions and 0 deletions
64
spec/helpers/vtt/builder_spec.cr
Normal file
64
spec/helpers/vtt/builder_spec.cr
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
require "../../spec_helper.cr"
|
||||||
|
|
||||||
|
MockLines = [
|
||||||
|
{
|
||||||
|
"start_time": Time::Span.new(seconds: 1),
|
||||||
|
"end_time": Time::Span.new(seconds: 2),
|
||||||
|
"text": "Line 1",
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"start_time": Time::Span.new(seconds: 2),
|
||||||
|
"end_time": Time::Span.new(seconds: 3),
|
||||||
|
"text": "Line 2",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
Spectator.describe "WebVTT::Builder" do
|
||||||
|
it "correctly builds a vtt file" do
|
||||||
|
result = WebVTT.build do |vtt|
|
||||||
|
MockLines.each do |line|
|
||||||
|
vtt.line(line["start_time"], line["end_time"], line["text"])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(result).to eq([
|
||||||
|
"WEBVTT",
|
||||||
|
"",
|
||||||
|
"00:00:01.000 --> 00:00:02.000",
|
||||||
|
"Line 1",
|
||||||
|
"",
|
||||||
|
"00:00:02.000 --> 00:00:03.000",
|
||||||
|
"Line 2",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
].join('\n'))
|
||||||
|
end
|
||||||
|
|
||||||
|
it "correctly builds a vtt file with setting fields" do
|
||||||
|
setting_fields = {
|
||||||
|
"Kind" => "captions",
|
||||||
|
"Language" => "en",
|
||||||
|
}
|
||||||
|
|
||||||
|
result = WebVTT.build(setting_fields) do |vtt|
|
||||||
|
MockLines.each do |line|
|
||||||
|
vtt.line(line["start_time"], line["end_time"], line["text"])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(result).to eq([
|
||||||
|
"WEBVTT",
|
||||||
|
"Kind: captions",
|
||||||
|
"Language: en",
|
||||||
|
"",
|
||||||
|
"00:00:01.000 --> 00:00:02.000",
|
||||||
|
"Line 1",
|
||||||
|
"",
|
||||||
|
"00:00:02.000 --> 00:00:03.000",
|
||||||
|
"Line 2",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
].join('\n'))
|
||||||
|
end
|
||||||
|
end
|
67
src/invidious/helpers/webvtt.cr
Normal file
67
src/invidious/helpers/webvtt.cr
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
# Namespace for logic relating to generating WebVTT files
|
||||||
|
#
|
||||||
|
# Probably not compliant to WebVTT's specs but it is enough for Invidious.
|
||||||
|
module WebVTT
|
||||||
|
# A WebVTT builder generates WebVTT files
|
||||||
|
private class Builder
|
||||||
|
def initialize(@io : IO)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Writes an vtt line with the specified time stamp and contents
|
||||||
|
def line(start_time : Time::Span, end_time : Time::Span, text : String)
|
||||||
|
timestamp(start_time, end_time)
|
||||||
|
@io << text
|
||||||
|
@io << "\n\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
private def timestamp(start_time : Time::Span, end_time : Time::Span)
|
||||||
|
add_timestamp_component(start_time)
|
||||||
|
@io << " --> "
|
||||||
|
add_timestamp_component(end_time)
|
||||||
|
|
||||||
|
@io << '\n'
|
||||||
|
end
|
||||||
|
|
||||||
|
private def add_timestamp_component(timestamp : Time::Span)
|
||||||
|
@io << timestamp.hours.to_s.rjust(2, '0')
|
||||||
|
@io << ':' << timestamp.minutes.to_s.rjust(2, '0')
|
||||||
|
@io << ':' << timestamp.seconds.to_s.rjust(2, '0')
|
||||||
|
@io << '.' << timestamp.milliseconds.to_s.rjust(3, '0')
|
||||||
|
end
|
||||||
|
|
||||||
|
def document(setting_fields : Hash(String, String)? = nil, &)
|
||||||
|
@io << "WEBVTT\n"
|
||||||
|
|
||||||
|
if setting_fields
|
||||||
|
setting_fields.each do |name, value|
|
||||||
|
@io << "#{name}: #{value}\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@io << '\n'
|
||||||
|
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns the resulting `String` of writing WebVTT to the yielded WebVTT::Builder
|
||||||
|
#
|
||||||
|
# ```
|
||||||
|
# string = WebVTT.build do |io|
|
||||||
|
# vtt.line(Time::Span.new(seconds: 1), Time::Span.new(seconds: 2), "Line 1")
|
||||||
|
# vtt.line(Time::Span.new(seconds: 2), Time::Span.new(seconds: 3), "Line 2")
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# string # => "WEBVTT\n\n00:00:01.000 --> 00:00:02.000\nLine 1\n\n00:00:02.000 --> 00:00:03.000\nLine 2\n\n"
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# Accepts an optional settings fields hash to add settings attribute to the resulting vtt file.
|
||||||
|
def self.build(setting_fields : Hash(String, String)? = nil, &)
|
||||||
|
String.build do |str|
|
||||||
|
builder = Builder.new(str)
|
||||||
|
builder.document(setting_fields) do
|
||||||
|
yield builder
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue