(function () { const logEl = document.getElementById('log'); function log(msg, type) { const line = document.createElement('div'); line.className = type || 'sys'; line.textContent = '[' + new Date().toLocaleTimeString() + '] ' + msg; logEl.appendChild(line); logEl.scrollTop = logEl.scrollHeight; } function fileToBase64(file) { return new Promise(function (resolve, reject) { const reader = new FileReader(); reader.onload = function () { const dataUrl = reader.result; const i = String(dataUrl).indexOf(','); resolve(i >= 0 ? dataUrl.slice(i + 1) : dataUrl); }; reader.onerror = reject; reader.readAsDataURL(file); }); } function showDataUrl(imgEl, mimetype, dataBase64) { if (!dataBase64) return; imgEl.src = 'data:' + (mimetype || 'image/webp') + ';base64,' + dataBase64; imgEl.hidden = false; var stage = imgEl.closest('.bs-stage'); if (stage) stage.hidden = false; } function setButtons(enabled) { ['probe', 'transform', 'extract', 'transcode'].forEach(function (id) { document.getElementById(id).disabled = !enabled; }); } function initWhenReady(attempts) { if (attempts >= 50) { log('BridgeSwarm not available. Install extension and reload.', 'err'); return; } if (typeof window.BridgeSwarm === 'undefined') { setTimeout(function () { initWhenReady(attempts + 1); }, 100); return; } window.BridgeSwarm.ready().then(async function () { const hasMedia = await window.BridgeSwarm.capabilities.has('media'); const packs = await window.BridgeSwarm.capabilities.list(); log('Capability packs: ' + (packs.length ? packs.join(', ') : '(none)')); if (!hasMedia) { document.getElementById('missing').hidden = false; setButtons(false); log('Rebuild/reinstall the default host (media/ffmpeg is included by default).', 'err'); return; } document.getElementById('ready').hidden = false; setButtons(true); log('Media pack ready.', 'val'); async function currentUpload() { const file = document.getElementById('file').files[0]; if (!file) throw new Error('Choose a file first'); if (file.size > 12 * 1024 * 1024) { throw new Error('Demo limit: keep uploads under ~12 MB (NMH / base64)'); } const dataBase64 = await fileToBase64(file); return { file: file, dataBase64: dataBase64 }; } document.getElementById('probe').onclick = async function () { try { const up = await currentUpload(); const r = await window.BridgeSwarm.media.info({ dataBase64: up.dataBase64, filename: up.file.name, }); log('info: ' + JSON.stringify(r, null, 0).slice(0, 400), 'val'); } catch (e) { log(e.message, 'err'); } }; document.getElementById('transform').onclick = async function () { try { const up = await currentUpload(); if (!up.file.type.startsWith('image/')) { log('Pick an image for transform (or use extract frame for video).', 'err'); return; } log('Transforming…'); const r = await window.BridgeSwarm.media.imageTransform({ dataBase64: up.dataBase64, filename: up.file.name, maxWidth: 640, maxHeight: 640, mimetype: 'image/webp', }); showDataUrl(document.getElementById('preview'), r.mimetype, r.dataBase64); log('imageTransform ok (' + (r.dataBase64 ? r.dataBase64.length : 0) + ' b64 chars)', 'val'); } catch (e) { log(e.message, 'err'); } }; document.getElementById('extract').onclick = async function () { try { const up = await currentUpload(); if (!up.file.type.startsWith('video/')) { log('Pick a video for frame extract.', 'err'); return; } const frameIndex = Number(document.getElementById('frameIndex').value) || 0; log('Extracting frame ' + frameIndex + '…'); const r = await window.BridgeSwarm.media.extractFrame({ dataBase64: up.dataBase64, filename: up.file.name, frameIndex: frameIndex, mimetype: 'image/webp', }); showDataUrl(document.getElementById('frame'), r.mimetype, r.dataBase64); log('extractFrame ok', 'val'); } catch (e) { log(e.message, 'err'); } }; document.getElementById('transcode').onclick = async function () { const progressEl = document.getElementById('progress'); try { const up = await currentUpload(); if (!up.file.type.startsWith('video/')) { log('Pick a video to transcode.', 'err'); return; } log('Transcoding to webm (may take a while)…'); progressEl.textContent = 'starting…'; const r = await window.BridgeSwarm.media.transcode( { dataBase64: up.dataBase64, filename: up.file.name, format: 'webm', width: 640, height: 360, }, { timeoutMs: 300000, onProgress: function (p) { progressEl.textContent = p.bytes ? (Math.round(p.bytes / 1024) + ' KB written') : '…'; }, } ); progressEl.textContent = 'done (' + (r.path || '') + ')'; log('transcode finished: ' + (r.path || JSON.stringify(r)), 'val'); if (r.path) { const read = await window.BridgeSwarm.media.readOutput({ path: r.path, mimetype: 'video/webm', }); const video = document.getElementById('outVideo'); video.src = 'data:video/webm;base64,' + read.dataBase64; video.hidden = false; var stage = document.getElementById('videoStage'); if (stage) stage.hidden = false; } } catch (e) { progressEl.textContent = ''; log(e.message, 'err'); } }; }).catch(function (e) { log(e.message, 'err'); }); } initWhenReady(0); })();