Browse Source

Added VTT previews!

main
Gwen Pasquarello 1 year ago
parent
commit
665f6d865a
  1. 36
      src/editing/Preview.ts
  2. 61
      src/editing/VttIO.ts
  3. 17
      src/editing/edit.main.ts
  4. 21
      src/editing/style.css
  5. 1
      src/index.ts

36
src/editing/Preview.ts

@ -0,0 +1,36 @@
import van from 'vanjs-core'
export function VttPreview(url: string, vtt: string, captionDiv: HTMLDivElement) {
const {video, track, div, button} = van.tags
const overlay = div(
{
class: 'overlay',
id: 'vttPreviewOverlay',
},
div(
button(
{
onclick: (e) => {
e.target.parentElement.parentElement.remove()
captionDiv.removeAttribute('inert')
},
},
'close'
),
video(
{
src: url,
controls: true,
},
track({
kind: 'captions',
default: true,
srclang: 'en',
src: `data:text/vtt;base64,${btoa(vtt)}`,
})
)
)
)
captionDiv.setAttribute('inert', 'true')
van.add(document.body, overlay)
}

61
src/editing/VttIO.ts

@ -1,12 +1,16 @@
import {WebVTTSerializer, WebVTTParser} from 'webvtt-parser'
import {saveAs} from 'file-saver'
import {RBTree} from 'bintrees'
import {Caption} from './Caption'
import {M} from 'vite/dist/node/types.d-aGj9QkWt'
// TODO support some more of the features of VTT
function createVTTCue(id: string, start: number, end: number, text: string) {
function createVTTCue(id: string, cap: Caption) {
let c = {
id: id,
startTime: start,
endTime: end,
text: text,
startTime: cap.start.val,
endTime: cap.end.val,
text: '',
tree: null,
pauseOnExit: false,
direction: 'horizontal',
@ -18,30 +22,51 @@ function createVTTCue(id: string, start: number, end: number, text: string) {
size: 100,
alignment: 'center',
}
c.tree = {
children: [
{
c.tree = {children: []}
cap.lines.forEach((l, i) => {
c.tree.children.push({
type: 'text',
value: i > 0 ? '\n ' : ' ',
})
if (l.val.speaker && l.val.speaker != '') {
c.text = `- ${c.text}<v ${l.val.speaker}>${l.val.text}</v>\n`
c.tree.children.push({
type: 'object',
name: 'v',
value: l.val.speaker,
children: [
{
type: 'text',
value: l.val.text,
},
],
})
} else {
c.text = `${c.text}${l.val.text}\n\n`
c.tree.children.push({
type: 'text',
value: text,
},
],
}
value: l.val.text,
})
}
})
return c
}
export function SaveVtt() {
export function CreateVtt(captions: RBTree<Caption>) {
let cues = []
let i = 0
captions.each((c: Caption) => {
cues.push(createVTTCue(i.toString(), c.start.val, c.end.val, c.text.val))
cues.push(createVTTCue(i.toString(), c))
i++
})
let s = new WebVTTSerializer()
let newVTT = s.serialize(cues)
const vttBlob = new Blob([newVTT], {type: 'text/vtt;charset=utf-8'})
saveAs(vttBlob, 'out.vtt')
return s.serialize(cues)
}
let p = new WebVTTParser()
console.log(p.parse(example))
export function SaveVtt(captions: RBTree<Caption>) {
const vttBlob = new Blob([CreateVtt(captions)], {type: 'text/vtt;charset=utf-8'})
saveAs(vttBlob, 'out.vtt')
}

17
src/editing/edit.main.ts

@ -4,8 +4,9 @@ import {RBTree} from 'bintrees'
import {addCoroutineListener} from './Coro'
//import {SetupVideoControlFunctions} from './VideoPlaybackControl'
import {ReactiveTimecodesEditor, UpdateTimcodeEditor} from './TimestampDisplay'
import {SaveVtt} from './VttIO'
import {CreateVtt, SaveVtt} from './VttIO'
import {captionTextEditor} from './TitleEditor'
import {VttPreview} from './Preview'
export function BuildEditor(
captionDiv: HTMLDivElement,
@ -186,10 +187,22 @@ export function BuildEditor(
titleControls,
button(
{
onclick: SaveVtt,
onclick: () => SaveVtt(captions as RBTree<Caption>),
id: 'SaveVtt',
},
'Done!'
)
)
van.add(
titleControls,
button(
{
onclick: () => {
VttPreview(video.src, CreateVtt(captions as RBTree<Caption>), captionDiv)
},
},
'Preview'
)
)
}

21
src/editing/style.css

@ -90,3 +90,24 @@ th {
.timecodeInput.milliseconds {
width: 3.5em;
}
/*******************************************************************************
* preview overlay
*/
.overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #000a;
display: flex;
justify-content: center;
align-items: center;
}
.overlay > video {
margin: auto;
width: 80%;
max-height: 80%;
background-color: black;
}

1
src/index.ts

@ -6,7 +6,6 @@ import van from 'vanjs-core'
document.getElementById('requiresJS').remove()
;(async () => {
const searchParamters = new URLSearchParams(new URL(document.URL).search)
console.log(searchParamters.get('video_url'))
const url = searchParamters.get('video_url')
? searchParamters.get('video_url')
: await ShowSpash()

Loading…
Cancel
Save