178 lines
6.2 KiB
JavaScript
178 lines
6.2 KiB
JavaScript
(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);
|
|
})();
|