Preview compatible fragmented MP4 transfers while saving the verified copy

This commit is contained in:
Jonathan Sykes
2026-10-03 20:43:03 +08:00
parent 795a5aaed4
commit 5661eea6e6
7 changed files with 67 additions and 4 deletions

View File

@@ -16,7 +16,7 @@
if (!file) throw Error('Save this song on this device before sending it');
const hash = root.Sha256.create();
for (let at = 0; at < file.size; at += 1024 * 1024) hash.update(new Uint8Array(await file.slice(at, at + 1024 * 1024).arrayBuffer()));
const claim = root.DirectProtocol.file({ ...meta, cid: hash.hex(), size: file.size, title: meta.title || meta.id });
const claim = root.DirectProtocol.file({ ...meta, cid: hash.hex(), size: file.size, extension: file.name.split('.').pop().toLowerCase(), streamMime: await root.DirectStream?.inspect(file), title: meta.title || meta.id });
if (!claim) throw Error('Unsupported file metadata');
pending.set(`${key}:${to}:${claim.id}`, { file, claim });
send(key, { type: 'direct', action: 'invite', to, file: claim });
@@ -25,6 +25,7 @@
function finish(s, error) {
if (s.done) return; s.done = true; clearTimeout(s.timer); clearTimeout(s.idle);
s.pc?.close(); transfers.delete(s.token);
if (error) s.preview?.close(); else s.preview?.end();
if (s.worker) { s.worker.postMessage({ op: 'abort' }); setTimeout(() => s.worker.terminate(), 1000); }
if (error) { waiting.get(s.claim.id)?.resolve(false); waiting.delete(s.claim.id); hooks.notify(`${error}. Partial copy kept for resume.`); hooks.fallback(s.claim, () => offer(s.key, s.peer, s.claim).catch(e => hooks.notify(e.message))); }
}
@@ -44,7 +45,7 @@
try {
if (receiver) {
if (typeof e.data === 'string') { const m = JSON.parse(e.data); if (m.t === 'end') s.worker.postMessage({ op: 'finish' }); else throw Error('Unexpected file control'); }
else s.worker.postMessage({ op: 'chunk', buf: e.data }, [e.data]);
else { s.preview?.push(e.data); s.worker.postMessage({ op: 'chunk', buf: e.data }, [e.data]); }
} else {
if (typeof e.data !== 'string' || s.started) throw Error('Unexpected file request');
const m = JSON.parse(e.data); if (m.t !== 'get') throw Error('Unexpected file request');
@@ -69,6 +70,7 @@
}
async function accept(key, m) {
const s = { key, token: m.token, claim: m.file, peer: m.from, receiver: true }; transfers.set(m.token, s);
s.preview = m.file.streamMime ? root.DirectStream?.create(m.file.streamMime, m.file.title) : null;
connection(s, true);
s.worker = new Worker('/direct-recv-worker.js');
s.worker.onmessage = async e => {