Live video on the AT Protocol
79
fork

Configure Feed

Select the types of activity you want to include in your feed.

at eli/github-skip-darwin 86 lines 2.4 kB view raw
1export const QUIET_PROFILE = "audible"; 2 3export async function quietReceiver( 4 mediaStream: MediaStream, 5 playerEvent: (time: string, eventType: string, data: any) => void, 6) { 7 let audioTime = 0; 8 let videoTime = 0; 9 let baseline = 0; 10 11 const diff = (a: number, b: number) => { 12 if (audioTime === 0 || videoTime === 0) { 13 return; 14 } 15 if (baseline === 0) { 16 baseline = audioTime - videoTime; 17 console.log("baseline", baseline); 18 } 19 console.log("diff", audioTime - videoTime - baseline); 20 playerEvent(new Date().toISOString(), "av-sync", { 21 diff: audioTime - videoTime - baseline, 22 }); 23 }; 24 25 const gotVideo = (time: number) => { 26 console.log("video", time); 27 videoTime = time; 28 // diff(audioTime, videoTime); 29 }; 30 31 const gotAudio = (time: number) => { 32 console.log("audio", time); 33 audioTime = time; 34 diff(audioTime, videoTime); 35 }; 36 37 const Quiet = await import("quietjs-bundle"); 38 Quiet.addReadyCallback(() => { 39 const nav = navigator as unknown as any; 40 // quiet doesn't let us pass in a mediaStream so we need to monkeypatch getusermedia 41 const getUserMedia = nav.getUserMedia; 42 nav.getUserMedia = async (constraints, cb) => { 43 cb(mediaStream); 44 console.log("quiet got user media"); 45 // we're done, unmonkeypatch 46 nav.getUserMedia = getUserMedia; 47 }; 48 const quiet = Quiet.receiver({ 49 profile: QUIET_PROFILE, 50 onReceive: (payload) => { 51 try { 52 const str = Quiet.ab2str(payload); 53 const time = parseInt(str); 54 gotAudio(time); 55 } catch (e) { 56 console.error("quiet receiver error", e); 57 } 58 }, 59 onCreate: () => { 60 console.log("receiver created"); 61 }, 62 onCreateFail: (error) => { 63 console.error("receiver failed to create", error); 64 }, 65 onReceiveFail: (error) => { 66 console.error("receiver failed to receive", error); 67 }, 68 // onReceiverStatsUpdate: (stats) => { 69 // console.log("receiver stats", stats); 70 // }, 71 }); 72 }); 73 74 const zxing = await import("@zxing/browser"); 75 const codeReader = new zxing.BrowserQRCodeReader(); 76 codeReader.decodeFromStream(mediaStream, undefined, (result, err) => { 77 try { 78 if (result) { 79 const time = parseInt(result.getText()); 80 gotVideo(time); 81 } 82 } catch (e) { 83 console.error("zxing error", e); 84 } 85 }); 86}