Spaces:
Running on Zero
Running on Zero
Commit ·
6390bb5
1
Parent(s): 782f393
app.py
CHANGED
|
@@ -1149,6 +1149,7 @@ def _build_waveform_html(audio_path: str, segments: list, slot_id: str,
|
|
| 1149 |
window["_wf_video_unlisten_{slot_id}"] = null;
|
| 1150 |
}}
|
| 1151 |
|
|
|
|
| 1152 |
const segments = {segs_json};
|
| 1153 |
const segColors = {json.dumps(seg_colors)};
|
| 1154 |
let audioDuration = 0;
|
|
@@ -1207,15 +1208,18 @@ def _build_waveform_html(audio_path: str, segments: list, slot_id: str,
|
|
| 1207 |
function drawWaveform(channelData, duration) {{
|
| 1208 |
audioDuration = duration;
|
| 1209 |
const canvas = document.getElementById('wf_canvas_{slot_id}');
|
| 1210 |
-
if (!canvas) return;
|
| 1211 |
const dpr = window.devicePixelRatio || 1;
|
| 1212 |
-
const
|
|
|
|
| 1213 |
|| (canvas.parentElement ? canvas.parentElement.getBoundingClientRect().width : 0)
|
| 1214 |
|| 600;
|
| 1215 |
const H = 80;
|
|
|
|
| 1216 |
canvas.width = W * dpr;
|
| 1217 |
canvas.height = H * dpr;
|
| 1218 |
const ctx = canvas.getContext('2d');
|
|
|
|
| 1219 |
ctx.scale(dpr, dpr);
|
| 1220 |
|
| 1221 |
// Background
|
|
@@ -1324,9 +1328,11 @@ def _build_waveform_html(audio_path: str, segments: list, slot_id: str,
|
|
| 1324 |
// Decode audio immediately (doesn't need canvas dimensions).
|
| 1325 |
// Drawing is deferred until the canvas actually has a non-zero width.
|
| 1326 |
const b64str = '{b64}';
|
|
|
|
| 1327 |
const bin = atob(b64str);
|
| 1328 |
const buf = new Uint8Array(bin.length);
|
| 1329 |
for (let i = 0; i < bin.length; i++) buf[i] = bin.charCodeAt(i);
|
|
|
|
| 1330 |
|
| 1331 |
// OfflineAudioContext for decoding — works without user gesture, no playback
|
| 1332 |
const OfflineCtx = window.OfflineAudioContext || window.webkitOfflineAudioContext;
|
|
@@ -1358,14 +1364,14 @@ def _build_waveform_html(audio_path: str, segments: list, slot_id: str,
|
|
| 1358 |
tryDraw();
|
| 1359 |
}};
|
| 1360 |
|
| 1361 |
-
// decodeAudioData
|
| 1362 |
-
|
| 1363 |
-
|
| 1364 |
-
|
| 1365 |
-
|
| 1366 |
-
decodePromise.then(doRender).catch(function(err) {{
|
| 1367 |
-
console.error('[waveform {slot_id}] decodeAudioData promise error:', err);
|
| 1368 |
}});
|
|
|
|
|
|
|
| 1369 |
}}
|
| 1370 |
}}
|
| 1371 |
}})();
|
|
|
|
| 1149 |
window["_wf_video_unlisten_{slot_id}"] = null;
|
| 1150 |
}}
|
| 1151 |
|
| 1152 |
+
console.log('[waveform {slot_id}] script executing');
|
| 1153 |
const segments = {segs_json};
|
| 1154 |
const segColors = {json.dumps(seg_colors)};
|
| 1155 |
let audioDuration = 0;
|
|
|
|
| 1208 |
function drawWaveform(channelData, duration) {{
|
| 1209 |
audioDuration = duration;
|
| 1210 |
const canvas = document.getElementById('wf_canvas_{slot_id}');
|
| 1211 |
+
if (!canvas) {{ console.error('[waveform {slot_id}] drawWaveform: canvas element missing'); return; }}
|
| 1212 |
const dpr = window.devicePixelRatio || 1;
|
| 1213 |
+
const rect = canvas.getBoundingClientRect();
|
| 1214 |
+
const W = rect.width
|
| 1215 |
|| (canvas.parentElement ? canvas.parentElement.getBoundingClientRect().width : 0)
|
| 1216 |
|| 600;
|
| 1217 |
const H = 80;
|
| 1218 |
+
console.log('[waveform {slot_id}] drawWaveform W=' + W + ' H=' + H + ' dpr=' + dpr + ' rect=' + JSON.stringify(rect));
|
| 1219 |
canvas.width = W * dpr;
|
| 1220 |
canvas.height = H * dpr;
|
| 1221 |
const ctx = canvas.getContext('2d');
|
| 1222 |
+
if (!ctx) {{ console.error('[waveform {slot_id}] drawWaveform: could not get 2d context'); return; }}
|
| 1223 |
ctx.scale(dpr, dpr);
|
| 1224 |
|
| 1225 |
// Background
|
|
|
|
| 1328 |
// Decode audio immediately (doesn't need canvas dimensions).
|
| 1329 |
// Drawing is deferred until the canvas actually has a non-zero width.
|
| 1330 |
const b64str = '{b64}';
|
| 1331 |
+
console.log('[waveform {slot_id}] b64 length=' + b64str.length);
|
| 1332 |
const bin = atob(b64str);
|
| 1333 |
const buf = new Uint8Array(bin.length);
|
| 1334 |
for (let i = 0; i < bin.length; i++) buf[i] = bin.charCodeAt(i);
|
| 1335 |
+
console.log('[waveform {slot_id}] decoded buf size=' + buf.byteLength + ' bytes');
|
| 1336 |
|
| 1337 |
// OfflineAudioContext for decoding — works without user gesture, no playback
|
| 1338 |
const OfflineCtx = window.OfflineAudioContext || window.webkitOfflineAudioContext;
|
|
|
|
| 1364 |
tryDraw();
|
| 1365 |
}};
|
| 1366 |
|
| 1367 |
+
// decodeAudioData — use callback form only to avoid double-calling doRender
|
| 1368 |
+
console.log('[waveform {slot_id}] calling decodeAudioData, buf byteLength=' + buf.buffer.byteLength);
|
| 1369 |
+
try {{
|
| 1370 |
+
tmpCtx.decodeAudioData(buf.buffer.slice(0), doRender, function(err) {{
|
| 1371 |
+
console.error('[waveform {slot_id}] decodeAudioData error:', err);
|
|
|
|
|
|
|
| 1372 |
}});
|
| 1373 |
+
}} catch(e) {{
|
| 1374 |
+
console.error('[waveform {slot_id}] decodeAudioData threw:', e);
|
| 1375 |
}}
|
| 1376 |
}}
|
| 1377 |
}})();
|