2023-02-06 09:09:42 +00:00
|
|
|
import * as DOMPurify from 'dompurify'
|
|
|
|
|
2020-08-21 12:46:25 +00:00
|
|
|
export function buildPlayer (video, player, videojs) {
|
|
|
|
window.videojs = videojs
|
|
|
|
require('videojs-overlay')
|
|
|
|
|
|
|
|
const fieldName = 'player-annotations'
|
|
|
|
|
|
|
|
if (!video.pluginData || !video.pluginData[fieldName]) return
|
|
|
|
|
|
|
|
const annotationsText = video.pluginData[fieldName]
|
|
|
|
|
2023-02-06 09:09:42 +00:00
|
|
|
const annotations = parseAnnotations(video, annotationsText)
|
2020-08-21 12:46:25 +00:00
|
|
|
if (!annotations) return
|
|
|
|
|
|
|
|
console.log('Will inject annotations in player.', annotations)
|
|
|
|
|
|
|
|
player.overlay({
|
|
|
|
overlays: annotations
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-02-06 09:09:42 +00:00
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
function parseAnnotations (video, annotationsText) {
|
2020-08-24 08:12:36 +00:00
|
|
|
const splitted = annotationsText.split(/\n\r?\n\r?/)
|
2023-02-06 09:09:42 +00:00
|
|
|
.filter(line => !!line)
|
2020-08-21 12:46:25 +00:00
|
|
|
|
2023-02-06 09:09:42 +00:00
|
|
|
return splitted.map(s => buildAnnotation(video, s))
|
2020-08-21 12:46:25 +00:00
|
|
|
.filter(a => !!a)
|
|
|
|
}
|
|
|
|
|
2023-02-06 09:09:42 +00:00
|
|
|
function buildAnnotation (video, text) {
|
2020-08-21 12:46:25 +00:00
|
|
|
const splitted = text.split('\n')
|
|
|
|
if (splitted.length < 2) {
|
2023-02-06 09:09:42 +00:00
|
|
|
console.error('Cannot build annotation "%s".', text)
|
2020-08-21 12:46:25 +00:00
|
|
|
return undefined
|
|
|
|
}
|
|
|
|
|
|
|
|
const timestampsText = splitted.shift()
|
|
|
|
const timestamps = buildTimestamps(timestampsText)
|
|
|
|
if (!timestamps) {
|
2023-02-06 09:09:42 +00:00
|
|
|
console.error('Cannot build timestamp "%s" of "%s".', timestampsText, text)
|
2020-08-21 12:46:25 +00:00
|
|
|
return undefined
|
|
|
|
}
|
|
|
|
|
|
|
|
let options
|
|
|
|
|
|
|
|
if (splitted[0] && (splitted[0] || '').startsWith('options:')) {
|
|
|
|
const optionsText = splitted[0]
|
|
|
|
options = buildOptions(optionsText)
|
|
|
|
|
|
|
|
if (!options) {
|
2023-02-06 09:09:42 +00:00
|
|
|
console.error('Cannot build options "%s" of "%s".', optionsText, text)
|
2020-08-21 12:46:25 +00:00
|
|
|
} else {
|
|
|
|
splitted.shift()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const content = splitted.join('\n')
|
|
|
|
|
|
|
|
const align = options && options.align ? options.align : 'top-right'
|
|
|
|
|
2020-08-21 13:04:10 +00:00
|
|
|
const result = {
|
2020-08-21 12:46:25 +00:00
|
|
|
align,
|
2023-02-06 09:09:42 +00:00
|
|
|
content: DOMPurify.sanitize(content)
|
2020-08-21 12:46:25 +00:00
|
|
|
}
|
2020-08-21 13:04:10 +00:00
|
|
|
|
|
|
|
result.start = timestamps.start || 0
|
|
|
|
result.end = timestamps.end || video.duration
|
|
|
|
|
|
|
|
return result
|
2020-08-21 12:46:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function buildTimestamps (text) {
|
|
|
|
const result = text.split('-->')
|
|
|
|
|
|
|
|
if (result.length !== 2) return undefined
|
|
|
|
|
|
|
|
const startText = result[0].trim()
|
|
|
|
const endText = result[1].trim()
|
|
|
|
|
|
|
|
if (!startText && !endText) return undefined
|
|
|
|
|
|
|
|
let start = parseInt(startText)
|
|
|
|
let end = parseInt(endText)
|
|
|
|
|
|
|
|
if (isNaN(start)) start = undefined
|
|
|
|
if (isNaN(end)) end = undefined
|
|
|
|
|
|
|
|
if (!start && !end) return undefined
|
|
|
|
|
|
|
|
return { start, end }
|
|
|
|
}
|
|
|
|
|
|
|
|
function buildOptions (text) {
|
|
|
|
const matchedAlign = text.match(/align=([^ ]+)/)
|
|
|
|
|
|
|
|
if (matchedAlign) {
|
|
|
|
return {
|
|
|
|
align: matchedAlign[1]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return undefined
|
|
|
|
}
|