mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-13 14:55:16 +00:00
105 lines
3.1 KiB
TypeScript
105 lines
3.1 KiB
TypeScript
// @vitest-environment node
|
|
|
|
import { describe, expect, it } from 'vitest'
|
|
|
|
import {
|
|
buildSpeechPosterFfmpegArgs,
|
|
speechPosterFilename,
|
|
speechPosterHref,
|
|
speechPosterOffsetSeconds,
|
|
speechPosterTarget,
|
|
} from '@/lib/speechPoster'
|
|
|
|
describe('speechPosterOffsetSeconds', () => {
|
|
it('points at the middle of the speech (intent literal)', () => {
|
|
expect(speechPosterOffsetSeconds(252)).toBe(126)
|
|
expect(speechPosterOffsetSeconds(601)).toBe(300)
|
|
})
|
|
|
|
it('returns null without a usable duration', () => {
|
|
expect(speechPosterOffsetSeconds(0)).toBeNull()
|
|
expect(speechPosterOffsetSeconds(-5)).toBeNull()
|
|
expect(speechPosterOffsetSeconds(null)).toBeNull()
|
|
expect(speechPosterOffsetSeconds(undefined)).toBeNull()
|
|
expect(speechPosterOffsetSeconds(Number.NaN)).toBeNull()
|
|
})
|
|
})
|
|
|
|
describe('speechPosterTarget', () => {
|
|
const coordinates = { eventId: 67091, audioId: 558641, excerptTMs: 1675801808560 }
|
|
|
|
it('joins the Câmara coordinates with the midpoint, stored VOD or not', () => {
|
|
const expected = {
|
|
eventId: 67091,
|
|
audioId: 558641,
|
|
excerptTms: 1675801808560,
|
|
offsetSeconds: 126,
|
|
}
|
|
|
|
expect(speechPosterTarget({ ...coordinates, durationSeconds: 252 })).toEqual(expected)
|
|
expect(
|
|
speechPosterTarget({
|
|
...coordinates,
|
|
durationSeconds: 252,
|
|
vodPlaybackUrl: 'https://vod.camara.leg.br/x',
|
|
}),
|
|
).toEqual(expected)
|
|
})
|
|
|
|
it('is ineligible without any coordinate or without a duration', () => {
|
|
expect(speechPosterTarget({ ...coordinates, durationSeconds: 252, eventId: null })).toBeNull()
|
|
expect(speechPosterTarget({ ...coordinates, durationSeconds: 252, audioId: null })).toBeNull()
|
|
expect(
|
|
speechPosterTarget({ ...coordinates, durationSeconds: 252, excerptTMs: null }),
|
|
).toBeNull()
|
|
expect(speechPosterTarget({ ...coordinates, durationSeconds: 0 })).toBeNull()
|
|
expect(speechPosterTarget({ durationSeconds: 252 })).toBeNull()
|
|
})
|
|
})
|
|
|
|
describe('speechPosterFilename / speechPosterHref', () => {
|
|
it('builds the deterministic cache name and the internal route', () => {
|
|
expect(speechPosterFilename(42)).toBe('speech-poster-42.jpg')
|
|
expect(speechPosterHref(42)).toBe('/campanha/comunicacao/acervo/42/poster')
|
|
})
|
|
})
|
|
|
|
describe('buildSpeechPosterFfmpegArgs', () => {
|
|
it('seeks to the midpoint and takes a single scaled frame', () => {
|
|
const args = buildSpeechPosterFfmpegArgs({
|
|
inputPath: '/tmp/source.mp4',
|
|
outputPath: '/tmp/speech-poster-42.jpg',
|
|
atSeconds: 126.4,
|
|
})
|
|
|
|
expect(args).toEqual([
|
|
'-nostdin',
|
|
'-hide_banner',
|
|
'-y',
|
|
'-ss',
|
|
'126',
|
|
'-i',
|
|
'/tmp/source.mp4',
|
|
'-frames:v',
|
|
'1',
|
|
'-vf',
|
|
'scale=480:-2',
|
|
'-q:v',
|
|
'2',
|
|
'-an',
|
|
'/tmp/speech-poster-42.jpg',
|
|
])
|
|
// The seek is an input option: before `-i`, never after.
|
|
expect(args.indexOf('-ss')).toBeLessThan(args.indexOf('-i'))
|
|
})
|
|
|
|
it('never seeks to a negative instant', () => {
|
|
const args = buildSpeechPosterFfmpegArgs({
|
|
inputPath: 'in.mp4',
|
|
outputPath: 'out.jpg',
|
|
atSeconds: -3,
|
|
})
|
|
|
|
expect(args[args.indexOf('-ss') + 1]).toBe('0')
|
|
})
|
|
})
|