@omnimedia/omnitool
Version:
open source video processing tools
211 lines (184 loc) • 7.12 kB
text/typescript
import {expect, Science, test} from "@e280/science"
import {O} from "./o.js"
import {Omni} from "./omni.js"
import {Item} from "../parts/item.js"
import {Driver} from "../../driver/driver.js"
import {Datafile} from "../utils/datafile.js"
import {loadVideo} from "../../demo/routines/load-video.js"
import {computeItemDuration} from "../renderers/parts/handy.js"
const workerUrl = new URL("../driver/driver.worker.bundle.min.js", import.meta.url)
export async function setupTest() {
const driver = await Driver.setup({workerUrl})
const omni = new Omni(driver)
const testVideo = await loadVideo("/assets/temp/test.mp4")
const {videoA} = await omni.load({videoA: Datafile.make(testVideo, "test.mp4")})
return {driver, omni, testVideo, videoA}
}
export default Science.suite({
"basic demo": test(async () => {
const driver = await Driver.setup({workerUrl: new URL("../driver/driver.worker.bundle.min.js", import.meta.url)})
const omni = new Omni(driver)
const testVideo = await loadVideo("/assets/temp/test.mp4")
const {videoA} = await omni.load({videoA: Datafile.make(testVideo, "test.mp4")})
const o = new O({timeline: omni.timeline(o => o.sequence())})
const rootItem = o.require<Item.Sequence>(o.timeline.rootId)!
const video = o.video(videoA)
o.addChildren(rootItem, video)
const videoDuration = computeItemDuration(video.id, o.timeline)
const timelineDuration = computeItemDuration(o.timeline.rootId, o.timeline)
expect(videoDuration).is(timelineDuration)
}),
"sequence duration is 3x": test(async () => {
const {omni, videoA} = await setupTest()
const o = new O({timeline: omni.timeline(o => o.sequence(
o.video(videoA),
o.video(videoA),
o.video(videoA),
))})
const timelineDuration = computeItemDuration(o.timeline.rootId, o.timeline)
expect(timelineDuration).is(videoA.duration * 3)
}),
"stack duration is 1x": test(async () => {
const {omni, videoA} = await setupTest()
const o = new O({timeline: omni.timeline(o => o.stack(
o.video(videoA),
o.video(videoA),
o.video(videoA),
))})
const timelineDuration = computeItemDuration(o.timeline.rootId, o.timeline)
expect(timelineDuration).is(videoA.duration)
}),
"nested stack inside sequence": test(async () => {
const {omni, videoA} = await setupTest()
const o = new O({timeline: omni.timeline(o => o.sequence(
o.video(videoA),
o.stack(
o.video(videoA),
o.video(videoA)
),
o.video(videoA),
))})
const timelineDuration = computeItemDuration(o.timeline.rootId, o.timeline)
expect(timelineDuration).is(videoA.duration * 3)
}),
"nested sequence inside stack": test(async () => {
const {omni, videoA} = await setupTest()
const o = new O({timeline: omni.timeline(o => o.stack(
o.video(videoA),
o.sequence(
o.video(videoA),
o.video(videoA)
)
))})
const timelineDuration = computeItemDuration(o.timeline.rootId, o.timeline)
expect(timelineDuration).is(videoA.duration * 2)
}),
"empty timeline duration is 0": test(async () => {
const {omni} = await setupTest()
const o1 = new O({timeline: omni.timeline(o => o.sequence())})
const o2 = new O({timeline: omni.timeline(o => o.stack())})
const duration1 = computeItemDuration(o1.timeline.rootId, o1.timeline)
const duration2 = computeItemDuration(o2.timeline.rootId, o2.timeline)
expect(duration1).is(0)
expect(duration2).is(0)
}),
"transition in a sequence": test(async () => {
const {omni, videoA} = await setupTest()
const transitionDuration = 1000
const o = new O({timeline: omni.timeline(o => o.sequence(
o.video(videoA),
o.transition.fade(transitionDuration),
o.video(videoA)
))})
const timelineDuration = computeItemDuration(o.timeline.rootId, o.timeline)
const expectedDuration = (videoA.duration * 2) + transitionDuration
expect(timelineDuration).is(expectedDuration)
}),
"transition in a stack": test(async () => {
const {omni, videoA} = await setupTest()
const transitionDuration = 1000
const o = new O({timeline: omni.timeline(o => o.stack(
o.video(videoA),
o.transition.fade(transitionDuration),
o.video(videoA)
))})
const timelineDuration = computeItemDuration(o.timeline.rootId, o.timeline)
expect(timelineDuration).is(videoA.duration)
}),
"edge transition takes sequence space": test(async () => {
const {omni, videoA} = await setupTest()
const o = new O({timeline: omni.timeline(o => o.sequence(
o.transition.fade(1000),
o.video(videoA),
o.video(videoA),
o.transition.fade(1000),
))})
const timelineDuration = computeItemDuration(o.timeline.rootId, o.timeline)
expect(timelineDuration).is(videoA.duration * 2 + 2000)
}),
"transition duration can be longer than neighboring clips": test(async () => {
const {omni, videoA} = await setupTest()
const duration = 3000
const o = new O({timeline: omni.timeline(o => o.sequence(
o.video(videoA, {duration}),
o.transition.fade(duration * 2),
o.video(videoA, {duration})
))})
const timelineDuration = computeItemDuration(o.timeline.rootId, o.timeline)
expect(timelineDuration).is(duration * 4)
}),
"multiple transitions": test(async () => {
const {omni, videoA} = await setupTest()
const transitionDuration = 1000
const o = new O({timeline: omni.timeline(o => o.sequence(
o.video(videoA),
o.transition.fade(transitionDuration),
o.video(videoA),
o.transition.fade(transitionDuration),
o.video(videoA)
))})
const timelineDuration = computeItemDuration(o.timeline.rootId, o.timeline)
const expected = (videoA.duration * 3) + (transitionDuration * 2)
expect(timelineDuration).is(expected)
}),
"gap item in a sequence": test(async () => {
const {omni, videoA} = await setupTest()
const gapDuration = 1000
const o = new O({timeline: omni.timeline(o => o.sequence(
o.video(videoA),
o.gap(gapDuration),
o.video(videoA)
))})
const timelineDuration = computeItemDuration(o.timeline.rootId, o.timeline)
const expected = videoA.duration * 2 + gapDuration
expect(timelineDuration).is(expected)
}),
"gap item in a stack": test(async () => {
const {omni, videoA} = await setupTest()
const o = new O({timeline: omni.timeline(o => o.stack(
o.video(videoA),
o.gap(1000),
o.video(videoA)
))})
const timelineDuration = computeItemDuration(o.timeline.rootId, o.timeline)
expect(timelineDuration).is(videoA.duration)
}),
"load media into Omni": test(async () => {
const driver = await Driver.setup({workerUrl})
const omni = new Omni(driver)
const testVideo = await loadVideo("/assets/temp/test.mp4")
const {videoA} = await omni.load({videoA: Datafile.make(testVideo, "test.mp4")})
expect(omni.resources.require(videoA.datafile.checksum.hash)).happy()
}),
"playback seeks to correct time": test(async () => {
const {omni, videoA} = await setupTest()
const o = new O({timeline: omni.timeline(o => o.sequence(
o.video(videoA, {duration: 2000}),
o.gap(500),
o.video(videoA, {duration: 2500})
))})
const playback = await omni.playback(o.timeline)
await playback.seek(1000)
expect(playback.currentTime).is(1000)
})
})