-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
205 lines (195 loc) · 8.47 KB
/
Copy pathindex.html
File metadata and controls
205 lines (195 loc) · 8.47 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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="color-scheme" content="dark" />
<title>WebCodecs Transcoding Lab</title>
<link rel="stylesheet" href="./src/styles.css" />
</head>
<body>
<div class="ambient ambient-one"></div>
<div class="ambient ambient-two"></div>
<main class="shell">
<header class="masthead">
<div>
<div class="eyebrow"><span class="pulse-dot"></span> Standalone browser lab</div>
<h1>WebCodecs<br /><span>Transcoding Matrix</span></h1>
<p class="lede">Trace a live webcam frame from source scaling through keyframe encode and decode—especially at the awkward edges around 90p.</p>
</div>
<div class="runtime-card" id="runtimeCard">
<span class="runtime-icon">WC</span>
<div>
<strong id="runtimeStatus">Checking runtime…</strong>
<span id="runtimeDetail">WebCodecs + camera access required</span>
</div>
</div>
</header>
<section class="source-section panel">
<div class="section-heading">
<div>
<span class="step-number">01</span>
<h2>Live source</h2>
</div>
<span class="status-pill idle" id="cameraStatus">Camera offline</span>
</div>
<div class="source-grid">
<div class="preview-wrap">
<video id="preview" autoplay muted playsinline></video>
<div class="preview-empty" id="previewEmpty">
<span class="camera-glyph"></span>
<strong>Camera is not running</strong>
<small>Frames stay in this browser tab.</small>
</div>
<div class="preview-meta" id="previewMeta">—</div>
</div>
<div class="source-controls">
<label>
<span>Camera device</span>
<select id="cameraSelect"><option value="">Default camera</option></select>
</label>
<div class="field-pair">
<label>
<span>Requested width</span>
<input id="cameraWidth" type="number" min="1" max="7680" value="1280" />
</label>
<label>
<span>Requested height</span>
<input id="cameraHeight" type="number" min="1" max="4320" value="720" />
</label>
</div>
<button class="button primary" id="cameraButton">Start camera</button>
<p class="microcopy">The requested capture size is only a constraint. The actual track size is reported on the preview and included in exported results.</p>
</div>
</div>
</section>
<section class="config-section panel">
<div class="section-heading">
<div>
<span class="step-number">02</span>
<h2>Build the matrix</h2>
</div>
<span class="case-count" id="caseCount">0 cases</span>
</div>
<div class="config-block">
<div class="config-label">
<strong>Codecs</strong>
<span>Each profile is probed before it runs.</span>
</div>
<div class="codec-grid" id="codecGrid"></div>
</div>
<div class="config-block acceleration-block">
<div class="config-label">
<strong>Hardware acceleration paths</strong>
<span>Encoder → decoder. Mixed paths use a different preference for each stage.</span>
</div>
<div class="acceleration-grid" id="accelerationPathGrid"></div>
</div>
<div class="resolution-grid">
<div class="config-block resolution-block">
<div class="config-label">
<strong>Input resolutions</strong>
<span>Webcam frame before the transcode scale.</span>
</div>
<textarea id="inputResolutions" rows="3" spellcheck="false">640x360</textarea>
<div class="preset-row">
<button class="text-button" data-input-preset="native">Use camera size</button>
<button class="text-button" data-input-preset="common">Common inputs</button>
</div>
</div>
<div class="flow-arrow" aria-hidden="true">→</div>
<div class="config-block resolution-block output-block">
<div class="config-label">
<strong>Encoded output resolutions</strong>
<span>One isolated bitstream per output size.</span>
</div>
<textarea id="outputResolutions" rows="3" spellcheck="false">162x90, 160x90, 158x90</textarea>
<div class="preset-row">
<button class="text-button accent" data-output-preset="ninety">90p edge sweep</button>
<button class="text-button" data-output-preset="ladder">Video ladder</button>
</div>
</div>
</div>
<div class="advanced-grid">
<label>
<span>Frames / case</span>
<input id="frameCount" type="number" min="1" max="120" value="4" />
</label>
<label>
<span>Frame rate</span>
<input id="frameRate" type="number" min="1" max="120" value="30" />
</label>
<label>
<span>Bitrate</span>
<select id="bitrateMode">
<option value="auto">Auto by pixel count</option>
<option value="fixed">Fixed</option>
</select>
</label>
<label>
<span>Fixed bitrate (bps)</span>
<input id="fixedBitrate" type="number" min="10000" step="10000" value="500000" disabled />
</label>
<label>
<span>Keyframe interval</span>
<input id="keyInterval" type="number" min="1" max="120" value="30" />
</label>
</div>
<div class="validation-message" id="validationMessage" hidden></div>
</section>
<section class="run-section">
<div class="run-copy">
<strong id="runHeadline">Ready for a matrix run</strong>
<span id="runSubhead">Start the camera, then run each case in isolation.</span>
</div>
<div class="run-actions">
<button class="button ghost" id="stopButton" disabled>Stop</button>
<button class="button primary run-button" id="runButton" disabled>Run matrix <span>→</span></button>
</div>
</section>
<section class="results-section panel" id="resultsSection">
<div class="section-heading results-heading">
<div>
<span class="step-number">03</span>
<h2>Results</h2>
</div>
<div class="results-tools">
<button class="text-button" id="exportButton" disabled>Export JSON</button>
<button class="text-button" id="clearButton" disabled>Clear</button>
</div>
</div>
<div class="summary-strip" id="summaryStrip">
<div><span class="summary-value">—</span><span>Passed</span></div>
<div><span class="summary-value">—</span><span>Failed</span></div>
<div><span class="summary-value">—</span><span>Unsupported</span></div>
<div><span class="summary-value">—</span><span>Elapsed</span></div>
</div>
<div class="empty-results" id="emptyResults">
<div class="empty-grid-icon"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div>
<strong>No measurements yet</strong>
<span>The result matrix will show exactly where each pipeline stopped.</span>
</div>
<div class="matrix-scroller" id="matrixScroller" hidden>
<table class="result-matrix" id="resultMatrix"></table>
</div>
</section>
</main>
<dialog id="detailDialog" class="detail-dialog">
<form method="dialog" class="dialog-shell">
<div class="dialog-heading">
<div>
<span class="eyebrow">Case inspector</span>
<h2 id="detailTitle">Pipeline details</h2>
</div>
<button class="icon-button" value="close" aria-label="Close">×</button>
</div>
<div id="detailContent"></div>
<div class="dialog-actions">
<button type="button" class="button ghost" id="copyDetailButton">Copy JSON</button>
<button type="button" class="button primary" id="rerunButton">Rerun this case</button>
</div>
</form>
</dialog>
<script type="module" src="./src/app.js"></script>
</body>
</html>