Files
aitrailer/output/report/match_report.html
T
Melbar 223789eafc Re-match Beat 15 as multi-shot in scene 309
Beat 15 (4.40 s, two women + coffee mugs + snowy window) was matched as a
single 4-second clip at scene 309 in=2626.93 s, score 0.531. The trailer
beat actually contains two shots split by an internal cut at offset 3.12 s,
and the previous match approximated both with the same continuous span,
landing at the wrong phase for the second sub-shot.

After `match --beat 15 --vision` with the per-shot pipeline:
  Shot 1 (offset 0.32, dur 2.80 s): scene 309 in=2626.929 score 0.531
  Shot 2 (offset 3.12, dur 1.20 s): scene 309 in=2607.254 score 0.608

Same scene, but the second shot is now placed earlier in the source where
the leopard-print woman enters the frame — the right phase for that sub-
shot. Other beats unchanged (0 diffs verified against bak).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 10:04:56 +02:00

500 lines
22 KiB
HTML

<!DOCTYPE html>
<html><head><meta charset='utf-8'><title>AI Trailer Match Report</title>
<style>
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: #0f0f0f; color: #e0e0e0; margin: 40px; }
h1 { color: #fff; border-bottom: 1px solid #333; padding-bottom: 10px; }
.stats { font-size: 1.2em; margin-bottom: 30px; color: #aaa; }
.beat-row { display: flex; margin-bottom: 30px; background: #1a1a1a; padding: 20px; border-radius: 12px; border: 1px solid #333; }
.info { width: 250px; padding-right: 20px; flex-shrink: 0; }
.info h3 { margin-top: 0; color: #fff; }
.video-container { display: flex; gap: 20px; flex-grow: 1; }
.videos { flex-grow: 1; }
.compare { margin-bottom: 18px; }
.video-col { flex: 1; }
.video-col p { margin-top: 0; font-weight: bold; color: #888; }
video { width: 100%; border-radius: 6px; box-shadow: 0 4px 6px rgba(0,0,0,0.5); background: #000; }
.status-match { color: #4ade80; font-weight: bold; font-size: 1.1em; }
.status-miss { color: #f87171; font-weight: bold; font-size: 1.1em; }
.score { font-family: monospace; font-size: 1.1em; color: #60a5fa; }
.code-hint { background: #000; padding: 10px; border-radius: 4px; font-family: monospace; font-size: 0.9em; margin-top: 15px; color: #a3e635; }
</style></head><body>
<h1>AI Trailer Generator — Match Report</h1>
<div class='stats'>Total Beats: 25 | Matched: 20</div>
<script>
function syncBeat(row) {
const vids = row.querySelectorAll('video');
if (vids.length < 2) return;
const ref = vids[0];
const src = vids[1];
let syncing = false;
function align() {
if (syncing) return;
syncing = true;
const target = Math.min(ref.currentTime, Math.max(0, (src.duration || ref.currentTime) - 0.02));
if (Math.abs(src.currentTime - target) > 0.035) src.currentTime = target;
if (ref.paused && !src.paused) src.pause();
if (!ref.paused && src.paused) src.play().catch(() => {});
syncing = false;
}
ref.addEventListener('play', () => { src.currentTime = Math.min(ref.currentTime, Math.max(0, (src.duration || ref.currentTime) - 0.02)); src.play().catch(() => {}); });
ref.addEventListener('pause', () => src.pause());
ref.addEventListener('seeked', () => { src.currentTime = Math.min(ref.currentTime, Math.max(0, (src.duration || ref.currentTime) - 0.02)); });
ref.addEventListener('timeupdate', align);
}
document.addEventListener('DOMContentLoaded', () => document.querySelectorAll('.beat-row').forEach(syncBeat));
</script>
<div class='beat-row'>
<div class='info'>
<h3>Beat 000</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 0.00s &rarr; 3.00s</p>
<p style='color: #fbbf24; font-weight: bold; font-size: 1.1em;'>PROVISIONAL MATCH</p>
<p><b>Scene ID:</b> 1</p>
<p><b>Movie In:</b> 3.80s</p>
<p><b>Source Dur:</b> 1.56s</p>
<p><b>Unmatched Tail:</b> 0.00s placeholder</p>
<p><b>Score:</b> <span class='score'>0.597</span></p>
<p style='color: #fbbf24; font-size: 0.9em;'>Some trailer frames are still unmatched; report fills only those gaps with placeholder black.</p>
<p style='color: #fbbf24; font-size: 0.9em;'>⚠️ Score below 0.80. Verify visually.</p>
<div class='code-hint'>python cli.py rematch --beat 0</div>
</div>
<div class='videos'>
<div class='compare'><p>Frame-Locked Compare</p><video src='beat_000_compare.mp4' controls loop muted autoplay></video></div>
</div>
</div>
<div class='beat-row'>
<div class='info'>
<h3>Beat 001</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 3.00s &rarr; 8.40s</p>
<p style='color: #fbbf24; font-weight: bold; font-size: 1.1em;'>PROVISIONAL MATCH</p>
<p><b>Scene ID:</b> 1</p>
<p><b>Movie In:</b> 4.38s</p>
<p><b>Source Dur:</b> 1.76s</p>
<p><b>Unmatched Tail:</b> 3.64s placeholder</p>
<p><b>Score:</b> <span class='score'>0.380</span></p>
<p style='color: #fbbf24; font-size: 0.9em;'>Some trailer frames are still unmatched; report fills only those gaps with placeholder black.</p>
<p style='color: #fbbf24; font-size: 0.9em;'>⚠️ Score below 0.80. Verify visually.</p>
<div class='code-hint'>python cli.py rematch --beat 1</div>
</div>
<div class='videos'>
<div class='compare'><p>Frame-Locked Compare</p><video src='beat_001_compare.mp4' controls loop muted autoplay></video></div>
</div>
</div>
<div class='beat-row'>
<div class='info'>
<h3>Beat 002</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 8.40s &rarr; 16.96s</p>
<p class='status-match'>MATCHED</p>
<p><b>Scene ID:</b> 3</p>
<p><b>Movie In:</b> 35.19s</p>
<p><b>Source Dur:</b> 8.08s</p>
<p><b>Unmatched Tail:</b> 0.48s placeholder</p>
<p><b>Score:</b> <span class='score'>0.761</span></p>
<p style='color: #fbbf24; font-size: 0.9em;'>Some trailer frames are still unmatched; report fills only those gaps with placeholder black.</p>
<p style='color: #fbbf24; font-size: 0.9em;'>⚠️ Score below 0.80. Verify visually.</p>
<div class='code-hint'>python cli.py rematch --beat 2</div>
</div>
<div class='videos'>
<div class='compare'><p>Frame-Locked Compare</p><video src='beat_002_compare.mp4' controls loop muted autoplay></video></div>
</div>
</div>
<div class='beat-row'>
<div class='info'>
<h3>Beat 003</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 16.96s &rarr; 19.12s</p>
<p style='color: #fbbf24; font-weight: bold; font-size: 1.1em;'>PROVISIONAL MATCH</p>
<p><b>Scene ID:</b> 438</p>
<p><b>Movie In:</b> 3755.22s</p>
<p><b>Source Dur:</b> 1.68s</p>
<p><b>Unmatched Tail:</b> 0.24s placeholder</p>
<p><b>Score:</b> <span class='score'>0.448</span></p>
<p style='color: #fbbf24; font-size: 0.9em;'>Some trailer frames are still unmatched; report fills only those gaps with placeholder black.</p>
<p style='color: #fbbf24; font-size: 0.9em;'>⚠️ Score below 0.80. Verify visually.</p>
<div class='code-hint'>python cli.py rematch --beat 3</div>
</div>
<div class='videos'>
<div class='compare'><p>Frame-Locked Compare</p><video src='beat_003_compare.mp4' controls loop muted autoplay></video></div>
</div>
</div>
<div class='beat-row'>
<div class='info'>
<h3>Beat 004</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 19.12s &rarr; 20.64s</p>
<p class='status-miss'>NO MATCH</p>
<div class='code-hint'>python cli.py rematch --beat 4</div>
</div>
<div class='videos'>
<div class='video-container'>
<div class='video-col'><p>Reference Trailer</p><video src='beat_004_ref.mp4' controls loop muted autoplay></video></div>
<div class='video-col'><p>Matched Source</p><div style='width: 100%; aspect-ratio: 16/9; background: #222; display: flex; align-items: center; justify-content: center; border-radius: 6px; color: #555;'>No Match</div></div>
</div>
</div>
</div>
<div class='beat-row'>
<div class='info'>
<h3>Beat 005</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 20.64s &rarr; 26.36s</p>
<p style='color: #fbbf24; font-weight: bold; font-size: 1.1em;'>PROVISIONAL MATCH</p>
<p><b>Scene ID:</b> 10</p>
<p><b>Movie In:</b> 93.14s</p>
<p><b>Source Dur:</b> 4.24s</p>
<p><b>Unmatched Tail:</b> 1.16s placeholder</p>
<p><b>Score:</b> <span class='score'>0.499</span></p>
<p style='color: #fbbf24; font-size: 0.9em;'>Some trailer frames are still unmatched; report fills only those gaps with placeholder black.</p>
<p style='color: #fbbf24; font-size: 0.9em;'>⚠️ Score below 0.80. Verify visually.</p>
<div class='code-hint'>python cli.py rematch --beat 5</div>
</div>
<div class='videos'>
<div class='compare'><p>Frame-Locked Compare</p><video src='beat_005_compare.mp4' controls loop muted autoplay></video></div>
</div>
</div>
<div class='beat-row'>
<div class='info'>
<h3>Beat 006</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 26.36s &rarr; 29.24s</p>
<p style='color: #fbbf24; font-weight: bold; font-size: 1.1em;'>PROVISIONAL MATCH</p>
<p><b>Scene ID:</b> 5</p>
<p><b>Movie In:</b> 63.27s</p>
<p><b>Source Dur:</b> 1.84s</p>
<p><b>Unmatched Tail:</b> 0.96s placeholder</p>
<p><b>Score:</b> <span class='score'>0.396</span></p>
<p style='color: #fbbf24; font-size: 0.9em;'>Some trailer frames are still unmatched; report fills only those gaps with placeholder black.</p>
<p style='color: #fbbf24; font-size: 0.9em;'>⚠️ Score below 0.80. Verify visually.</p>
<div class='code-hint'>python cli.py rematch --beat 6</div>
</div>
<div class='videos'>
<div class='compare'><p>Frame-Locked Compare</p><video src='beat_006_compare.mp4' controls loop muted autoplay></video></div>
</div>
</div>
<div class='beat-row'>
<div class='info'>
<h3>Beat 007</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 29.24s &rarr; 31.68s</p>
<p style='color: #fbbf24; font-weight: bold; font-size: 1.1em;'>PROVISIONAL MATCH</p>
<p><b>Scene ID:</b> 553</p>
<p><b>Movie In:</b> 4810.44s</p>
<p><b>Source Dur:</b> 2.16s</p>
<p><b>Unmatched Tail:</b> 0.20s placeholder</p>
<p><b>Score:</b> <span class='score'>0.497</span></p>
<p style='color: #fbbf24; font-size: 0.9em;'>Some trailer frames are still unmatched; report fills only those gaps with placeholder black.</p>
<p style='color: #fbbf24; font-size: 0.9em;'>⚠️ Score below 0.80. Verify visually.</p>
<div class='code-hint'>python cli.py rematch --beat 7</div>
</div>
<div class='videos'>
<div class='compare'><p>Frame-Locked Compare</p><video src='beat_007_compare.mp4' controls loop muted autoplay></video></div>
</div>
</div>
<div class='beat-row'>
<div class='info'>
<h3>Beat 008</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 31.68s &rarr; 33.64s</p>
<p style='color: #fbbf24; font-weight: bold; font-size: 1.1em;'>PROVISIONAL MATCH</p>
<p><b>Scene ID:</b> 5</p>
<p><b>Movie In:</b> 51.27s</p>
<p><b>Source Dur:</b> 1.76s</p>
<p><b>Unmatched Tail:</b> 0.20s placeholder</p>
<p><b>Score:</b> <span class='score'>0.620</span></p>
<p style='color: #fbbf24; font-size: 0.9em;'>Some trailer frames are still unmatched; report fills only those gaps with placeholder black.</p>
<p style='color: #fbbf24; font-size: 0.9em;'>⚠️ Score below 0.80. Verify visually.</p>
<div class='code-hint'>python cli.py rematch --beat 8</div>
</div>
<div class='videos'>
<div class='compare'><p>Frame-Locked Compare</p><video src='beat_008_compare.mp4' controls loop muted autoplay></video></div>
</div>
</div>
<div class='beat-row'>
<div class='info'>
<h3>Beat 009</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 33.64s &rarr; 36.76s</p>
<p class='status-match'>MATCHED</p>
<p><b>Scene ID:</b> 557</p>
<p><b>Movie In:</b> 4829.12s</p>
<p><b>Source Dur:</b> 3.12s</p>
<p><b>Unmatched Tail:</b> 0.00s placeholder</p>
<p><b>Score:</b> <span class='score'>0.674</span></p>
<p style='color: #fbbf24; font-size: 0.9em;'>Some trailer frames are still unmatched; report fills only those gaps with placeholder black.</p>
<p style='color: #fbbf24; font-size: 0.9em;'>⚠️ Score below 0.80. Verify visually.</p>
<div class='code-hint'>python cli.py rematch --beat 9</div>
</div>
<div class='videos'>
<div class='compare'><p>Frame-Locked Compare</p><video src='beat_009_compare.mp4' controls loop muted autoplay></video></div>
</div>
</div>
<div class='beat-row'>
<div class='info'>
<h3>Beat 010</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 36.76s &rarr; 40.08s</p>
<p style='color: #fbbf24; font-weight: bold; font-size: 1.1em;'>PROVISIONAL MATCH</p>
<p><b>Scene ID:</b> 554</p>
<p><b>Movie In:</b> 4813.56s</p>
<p><b>Source Dur:</b> 3.32s</p>
<p><b>Segments:</b> 3 matched visual islands</p>
<p><b>Score:</b> <span class='score'>0.660</span></p>
<p style='color: #fbbf24; font-size: 0.9em;'>⚠️ Score below 0.80. Verify visually.</p>
<div class='code-hint'>python cli.py rematch --beat 10</div>
</div>
<div class='videos'>
<div class='compare'><p>Frame-Locked Compare</p><video src='beat_010_compare.mp4' controls loop muted autoplay></video></div>
</div>
</div>
<div class='beat-row'>
<div class='info'>
<h3>Beat 011</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 40.08s &rarr; 42.12s</p>
<p style='color: #fbbf24; font-weight: bold; font-size: 1.1em;'>PROVISIONAL MATCH</p>
<p><b>Scene ID:</b> 559</p>
<p><b>Movie In:</b> 4840.76s</p>
<p><b>Source Dur:</b> 2.00s</p>
<p><b>Unmatched Tail:</b> 0.04s placeholder</p>
<p><b>Score:</b> <span class='score'>0.636</span></p>
<p style='color: #fbbf24; font-size: 0.9em;'>Some trailer frames are still unmatched; report fills only those gaps with placeholder black.</p>
<p style='color: #fbbf24; font-size: 0.9em;'>⚠️ Score below 0.80. Verify visually.</p>
<div class='code-hint'>python cli.py rematch --beat 11</div>
</div>
<div class='videos'>
<div class='compare'><p>Frame-Locked Compare</p><video src='beat_011_compare.mp4' controls loop muted autoplay></video></div>
</div>
</div>
<div class='beat-row'>
<div class='info'>
<h3>Beat 012</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 42.12s &rarr; 50.24s</p>
<p class='status-match'>MATCHED</p>
<p><b>Scene ID:</b> 519</p>
<p><b>Movie In:</b> 4466.24s</p>
<p><b>Source Dur:</b> 6.40s</p>
<p><b>Segments:</b> 2 matched visual islands</p>
<p><b>Unmatched Tail:</b> 0.36s placeholder</p>
<p><b>Score:</b> <span class='score'>0.701</span></p>
<p style='color: #fbbf24; font-size: 0.9em;'>Some trailer frames are still unmatched; report fills only those gaps with placeholder black.</p>
<p style='color: #fbbf24; font-size: 0.9em;'>⚠️ Score below 0.80. Verify visually.</p>
<div class='code-hint'>python cli.py rematch --beat 12</div>
</div>
<div class='videos'>
<div class='compare'><p>Frame-Locked Compare</p><video src='beat_012_compare.mp4' controls loop muted autoplay></video></div>
</div>
</div>
<div class='beat-row'>
<div class='info'>
<h3>Beat 013</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 50.24s &rarr; 53.84s</p>
<p style='color: #fbbf24; font-weight: bold; font-size: 1.1em;'>PROVISIONAL MATCH</p>
<p><b>Scene ID:</b> 308</p>
<p><b>Movie In:</b> 2599.56s</p>
<p><b>Source Dur:</b> 3.60s</p>
<p><b>Unmatched Tail:</b> 0.00s placeholder</p>
<p><b>Score:</b> <span class='score'>0.636</span></p>
<p style='color: #fbbf24; font-size: 0.9em;'>Some trailer frames are still unmatched; report fills only those gaps with placeholder black.</p>
<p style='color: #fbbf24; font-size: 0.9em;'>⚠️ Score below 0.80. Verify visually.</p>
<div class='code-hint'>python cli.py rematch --beat 13</div>
</div>
<div class='videos'>
<div class='compare'><p>Frame-Locked Compare</p><video src='beat_013_compare.mp4' controls loop muted autoplay></video></div>
</div>
</div>
<div class='beat-row'>
<div class='info'>
<h3>Beat 014</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 53.84s &rarr; 57.08s</p>
<p style='color: #fbbf24; font-weight: bold; font-size: 1.1em;'>PROVISIONAL MATCH</p>
<p><b>Scene ID:</b> 309</p>
<p><b>Movie In:</b> 2618.23s</p>
<p><b>Source Dur:</b> 3.12s</p>
<p><b>Unmatched Tail:</b> 0.12s placeholder</p>
<p><b>Score:</b> <span class='score'>0.626</span></p>
<p style='color: #fbbf24; font-size: 0.9em;'>Some trailer frames are still unmatched; report fills only those gaps with placeholder black.</p>
<p style='color: #fbbf24; font-size: 0.9em;'>⚠️ Score below 0.80. Verify visually.</p>
<div class='code-hint'>python cli.py rematch --beat 14</div>
</div>
<div class='videos'>
<div class='compare'><p>Frame-Locked Compare</p><video src='beat_014_compare.mp4' controls loop muted autoplay></video></div>
</div>
</div>
<div class='beat-row'>
<div class='info'>
<h3>Beat 015</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 57.08s &rarr; 61.48s</p>
<p style='color: #fbbf24; font-weight: bold; font-size: 1.1em;'>PROVISIONAL MATCH</p>
<p><b>Scene ID:</b> 309</p>
<p><b>Movie In:</b> 2626.93s</p>
<p><b>Source Dur:</b> 4.00s</p>
<p><b>Segments:</b> 2 matched visual islands</p>
<p><b>Unmatched Tail:</b> 0.08s placeholder</p>
<p><b>Score:</b> <span class='score'>0.555</span></p>
<p style='color: #fbbf24; font-size: 0.9em;'>Some trailer frames are still unmatched; report fills only those gaps with placeholder black.</p>
<p style='color: #fbbf24; font-size: 0.9em;'>⚠️ Score below 0.80. Verify visually.</p>
<div class='code-hint'>python cli.py rematch --beat 15</div>
</div>
<div class='videos'>
<div class='compare'><p>Frame-Locked Compare</p><video src='beat_015_compare.mp4' controls loop muted autoplay></video></div>
</div>
</div>
<div class='beat-row'>
<div class='info'>
<h3>Beat 016</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 61.48s &rarr; 64.48s</p>
<p style='color: #fbbf24; font-weight: bold; font-size: 1.1em;'>PROVISIONAL MATCH</p>
<p><b>Scene ID:</b> 451</p>
<p><b>Movie In:</b> 3912.48s</p>
<p><b>Source Dur:</b> 2.80s</p>
<p><b>Unmatched Tail:</b> 0.12s placeholder</p>
<p><b>Score:</b> <span class='score'>0.626</span></p>
<p style='color: #fbbf24; font-size: 0.9em;'>Some trailer frames are still unmatched; report fills only those gaps with placeholder black.</p>
<p style='color: #fbbf24; font-size: 0.9em;'>⚠️ Score below 0.80. Verify visually.</p>
<div class='code-hint'>python cli.py rematch --beat 16</div>
</div>
<div class='videos'>
<div class='compare'><p>Frame-Locked Compare</p><video src='beat_016_compare.mp4' controls loop muted autoplay></video></div>
</div>
</div>
<div class='beat-row'>
<div class='info'>
<h3>Beat 017</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 64.48s &rarr; 69.12s</p>
<p class='status-match'>MATCHED</p>
<p><b>Scene ID:</b> 623</p>
<p><b>Movie In:</b> 5486.26s</p>
<p><b>Source Dur:</b> 4.48s</p>
<p><b>Score:</b> <span class='score'>0.685</span></p>
<p style='color: #fbbf24; font-size: 0.9em;'>⚠️ Score below 0.80. Verify visually.</p>
<div class='code-hint'>python cli.py rematch --beat 17</div>
</div>
<div class='videos'>
<div class='compare'><p>Frame-Locked Compare</p><video src='beat_017_compare.mp4' controls loop muted autoplay></video></div>
</div>
</div>
<div class='beat-row'>
<div class='info'>
<h3>Beat 018</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 69.12s &rarr; 70.76s</p>
<p class='status-miss'>NO MATCH</p>
<div class='code-hint'>python cli.py rematch --beat 18</div>
</div>
<div class='videos'>
<div class='video-container'>
<div class='video-col'><p>Reference Trailer</p><video src='beat_018_ref.mp4' controls loop muted autoplay></video></div>
<div class='video-col'><p>Matched Source</p><div style='width: 100%; aspect-ratio: 16/9; background: #222; display: flex; align-items: center; justify-content: center; border-radius: 6px; color: #555;'>No Match</div></div>
</div>
</div>
</div>
<div class='beat-row'>
<div class='info'>
<h3>Beat 019</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 70.76s &rarr; 72.52s</p>
<p style='color: #fbbf24; font-weight: bold; font-size: 1.1em;'>PROVISIONAL MATCH</p>
<p><b>Scene ID:</b> 126</p>
<p><b>Movie In:</b> 1008.54s</p>
<p><b>Source Dur:</b> 0.88s</p>
<p><b>Unmatched Tail:</b> 0.48s placeholder</p>
<p><b>Score:</b> <span class='score'>0.403</span></p>
<p style='color: #fbbf24; font-size: 0.9em;'>Some trailer frames are still unmatched; report fills only those gaps with placeholder black.</p>
<p style='color: #fbbf24; font-size: 0.9em;'>⚠️ Score below 0.80. Verify visually.</p>
<div class='code-hint'>python cli.py rematch --beat 19</div>
</div>
<div class='videos'>
<div class='compare'><p>Frame-Locked Compare</p><video src='beat_019_compare.mp4' controls loop muted autoplay></video></div>
</div>
</div>
<div class='beat-row'>
<div class='info'>
<h3>Beat 020</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 72.52s &rarr; 75.56s</p>
<p class='status-miss'>NO MATCH</p>
<div class='code-hint'>python cli.py rematch --beat 20</div>
</div>
<div class='videos'>
<div class='video-container'>
<div class='video-col'><p>Reference Trailer</p><video src='beat_020_ref.mp4' controls loop muted autoplay></video></div>
<div class='video-col'><p>Matched Source</p><div style='width: 100%; aspect-ratio: 16/9; background: #222; display: flex; align-items: center; justify-content: center; border-radius: 6px; color: #555;'>No Match</div></div>
</div>
</div>
</div>
<div class='beat-row'>
<div class='info'>
<h3>Beat 021</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 75.56s &rarr; 77.52s</p>
<p class='status-miss'>NO MATCH</p>
<div class='code-hint'>python cli.py rematch --beat 21</div>
</div>
<div class='videos'>
<div class='video-container'>
<div class='video-col'><p>Reference Trailer</p><video src='beat_021_ref.mp4' controls loop muted autoplay></video></div>
<div class='video-col'><p>Matched Source</p><div style='width: 100%; aspect-ratio: 16/9; background: #222; display: flex; align-items: center; justify-content: center; border-radius: 6px; color: #555;'>No Match</div></div>
</div>
</div>
</div>
<div class='beat-row'>
<div class='info'>
<h3>Beat 022</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 77.52s &rarr; 79.92s</p>
<p style='color: #fbbf24; font-weight: bold; font-size: 1.1em;'>PROVISIONAL MATCH</p>
<p><b>Scene ID:</b> 442</p>
<p><b>Movie In:</b> 3785.44s</p>
<p><b>Source Dur:</b> 1.84s</p>
<p><b>Unmatched Tail:</b> 0.48s placeholder</p>
<p><b>Score:</b> <span class='score'>0.544</span></p>
<p style='color: #fbbf24; font-size: 0.9em;'>Some trailer frames are still unmatched; report fills only those gaps with placeholder black.</p>
<p style='color: #fbbf24; font-size: 0.9em;'>⚠️ Score below 0.80. Verify visually.</p>
<div class='code-hint'>python cli.py rematch --beat 22</div>
</div>
<div class='videos'>
<div class='compare'><p>Frame-Locked Compare</p><video src='beat_022_compare.mp4' controls loop muted autoplay></video></div>
</div>
</div>
<div class='beat-row'>
<div class='info'>
<h3>Beat 023</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 79.92s &rarr; 85.56s</p>
<p style='color: #fbbf24; font-weight: bold; font-size: 1.1em;'>PROVISIONAL MATCH</p>
<p><b>Scene ID:</b> 446</p>
<p><b>Movie In:</b> 3875.87s</p>
<p><b>Source Dur:</b> 5.20s</p>
<p><b>Unmatched Tail:</b> 0.36s placeholder</p>
<p><b>Score:</b> <span class='score'>0.534</span></p>
<p style='color: #fbbf24; font-size: 0.9em;'>Some trailer frames are still unmatched; report fills only those gaps with placeholder black.</p>
<p style='color: #fbbf24; font-size: 0.9em;'>⚠️ Score below 0.80. Verify visually.</p>
<div class='code-hint'>python cli.py rematch --beat 23</div>
</div>
<div class='videos'>
<div class='compare'><p>Frame-Locked Compare</p><video src='beat_023_compare.mp4' controls loop muted autoplay></video></div>
</div>
</div>
<div class='beat-row'>
<div class='info'>
<h3>Beat 024</h3>
<p><b>Type:</b> UNKNOWN</p>
<p><b>Trailer:</b> 85.56s &rarr; 92.28s</p>
<p class='status-miss'>NO MATCH</p>
<div class='code-hint'>python cli.py rematch --beat 24</div>
</div>
<div class='videos'>
<div class='video-container'>
<div class='video-col'><p>Reference Trailer</p><video src='beat_024_ref.mp4' controls loop muted autoplay></video></div>
<div class='video-col'><p>Matched Source</p><div style='width: 100%; aspect-ratio: 16/9; background: #222; display: flex; align-items: center; justify-content: center; border-radius: 6px; color: #555;'>No Match</div></div>
</div>
</div>
</div>
</body></html>