Compare commits
4 commits
c06273269e
...
de48213dce
Author | SHA1 | Date | |
---|---|---|---|
de48213dce | |||
5bbd505ff6 | |||
dd4bd1d497 | |||
589e235756 |
6 changed files with 71 additions and 11 deletions
|
@ -28,6 +28,9 @@ for (let i = 0; i < numberOfRepeats; i++) {
|
||||||
finalSamples.set(oneSecondChunk, i * sampleRate);
|
finalSamples.set(oneSecondChunk, i * sampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let halfSecondSilence = new Float32Array(sampleRate / 2).fill(0);
|
||||||
|
finalSamples = Float32Array.from([...halfSecondSilence, ...finalSamples]);
|
||||||
|
|
||||||
let finalBuffer = wav.encode([finalSamples], { sampleRate: sampleRate, float: true, bitDepth: 32 });
|
let finalBuffer = wav.encode([finalSamples], { sampleRate: sampleRate, float: true, bitDepth: 32 });
|
||||||
|
|
||||||
fs.writeFileSync(options.output, finalBuffer);
|
fs.writeFileSync(options.output, finalBuffer);
|
||||||
|
|
|
@ -31,16 +31,19 @@ await page.evaluate(async (fps) => {
|
||||||
}, options.fps);
|
}, options.fps);
|
||||||
|
|
||||||
const totalFrames = parseInt(options.fps) * parseInt(options.cycles);
|
const totalFrames = parseInt(options.fps) * parseInt(options.cycles);
|
||||||
|
const half = Math.floor(parseInt(options.fps) / 2);
|
||||||
for (let frame = 0; frame < totalFrames; frame++) {
|
for (let frame = 0; frame < totalFrames; frame++) {
|
||||||
let start = Date.now();
|
let start = Date.now();
|
||||||
await page.evaluate(async (n) => {
|
await page.evaluate(async (n) => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
await window.setFrame(n);
|
await window.setFrame(n);
|
||||||
}, frame);
|
}, frame + half);
|
||||||
const path = `${options.output}/${frame.toString().padStart(Math.log10(totalFrames) + 1, '0')}.png`;
|
const path = `${options.output}/${frame.toString().padStart(Math.log10(totalFrames) + 1, '0')}.png`;
|
||||||
await page.screenshot({ path, omitBackground: true });
|
await page.screenshot({ path, omitBackground: true });
|
||||||
let end = Date.now();
|
let end = Date.now();
|
||||||
console.log(`Captured frame ${frame + 1}/${totalFrames} (took ${end - start}ms)`);
|
console.log(
|
||||||
|
`Captured frame ${frame + half}: ${frame + 1}/${totalFrames} (took ${end - start}ms)`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Done.');
|
console.log('Done.');
|
||||||
|
|
|
@ -3,14 +3,24 @@
|
||||||
export let fps: number;
|
export let fps: number;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="scale">
|
<div class="scale" style="--frame: {frame}; --fps: {fps}">
|
||||||
<div class="labels">
|
<div class="labels">
|
||||||
<div>Video Late</div>
|
<div>Video Late</div>
|
||||||
<div>Audio Late</div>
|
<div>Audio Late</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="zero">
|
||||||
|
<div class="label">0</div>
|
||||||
|
<div class="mark"></div>
|
||||||
|
</div>
|
||||||
<div class="indicator"></div>
|
<div class="indicator"></div>
|
||||||
<div class="ticks">
|
<div class="ticks">
|
||||||
|
<div class="tick"></div>
|
||||||
{#each Array.from({ length: fps }, (_, i) => i) as i}
|
{#each Array.from({ length: fps }, (_, i) => i) as i}
|
||||||
|
<div class="spacer" class:active={i === (frame + fps / 2) % fps}>
|
||||||
|
{#if i % (fps / 10) === 0 && i !== 0 && i !== fps / 2}
|
||||||
|
<div class="label">{(i - fps / 2) * (1000 / fps)}ms</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
<div class="tick"></div>
|
<div class="tick"></div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
@ -48,12 +58,56 @@
|
||||||
|
|
||||||
.ticks {
|
.ticks {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
flex-wrap: wrap;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
& .spacer {
|
||||||
|
position: relative;
|
||||||
|
flex-grow: 1;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: var(--color-active);
|
||||||
|
z-index: 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tick {
|
& .label {
|
||||||
|
position: absolute;
|
||||||
|
top: calc(100% + 2em);
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%) rotate(90deg);
|
||||||
|
|
||||||
|
line-height: 1;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& .tick {
|
||||||
width: 2px;
|
width: 2px;
|
||||||
height: 3vh;
|
height: 5vh;
|
||||||
background: white;
|
background: white;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.zero {
|
||||||
|
position: absolute;
|
||||||
|
top: calc(50% - 5vh * 2.5 / 2);
|
||||||
|
left: calc(50%);
|
||||||
|
width: calc(100% / var(--fps) - 1px);
|
||||||
|
font-size: 2vw;
|
||||||
|
|
||||||
|
& .label {
|
||||||
|
position: absolute;
|
||||||
|
top: -1.2em;
|
||||||
|
color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
& .mark {
|
||||||
|
width: 2px;
|
||||||
|
height: calc(5vh * 2.5);
|
||||||
|
background: white;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "testcard",
|
"name": "testcard",
|
||||||
"version": "0.0.1",
|
"version": "0.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite dev",
|
"dev": "vite dev",
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<i class="ti ti-volume"></i>
|
<i class="ti ti-volume"></i>
|
||||||
Audio
|
Audio
|
||||||
</a>
|
</a>
|
||||||
<a href="av-sync" class="disabled">
|
<a href="av-sync">
|
||||||
<i class="ti ti-time-duration-off"></i>
|
<i class="ti ti-time-duration-off"></i>
|
||||||
AV Sync
|
AV Sync
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -69,7 +69,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.channels .label) {
|
:global(.channels .label) {
|
||||||
opacity: 0.33;
|
opacity: 0.2;
|
||||||
font-size: 6rem;
|
font-size: 6rem;
|
||||||
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
Loading…
Reference in a new issue