add customm cue handler
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import React, {useEffect, useRef, useState} from 'react'
|
import React, {useEffect, useRef, useState} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import Hls from 'hls.js'
|
import Hls, {CuesInterface} from 'hls.js'
|
||||||
|
|
||||||
import {atoms as a} from '#/alf'
|
import {atoms as a} from '#/alf'
|
||||||
import {Controls} from './VideoWebControls'
|
import {Controls} from './VideoWebControls'
|
||||||
@@ -27,7 +27,7 @@ export function VideoEmbedInner({
|
|||||||
if (!ref.current) return
|
if (!ref.current) return
|
||||||
if (!Hls.isSupported()) throw new HLSUnsupportedError()
|
if (!Hls.isSupported()) throw new HLSUnsupportedError()
|
||||||
|
|
||||||
const hls = new Hls({capLevelToPlayerSize: true})
|
const hls = new Hls({capLevelToPlayerSize: true, cueHandler})
|
||||||
hlsRef.current = hls
|
hlsRef.current = hls
|
||||||
|
|
||||||
hls.attachMedia(ref.current)
|
hls.attachMedia(ref.current)
|
||||||
@@ -91,3 +91,82 @@ export class HLSUnsupportedError extends Error {
|
|||||||
super('HLS is not supported')
|
super('HLS is not supported')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// copy-pasted from https://github.com/dailymotion/hls.js/blob/master/src/utils/cues.js
|
||||||
|
//
|
||||||
|
// modified to change the line calculation for Firefox - I've annotated the change
|
||||||
|
const cueHandler: CuesInterface = {
|
||||||
|
newCue: (track, startTime, endTime, captionScreen) => {
|
||||||
|
let row
|
||||||
|
let cue
|
||||||
|
let indenting
|
||||||
|
let indent
|
||||||
|
let text
|
||||||
|
let VTTCue = window.VTTCue || window.TextTrackCue
|
||||||
|
|
||||||
|
const cues = []
|
||||||
|
|
||||||
|
for (let r = 0; r < captionScreen.rows.length; r++) {
|
||||||
|
row = captionScreen.rows[r]
|
||||||
|
indenting = true
|
||||||
|
indent = 0
|
||||||
|
text = ''
|
||||||
|
|
||||||
|
if (!row.isEmpty()) {
|
||||||
|
for (let c = 0; c < row.chars.length; c++) {
|
||||||
|
if (row.chars[c].uchar.match(/\s/) && indenting) {
|
||||||
|
indent++
|
||||||
|
} else {
|
||||||
|
text += row.chars[c].uchar
|
||||||
|
indenting = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// To be used for cleaning-up orphaned roll-up captions
|
||||||
|
row.cueStartTime = startTime
|
||||||
|
|
||||||
|
// Give a slight bump to the endTime if it's equal to startTime to avoid a SyntaxError in IE
|
||||||
|
if (startTime === endTime) {
|
||||||
|
endTime += 0.0001
|
||||||
|
}
|
||||||
|
|
||||||
|
cue = new VTTCue(startTime, endTime, fixLineBreaks(text.trim()))
|
||||||
|
|
||||||
|
if (indent >= 16) {
|
||||||
|
indent--
|
||||||
|
} else {
|
||||||
|
indent++
|
||||||
|
}
|
||||||
|
|
||||||
|
// VTTCue.line get's flakey when using controls, so let's now include line 13&14
|
||||||
|
// also, drop line 1 since it's to close to the top
|
||||||
|
if (navigator.userAgent.match(/Firefox\//)) {
|
||||||
|
cue.line = -2
|
||||||
|
} else {
|
||||||
|
cue.line = r > 7 ? r - 2 : r + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
cue.align = 'left'
|
||||||
|
// Clamp the position between 0 and 100 - if out of these bounds, Firefox throws an exception and captions break
|
||||||
|
cue.position = Math.max(
|
||||||
|
0,
|
||||||
|
Math.min(
|
||||||
|
100,
|
||||||
|
100 * (indent / 32) +
|
||||||
|
(navigator.userAgent.match(/Firefox\//) ? 50 : 0),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
// modified - they had a type error
|
||||||
|
cues.push(cue)
|
||||||
|
if (track) {
|
||||||
|
track.addCue(cue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cues
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
function fixLineBreaks(input: string) {
|
||||||
|
return input.replace(/<br(?: \/)?>/gi, '\n')
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user