Display multiple captions at once
This commit is contained in:
parent
9a0ffa4710
commit
f6ea8c441e
4 changed files with 125 additions and 85 deletions
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"rules": {
|
||||
"unused-variable": "error"
|
||||
}
|
||||
}
|
||||
"rules": {
|
||||
"unused-variable": "warn"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import "pkg:/source/api/baserequest.bs"
|
||||
import "pkg:/source/enums/MediaPlaybackState.bs"
|
||||
import "pkg:/source/enums/String.bs"
|
||||
import "pkg:/source/utils/config.bs"
|
||||
|
||||
sub init()
|
||||
|
|
@ -95,32 +96,102 @@ end function
|
|||
|
||||
|
||||
sub updateCaption()
|
||||
m.top.currentCaption = []
|
||||
if LCase(m.top.playerState) = "playingon"
|
||||
m.top.currentPos = m.top.currentPos + 100
|
||||
texts = []
|
||||
captionStyles = {}
|
||||
for each entry in m.captionList
|
||||
if entry["start"] <= m.top.currentPos and m.top.currentPos < entry["end"]
|
||||
captionStyles = entry["styles"]
|
||||
t = m.tags.replaceAll(entry["text"], "")
|
||||
texts.push(t)
|
||||
end if
|
||||
end for
|
||||
labels = []
|
||||
for each text in texts
|
||||
labels.push(newlabel (text))
|
||||
end for
|
||||
lines = newLayoutGroup(labels)
|
||||
rect = newRect(lines)
|
||||
m.top.currentCaption = [rect, lines]
|
||||
|
||||
m.top.captionStyles = captionStyles
|
||||
else if LCase(m.top.playerState.right(1)) = "w"
|
||||
if LCase(m.top.playerState.right(1)) = "w"
|
||||
m.top.playerState = m.top.playerState.left(len (m.top.playerState) - 1)
|
||||
return
|
||||
end if
|
||||
|
||||
m.top.currentCaption = []
|
||||
|
||||
if not isStringEqual(m.top.playerState, "playingon") then return
|
||||
|
||||
m.top.currentPos = m.top.currentPos + 100
|
||||
captions = []
|
||||
|
||||
for each entry in m.captionList
|
||||
if entry["start"] <= m.top.currentPos and m.top.currentPos < entry["end"]
|
||||
|
||||
labels = []
|
||||
for each text in entry["text"]
|
||||
labels.push(newlabel(text))
|
||||
end for
|
||||
|
||||
lines = newLayoutGroup(labels)
|
||||
rect = newRect(lines)
|
||||
|
||||
finalStyles = prepareStyles(entry["styles"], rect)
|
||||
lines.translation = finalStyles.translation
|
||||
|
||||
rectxy = lines.BoundingRect()
|
||||
rect.translation = [finalStyles.translation[0], finalStyles.translation[1] - (rectxy.height / 2)]
|
||||
|
||||
captions.push([rect, lines])
|
||||
end if
|
||||
end for
|
||||
|
||||
m.top.currentCaption = captions
|
||||
end sub
|
||||
|
||||
function prepareStyles(styles as object, rect) as object
|
||||
captionStyles = styles
|
||||
finalStyles = { translation: [960, 1020] }
|
||||
|
||||
verticalPosition = 1020
|
||||
|
||||
if not isValidAndNotEmpty(captionStyles)
|
||||
return finalStyles
|
||||
end if
|
||||
|
||||
captionLine = chainLookupReturn(captionStyles, "line", string.EMPTY)
|
||||
|
||||
' Line
|
||||
if not isStringEqual(captionLine, string.EMPTY)
|
||||
captionLineHeight = rect.BoundingRect().height
|
||||
verticalPosition = processLineCue(captionLine, captionLineHeight)
|
||||
end if
|
||||
|
||||
finalStyles.translation = [960, verticalPosition]
|
||||
|
||||
return finalStyles
|
||||
end function
|
||||
|
||||
function processLineCue(captionLine as string, captionLineHeight as float) as integer
|
||||
' A percentage
|
||||
if captionLine.Instr("%") <> -1
|
||||
calculatedPosition = 1080 * (val(captionLine) / 100)
|
||||
calculatedPosition += captionLineHeight
|
||||
|
||||
if calculatedPosition > 1020
|
||||
calculatedPosition = 1020
|
||||
end if
|
||||
|
||||
return calculatedPosition
|
||||
end if
|
||||
|
||||
' Note: Non-numeric values are treated as 0
|
||||
lineValue = val(captionLine)
|
||||
|
||||
' A positive line value. Count from the top
|
||||
if lineValue >= 0
|
||||
calculatedPosition = (lineValue + 1) * captionLineHeight
|
||||
|
||||
if calculatedPosition > 1020
|
||||
calculatedPosition = 1020
|
||||
end if
|
||||
|
||||
return calculatedPosition
|
||||
end if
|
||||
|
||||
' A negative line value. Count from the bottom
|
||||
calculatedPosition = 1080 - Abs((lineValue + 1) * captionLineHeight)
|
||||
|
||||
if calculatedPosition < 0
|
||||
calculatedPosition = 0
|
||||
end if
|
||||
|
||||
return calculatedPosition
|
||||
end function
|
||||
|
||||
function isTime(text)
|
||||
return text.right(1) = chr(31)
|
||||
end function
|
||||
|
|
@ -158,20 +229,40 @@ function parseVTT(lines)
|
|||
curEnd = -1
|
||||
entries = []
|
||||
|
||||
currentLine = []
|
||||
entry = {}
|
||||
|
||||
isNewLine = false
|
||||
|
||||
for i = 0 to lines.count() - 1
|
||||
if isTime(lines[i])
|
||||
currentLine = []
|
||||
|
||||
curStart = toMs(lines[i])
|
||||
lineData = extractStyles(lines[i + 1])
|
||||
curEnd = toMs(lineData.LookupCI("endTimestamp"))
|
||||
curstyles = chainLookup(lineData, "styles")
|
||||
entry = { "start": curStart, "end": curEnd, "styles": curstyles }
|
||||
isNewLine = true
|
||||
|
||||
i += 1
|
||||
else if curStart <> -1
|
||||
continue for
|
||||
end if
|
||||
|
||||
if isNewLine
|
||||
trimmed = lines[i].trim()
|
||||
if trimmed <> chr(0)
|
||||
entry = { "start": curStart, "end": curEnd, "text": trimmed, "styles": curstyles }
|
||||
finalText = m.tags.replaceAll(trimmed, "")
|
||||
|
||||
if isStringEqual(finalText, string.EMPTY)
|
||||
entry.AddReplace("text", currentLine)
|
||||
entries.push(entry)
|
||||
isNewLine = false
|
||||
else
|
||||
currentLine.push(finalText)
|
||||
end if
|
||||
|
||||
end if
|
||||
end for
|
||||
|
||||
return entries
|
||||
end function
|
||||
|
|
|
|||
|
|
@ -384,7 +384,6 @@ sub onAllowCaptionsChange()
|
|||
m.captionGroup = m.top.findNode("captionGroup")
|
||||
m.captionGroup.createchildren(9, "LayoutGroup")
|
||||
m.captionTask = createObject("roSGNode", "captionTask")
|
||||
m.captionTask.observeField("captionStyles", "updateCaptionStyles")
|
||||
m.captionTask.observeField("currentCaption", "updateCaption")
|
||||
m.captionTask.observeField("useThis", "checkCaptionMode")
|
||||
m.top.observeField("subtitleTrack", "loadCaption")
|
||||
|
|
@ -416,63 +415,13 @@ sub toggleCaption()
|
|||
end if
|
||||
end sub
|
||||
|
||||
sub updateCaptionStyles()
|
||||
captionStyles = m.captionTask.captionStyles
|
||||
if not isValidAndNotEmpty(captionStyles)
|
||||
m.captionGroup.translation = [960, 1020]
|
||||
end if
|
||||
|
||||
captionLine = chainLookupReturn(captionStyles, "line", string.EMPTY)
|
||||
|
||||
' Line
|
||||
if not isStringEqual(captionLine, string.EMPTY)
|
||||
' A percentage
|
||||
if captionLine.Instr("%") <> -1
|
||||
calculatedPosition = 1080 * (val(captionLine) / 100)
|
||||
calculatedPosition += m.captionGroup.BoundingRect().height
|
||||
|
||||
if calculatedPosition > 1020
|
||||
calculatedPosition = 1020
|
||||
end if
|
||||
|
||||
m.captionGroup.translation = [960, calculatedPosition]
|
||||
return
|
||||
end if
|
||||
|
||||
' Note: Non-numeric values are treated as 0
|
||||
lineValue = val(captionLine)
|
||||
|
||||
' A positive line value. Count from the top
|
||||
if lineValue >= 0
|
||||
calculatedPosition = (lineValue + 1) * m.captionGroup.BoundingRect().height
|
||||
|
||||
if calculatedPosition > 1020
|
||||
calculatedPosition = 1020
|
||||
end if
|
||||
|
||||
m.captionGroup.translation = [960, calculatedPosition]
|
||||
return
|
||||
end if
|
||||
|
||||
' A negative line value. Count from the bottom
|
||||
calculatedPosition = 1080 - Abs((lineValue + 1) * m.captionGroup.BoundingRect().height)
|
||||
|
||||
if calculatedPosition < 0
|
||||
calculatedPosition = 0
|
||||
end if
|
||||
|
||||
m.captionGroup.translation = [960, calculatedPosition]
|
||||
return
|
||||
end if
|
||||
|
||||
' No styles passed, reset to default position
|
||||
m.captionGroup.translation = [960, 1020]
|
||||
end sub
|
||||
|
||||
' Removes old subtitle lines and adds new subtitle lines
|
||||
sub updateCaption()
|
||||
m.captionGroup.removeChildrenIndex(m.captionGroup.getChildCount(), 0)
|
||||
m.captionGroup.appendChildren(m.captionTask.currentCaption)
|
||||
|
||||
for each caption in m.captionTask.currentCaption
|
||||
m.captionGroup.appendChildren(caption)
|
||||
end for
|
||||
end sub
|
||||
|
||||
' Event handler for when selectedSubtitle changes
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
</interface>
|
||||
|
||||
<children>
|
||||
<Group id="captionGroup" translation="[960,1020]" />
|
||||
<Group id="captionGroup" translation="[0,0]" />
|
||||
<timer id="playbackTimer" repeat="true" duration="30" />
|
||||
<timer id="bufferCheckTimer" repeat="true" />
|
||||
<OSD id="osd" visible="false" inactiveTimeout="5" />
|
||||
|
|
|
|||
Loading…
Reference in a new issue