Skip to content

Commit

Permalink
Made VTT files left|right|none|centre alignment aware and included st…
Browse files Browse the repository at this point in the history
…yling for lines with spaces at the start
  • Loading branch information
hurdlea committed Jun 24, 2020
1 parent 7b2cad0 commit e140b12
Show file tree
Hide file tree
Showing 7 changed files with 5,619 additions and 5,573 deletions.
70 changes: 56 additions & 14 deletions src/au/com/foxtel/product/subtitleTools/CaptionLine.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,43 @@ import java.util.regex.Matcher


class CaptionLine {
Boolean empty = true

enum LineAlignment {
NONE(0), LEFT(1), CENTRE(2), RIGHT(3)
private int value
private static Map map = new HashMap<>()

private LineAlignment(int value) {
this.value = value
}

static {
for (LineAlignment alignment : values()) {
map.put(alignment.value, alignment)
}
}

static LineAlignment valueOf(int alignment) {
return (LineAlignment) map.get(alignment)
}

int getValue() {
value
}
}


public LineAlignment align = LineAlignment.CENTRE
public int charStart = 0

int row
ArrayList<LineFormat> text = new ArrayList<LineFormat>()
String[] ebuColours = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white']
private ArrayList<LineFormat> text = new ArrayList<LineFormat>()
private String[] ebuColours = ['black', 'red', 'lime', 'yellow', 'blue', 'magenta', 'cyan', 'white']

def parseEbuText(int row, ArrayList<Byte> line)
{
this.row = row
def format = new LineFormat()
LineFormat format = new LineFormat()
boolean backgroundChange = false

line.each {
Expand Down Expand Up @@ -63,6 +91,16 @@ class CaptionLine {
if (!format.text.trim().empty) {
this.text.add(format)
}

if (this.text.size() > 0) {
String text = this.text[0].text
Matcher m
if(m = text =~ /(\s+)(.+)/) {
this.charStart = m.group(1).size()
this.text[0].text = m.group(2)
//println("Row: ${this.row} Align: ${align} Offset: ${this.charStart} ${m.group(2)}")
}
}
}

String toString()
Expand Down Expand Up @@ -92,26 +130,30 @@ class CaptionLine {
}
}

String toVTT()
String toVTT(int start)
{
def output = ""
boolean first_unit = true
String output = ""

text.each {
String caption = it.text

// Trim any leading spaces
def m
if ((m = it.text =~ /(\s*)(.+)/)) {
caption = m.group(2)

if (align == LineAlignment.NONE && first_unit) {
int length = this.charStart - start
if (length > 1) {
output += "<c.transparent.bg_transparent>" + "." * length + "</c>"
}
}

if (it.colour != "white") {
output += "<c." + it.colour + ">" + caption + "</c>"
} else {
output += caption
}
output += "\n"
first_unit = false
}

output += "\n"

return output
}

Expand Down
47 changes: 43 additions & 4 deletions src/au/com/foxtel/product/subtitleTools/CaptionMessage.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,27 @@ package au.com.foxtel.product.subtitleTools

import groovy.xml.MarkupBuilder

import java.util.stream.Stream

class CaptionMessage {
def lines = new ArrayList<CaptionLine>()
int startOfMessage = 0
int endOfMessage = 0

CaptionLine.LineAlignment align

void ebuTextField(StlTtiBlock message)
{
int row = message.verticalPosition
startOfMessage = message.timecodeIn
endOfMessage = message.timecodeOut
align = CaptionLine.LineAlignment.valueOf(message.justificationCode)

def rows = splitLines(message.textField)

rows.each {
if (!it.isEmpty()) {
CaptionLine line = new CaptionLine()
line.align = align
line.parseEbuText(row, it)
if (!line.text.empty) {
this.lines.add(line)
Expand Down Expand Up @@ -89,14 +94,48 @@ class CaptionMessage {
String toVTT(int offset)
{
String output = ""

int start = 0

if (align == CaptionLine.LineAlignment.NONE) {
start = 1000
// Determine the lowest start position of the text
lines.each {
if (start > it.charStart) {
start = it.charStart
}
}
}

//println("Start: ${start} ${lines.toString()}")
String formatting

switch (align) {
case CaptionLine.LineAlignment.NONE:
long position = Math.round(((5 + start)/50) * 100)
formatting = "align:left "
formatting += "position:${position}%,line-left "
formatting += "size:${80 - position}%"
break

case CaptionLine.LineAlignment.LEFT:
formatting = 'align:left size:80% position:10%,line-left%'
break

case CaptionLine.LineAlignment.RIGHT:
formatting = 'align:right size:80% position:90%'
break

default:
formatting = 'align:middle position:50% size:80%'
}

// Render the text
output += framesToIsoTime(startOfMessage + offset) + " --> " +
framesToIsoTime(endOfMessage + offset) + " " +
"line:" + Math.round(((lines[0].row + 3) / 30) * 100) + "% " +
"align:middle position:50% size:80%\n"
"${formatting}\n"
lines.each {
output += it.toVTT()
output += it.toVTT(start)
}
output += "\n"

Expand Down
83 changes: 81 additions & 2 deletions src/au/com/foxtel/product/subtitleTools/ConvertSTL.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,87 @@ class ConvertSTL {
static String getVTT(ArrayList captions, int offset = 0)
{
def output = ""

output += "WEBVTT\n\n"
String style = '''\
STYLE
::cue {
line-height: 5.33vh;
font-size: 4.1vh;
font-family: monospace;
font-style: normal;
font-weight: normal;
background-color: black;
color: white;
}
::cue(c.transparent) {
color: transparent;
}
::cue(c.semi-transparent) {
color: rgba(0, 0, 0, 0.5);
}
::cue(c.opaque) {
color: rgba(0, 0, 0, 1);
}
::cue(c.blink) {
text-decoration: blink;
}
::cue(c.white) {
color: white;
}
::cue(c.red) {
color: red;
}
::cue(c.green) {
color: lime;
}
::cue(c.blue) {
color: blue;
}
::cue(c.cyan) {
color: cyan;
}
::cue(c.yellow) {
color: yellow;
}
::cue(c.magenta) {
color: magenta;
}
::cue(c.bg_transparent) {
background-color: transparent;
}
::cue(c.bg_semi-transparent) {
background-color: rgba(0, 0, 0, 0.5);
}
::cue(c.bg_opaque) {
background-color: rgba(0, 0, 0, 1);
}
::cue(c.bg_white) {
background-color: white;
}
::cue(c.bg_green) {
background-color: lime;
}
::cue(c.bg_blue) {
background-color: blue;
}
::cue(c.bg_cyan) {
background-color: cyan;
}
::cue(c.bg_red) {
background-color: red;
}
::cue(c.bg_yellow) {
background-color: yellow;
}
::cue(c.bg_magenta) {
background-color: magenta;
}
::cue(c.bg_black) {
background-color: black;
}
'''
output += "WEBVTT\n\n" + style

captions.each {
output += it.toVTT(offset)
}
Expand Down
3 changes: 2 additions & 1 deletion src/au/com/foxtel/product/subtitleTools/stlTtiBlock.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ class StlTtiBlock {
System.arraycopy(this.textField, 0, buffer, 0, this.textField.length)
System.arraycopy(record, 16, buffer, this.textField.length, 112)
this.textField = buffer
//println("Multiple text blocks ${textField}")

//println("Multiple text blocks ${makePrintable(buffer)}")
} else {
this.textField = record[16..127] as byte[]
}
Expand Down
Loading

0 comments on commit e140b12

Please sign in to comment.