Repository navigation
Expand file tree
/
Copy pathloader.html
More file actions
174 lines (160 loc) · 8.57 KB
/
Copy pathloader.html
File metadata and controls
174 lines (160 loc) · 8.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title data-i18n="loader_page_title">Video Loader — Ghostmaxxing</title>
<meta name="description" content="Analyse an existing local makeup video, review face-model transitions, and export reproducible evidence without uploading the source." />
<meta property="og:title" content="Makeup Video Analyser — Ghostmaxxing" />
<meta property="og:description" content="Analyse local makeup videos into timelines, before-and-after evidence, and reusable technical logs." />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://ghostmaxxing.vecna.eu/loader.html" />
<meta property="og:image" content="https://ghostmaxxing.vecna.eu/images/social/ghostmaxxing-generic.jpg" />
<meta name="twitter:card" content="summary_large_image" />
<link rel="canonical" href="https://ghostmaxxing.vecna.eu/loader.html" />
<meta name="theme-color" content="#14100c" />
<link rel="icon" type="image/svg+xml" href="/images/logo/mark-color.svg" />
<link rel="stylesheet" href="/styles/styles.css" />
<link rel="stylesheet" href="/styles/pages.css" />
<link rel="stylesheet" href="/styles/loader.css" />
</head>
<body class="loader-page">
<main class="loader-shell" aria-labelledby="loader-title">
<header class="loader-header">
<a class="wordmark" href="/" aria-label="Ghostmaxxing homepage" data-i18n-aria-label="loader_wordmark_label">
<span class="wordmark__main">
<img class="wordmark__mark" src="/images/logo/mark-ondark.svg" alt="" aria-hidden="true" />
<span class="wordmark__title">Ghostmaxxing</span>
</span>
<span class="wordmark__subtitle">Seekable video analysis</span>
</a>
<div class="loader-header__tools">
<label class="locale-control">
<span class="locale-control__flag" aria-hidden="true"></span>
<select id="localeSelect" class="locale-select" aria-label="Language" data-i18n-aria-label="language_label"></select>
</label>
<div class="loader-status" aria-live="polite">
<span id="statusDot" class="status-dot"></span>
<span id="statusText">loading models</span>
</div>
</div>
</header>
<section class="loader-intro">
<div>
<p class="loader-kicker">Existing video → evidence</p>
<h1 id="loader-title" class="loader-title">Makeup video analyser</h1>
</div>
<p class="loader-intro__copy">
Select a local video. It stays on this device while MediaPipe maps frequent visual changes and face-api verifies selected moments.
</p>
</section>
<section class="loader-stage" aria-label="Local video source">
<div id="viewer" class="loader-viewer">
<div id="placeholder" class="loader-placeholder">Select a local MP4, WebM, or compatible video to begin.</div>
<video id="video" controls playsinline preload="metadata"></video>
<div id="analysisLockNotice" class="loader-viewer-lock" hidden>Analysis controls the video position</div>
</div>
<div class="loader-source-controls">
<div class="loader-source-file">
<span class="loader-control-label">Source</span>
<label class="file-control">
<span id="sourceFileAction">Select local video</span>
<input id="videoFile" type="file" accept="video/*,.mkv" />
</label>
<div class="loader-source-file__identity">
<strong id="sourceFileName">No video selected</strong>
<span id="sourceFileMeta">Local files remain on this device.</span>
</div>
</div>
<div class="loader-seek" aria-label="Precise source position">
<span class="loader-seek__name">Viewing</span>
<span id="currentTimeLabel">00:00.000</span>
<input id="videoSeek" type="range" min="0" max="0" step="0.001" value="0" disabled />
<span id="durationLabel">00:00.000</span>
</div>
<button id="analyzeFrameBtn" type="button" disabled>Analyse this frame</button>
</div>
<div class="loader-analysis-controls" aria-label="Analysis controls">
<div class="loader-control-group loader-analysis-plan">
<span class="loader-control-label">Analysis plan</span>
<div id="analysisSettings" class="loader-analysis-settings">
<label>
<span>Sample every</span>
<select id="sampleInterval">
<option value="0.25">0.25 seconds</option>
<option value="0.5" selected>0.5 seconds</option>
<option value="1">1 second</option>
<option value="2">2 seconds</option>
</select>
</label>
<div class="loader-base-picker">
<button id="selectBaseBtn" type="button" disabled>Select base at 00:00.000</button>
<span id="selectedBaseLabel" aria-live="polite">No base selected. Scrub the video, then select the displayed frame.</span>
</div>
</div>
</div>
<div class="loader-control-group loader-run-state">
<span class="loader-control-label">Run</span>
<div class="loader-run-state__action">
<button id="startAnalysisBtn" class="loader-primary" type="button" disabled>Analyse video</button>
<button id="cancelAnalysisBtn" type="button" disabled hidden>Pause after this sample</button>
</div>
<div class="loader-progress" aria-label="Analysis sample progress">
<span class="loader-progress__name">Analysis samples</span>
<progress id="analysisProgress" max="100" value="0"></progress>
<span id="analysisProgressLabel" aria-live="polite">0 / —</span>
</div>
</div>
<div id="analysisMessage" class="loader-analysis-message" role="alert" hidden>
<strong id="analysisMessageTitle"></strong>
<span id="analysisMessageBody"></span>
</div>
</div>
</section>
<section class="loader-report" aria-labelledby="report-title">
<header class="loader-report__header">
<div>
<p class="loader-kicker">Analysis report</p>
<h2 id="report-title">Evidence and story order</h2>
<p id="reportSummary" class="loader-report__summary">No video analysed yet.</p>
</div>
<div class="loader-report__actions">
<div class="loader-action-group" aria-label="Edit history">
<span>History</span>
<button id="undoEditBtn" type="button" disabled>Undo</button>
<button id="redoEditBtn" type="button" disabled>Redo</button>
</div>
<div class="loader-action-group" aria-label="Export analysis">
<span>Export</span>
<button id="downloadReportBtn" type="button" disabled>Download report</button>
<button id="downloadLogBtn" type="button" disabled>Download technical log</button>
</div>
</div>
</header>
<div class="loader-baseline">
<strong>Distance reference</strong>
<span id="baselineSummary">Distance reference not acquired yet.</span>
</div>
<p class="loader-story-note">
The baseline stays first because every distance starts there. Source timestamps remain factual; use “Move earlier” and “Move later” to arrange the later evidence independently of source chronology.
</p>
<figure class="loader-timeline-figure">
<canvas id="analysisTimeline" aria-label="Analysis timeline with separate MediaPipe coverage, ImageEmbedder, and face-api lanes"></canvas>
<figcaption>
MediaPipe coverage is diagnostic context, not evidence by itself. ImageEmbedder drift is frequent generic-image change measured as 1 − cosine similarity. face-api L2 distance is sampled only on comparable frames; × means no 2D face was returned. Each dashed line prints the active numeric trigger or decision threshold beside it.
</figcaption>
</figure>
<div id="emptyReport" class="loader-empty-report">
Confirmed transitions will appear here with a high-resolution source frame and editable story text.
</div>
<div id="eventList" class="loader-event-list"></div>
</section>
<aside class="loader-privacy">
<strong>Local by design.</strong>
The source video is not uploaded. The editorial report and the versioned technical log are separate downloads.
</aside>
</main>
<script src="/lab-js/vendor/face-api.js"></script>
<script type="module" src="/lab-js/loader.js"></script>
</body>
</html>