Skip to content

Commit eff9443

Browse files
Add Subtitles Always on Top option (#397)
1 parent a3e0bdc commit eff9443

12 files changed

+388
-214
lines changed

src/bigscreenplayer.js

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ function BigscreenPlayer() {
109109
}
110110
}
111111

112-
function bigscreenPlayerDataLoaded({ media, enableSubtitles, enableAudioDescribed }) {
112+
function bigscreenPlayerDataLoaded({ media, enableSubtitles, subtitlesAlwaysOnTop, enableAudioDescribed }) {
113113
abortSignal.throwIfAborted(AbortStages.DATA_LOADED)
114114

115115
const initialPresentationTime =
@@ -136,14 +136,11 @@ function BigscreenPlayer() {
136136
PlayerComponent.getLiveSupport(),
137137
() => {
138138
_callbacks.playerReady && _callbacks.playerReady()
139-
subtitles = Subtitles(
140-
playerComponent,
141-
enableSubtitles,
142-
playbackElement,
143-
media.subtitleCustomisation,
144-
mediaSources,
145-
callSubtitlesCallbacks
146-
)
139+
subtitles = Subtitles(playerComponent, playbackElement, mediaSources, callSubtitlesCallbacks, {
140+
alwaysOnTop: subtitlesAlwaysOnTop,
141+
autoStart: enableSubtitles,
142+
defaultStyleOpts: media.subtitleCustomisation,
143+
})
147144
}
148145
)
149146
}

src/bigscreenplayer.test.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,11 +209,12 @@ describe("Bigscreen Player", () => {
209209

210210
expect(jest.mocked(Subtitles)).toHaveBeenCalledWith(
211211
expect.any(Object),
212-
true,
213212
expect.any(HTMLDivElement),
214-
undefined,
215213
expect.any(Object),
216-
expect.any(Function)
214+
expect.any(Function),
215+
expect.objectContaining({
216+
autoStart: true,
217+
})
217218
)
218219
})
219220

src/subtitles/embeddedsubtitles.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Utils from "../utils/playbackutils"
44
import DebugTool from "../debugger/debugtool"
55
import Plugins from "../plugins"
66

7-
function EmbeddedSubtitles(mediaPlayer, autoStart, parentElement, _mediaSources, defaultStyleOpts) {
7+
function EmbeddedSubtitles(mediaPlayer, parentElement, { autoStart = false, defaultStyleOpts = {} } = {}) {
88
let exampleSubtitlesElement
99
let imscRenderOpts = transformStyleOptions(defaultStyleOpts)
1010
let subtitlesEnabled = false
@@ -43,6 +43,7 @@ function EmbeddedSubtitles(mediaPlayer, autoStart, parentElement, _mediaSources,
4343
exampleSubtitlesElement.style.right = `${rightPixels}px`
4444
exampleSubtitlesElement.style.bottom = `${bottomPixels}px`
4545
exampleSubtitlesElement.style.left = `${leftPixels}px`
46+
4647
parentElement.appendChild(exampleSubtitlesElement)
4748

4849
renderSubtitle(exampleXml, 1, exampleSubtitlesElement, exampleStyle, renderHeight, renderWidth)

src/subtitles/embeddedsubtitles.test.js

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,7 @@ describe("Embedded Subtitles", () => {
7272

7373
describe("construction", () => {
7474
it("returns the correct interface", () => {
75-
const autoStart = false
76-
77-
subtitles = EmbeddedSubtitles(mockMediaPlayer, autoStart, targetElement, null, {})
75+
subtitles = EmbeddedSubtitles(mockMediaPlayer, targetElement)
7876

7977
expect(subtitles).toEqual(
8078
expect.objectContaining({
@@ -91,7 +89,10 @@ describe("Embedded Subtitles", () => {
9189
it("triggers the MSE player to enable subtitles immediately when autoplay is true", () => {
9290
const autoStart = true
9391

94-
subtitles = EmbeddedSubtitles(mockMediaPlayer, autoStart, targetElement, null, {})
92+
subtitles = EmbeddedSubtitles(mockMediaPlayer, targetElement, {
93+
autoStart,
94+
defaultStyleOpts: {},
95+
})
9596

9697
progressTime(1.5)
9798
expect(mockMediaPlayer.setSubtitles).toHaveBeenCalledTimes(1)
@@ -100,7 +101,7 @@ describe("Embedded Subtitles", () => {
100101
it("does not trigger the MSE player to enable subtitles immediately when autoplay is false", () => {
101102
const autoStart = false
102103

103-
subtitles = EmbeddedSubtitles(mockMediaPlayer, autoStart, targetElement, null, {})
104+
subtitles = EmbeddedSubtitles(mockMediaPlayer, targetElement, { autoStart })
104105

105106
progressTime(1.5)
106107
expect(mockMediaPlayer.setSubtitles).toHaveBeenCalledTimes(0)
@@ -111,9 +112,11 @@ describe("Embedded Subtitles", () => {
111112
it("overrides the subtitles styling metadata with supplied defaults when rendering", () => {
112113
const expectedStyles = { spanBackgroundColorAdjust: { transparent: "black" }, fontFamily: "Arial" }
113114

114-
subtitles = EmbeddedSubtitles(mockMediaPlayer, false, targetElement, null, {
115-
backgroundColour: "black",
116-
fontFamily: "Arial",
115+
subtitles = EmbeddedSubtitles(mockMediaPlayer, targetElement, {
116+
defaultStyleOpts: {
117+
backgroundColour: "black",
118+
fontFamily: "Arial",
119+
},
117120
})
118121

119122
subtitles.start()
@@ -124,7 +127,7 @@ describe("Embedded Subtitles", () => {
124127
})
125128

126129
it("overrides the subtitles styling metadata with supplied custom styles when rendering", () => {
127-
subtitles = EmbeddedSubtitles(mockMediaPlayer, false, targetElement, null, {})
130+
subtitles = EmbeddedSubtitles(mockMediaPlayer, targetElement)
128131

129132
const styleOpts = { size: 0.7, lineHeight: 0.9 }
130133
const expectedOpts = { sizeAdjust: 0.7, lineHeightAdjust: 0.9 }
@@ -147,7 +150,7 @@ describe("Embedded Subtitles", () => {
147150
lineHeightAdjust: 0.9,
148151
}
149152

150-
subtitles = EmbeddedSubtitles(mockMediaPlayer, false, targetElement, null, defaultStyleOpts)
153+
subtitles = EmbeddedSubtitles(mockMediaPlayer, targetElement, { defaultStyleOpts })
151154

152155
mockMediaPlayer.getCurrentTime.mockReturnValueOnce(1)
153156

@@ -161,7 +164,7 @@ describe("Embedded Subtitles", () => {
161164
const defaultStyleOpts = { backgroundColour: "black", fontFamily: "Arial" }
162165
const customStyleOpts = { size: 0.7, lineHeight: 0.9 }
163166

164-
subtitles = EmbeddedSubtitles(mockMediaPlayer, false, targetElement, null, defaultStyleOpts)
167+
subtitles = EmbeddedSubtitles(mockMediaPlayer, targetElement, { defaultStyleOpts })
165168

166169
mockMediaPlayer.getCurrentTime.mockReturnValueOnce(1)
167170

@@ -179,7 +182,7 @@ describe("Embedded Subtitles", () => {
179182

180183
describe("example rendering", () => {
181184
it("should call fromXML, generate and render when renderExample is called", () => {
182-
subtitles = EmbeddedSubtitles(mockMediaPlayer, false, targetElement, null, {})
185+
subtitles = EmbeddedSubtitles(mockMediaPlayer, targetElement)
183186

184187
subtitles.renderExample("", {}, {})
185188

@@ -189,7 +192,7 @@ describe("Embedded Subtitles", () => {
189192
})
190193

191194
it("should call renderHTML with a preview element with the correct structure when no position info", () => {
192-
subtitles = EmbeddedSubtitles(mockMediaPlayer, false, targetElement, null, {})
195+
subtitles = EmbeddedSubtitles(mockMediaPlayer, targetElement)
193196

194197
let exampleSubsElement = null
195198
let height = null
@@ -215,7 +218,7 @@ describe("Embedded Subtitles", () => {
215218
})
216219

217220
it("should call renderHTML with a preview element with the correct structure when there is position info", () => {
218-
subtitles = EmbeddedSubtitles(mockMediaPlayer, false, targetElement, null, {})
221+
subtitles = EmbeddedSubtitles(mockMediaPlayer, targetElement)
219222

220223
let exampleSubsElement = null
221224
let height = null

src/subtitles/imscsubtitles.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@ import findSegmentTemplate from "../utils/findtemplate"
99
const SEGMENTS_BUFFER_SIZE = 3
1010
const LOAD_ERROR_COUNT_MAX = 3
1111

12-
function IMSCSubtitles(mediaPlayer, autoStart, parentElement, mediaSources, defaultStyleOpts) {
12+
function IMSCSubtitles(
13+
mediaPlayer,
14+
parentElement,
15+
mediaSources,
16+
{ alwaysOnTop = false, autoStart = false, defaultStyleOpts = {} } = {}
17+
) {
1318
let imscRenderOpts = transformStyleOptions(defaultStyleOpts)
1419
let currentSegmentRendered = {}
1520
let loadErrorCount = 0
@@ -19,9 +24,7 @@ function IMSCSubtitles(mediaPlayer, autoStart, parentElement, mediaSources, defa
1924
let currentSubtitlesElement
2025
let updateInterval
2126

22-
if (autoStart) {
23-
start()
24-
}
27+
if (autoStart) start()
2528

2629
function hasOffset() {
2730
const { presentationTimeOffsetInMilliseconds } = mediaSources.time()
@@ -176,7 +179,9 @@ function IMSCSubtitles(mediaPlayer, autoStart, parentElement, mediaSources, defa
176179

177180
// Opts: { backgroundColour: string (css colour, hex), fontFamily: string , size: number, lineHeight: number }
178181
function transformStyleOptions(opts) {
179-
if (opts === undefined) return
182+
if (opts === undefined || Object.keys(opts).length === 0) {
183+
return {}
184+
}
180185

181186
const customStyles = {}
182187

@@ -243,6 +248,9 @@ function IMSCSubtitles(mediaPlayer, autoStart, parentElement, mediaSources, defa
243248
currentSubtitlesElement = document.createElement("div")
244249
currentSubtitlesElement.id = "bsp_subtitles"
245250
currentSubtitlesElement.style.position = "absolute"
251+
252+
if (alwaysOnTop) currentSubtitlesElement.style.zIndex = 2147483647
253+
246254
parentElement.appendChild(currentSubtitlesElement)
247255

248256
renderSubtitle(
@@ -280,6 +288,9 @@ function IMSCSubtitles(mediaPlayer, autoStart, parentElement, mediaSources, defa
280288
exampleSubtitlesElement.style.right = `${rightPixels}px`
281289
exampleSubtitlesElement.style.bottom = `${bottomPixels}px`
282290
exampleSubtitlesElement.style.left = `${leftPixels}px`
291+
292+
if (alwaysOnTop) exampleSubtitlesElement.style.zIndex = 2147483647
293+
283294
parentElement.appendChild(exampleSubtitlesElement)
284295

285296
renderSubtitle(exampleXml, 1, exampleSubtitlesElement, exampleStyle, renderHeight, renderWidth)

0 commit comments

Comments
 (0)