music video renderer web app deftoku.digi.rip
audio visualizer webapp
1

Configure Feed

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

optimizations: added flag to visualizers to specify whether or not they need freq data and skip extraction

- also switched from vp9 -> vp8 for faster processing speed

digi.rip (Jun 22, 2026, 1:07 AM EDT) 82eed70a 9915d625

+20 -5
+13 -5
src/output.ts
··· 22 22 fps: number, 23 23 quality: Quality, 24 24 options: VisualizerOptions = {}, 25 + audioReactive = true, 25 26 onProgress?: (current: number, total: number) => void, 26 27 ) { 27 - const frames = await extractFreqFrames(buffer, fps); 28 + const freqFrames = audioReactive 29 + ? await extractFreqFrames(buffer, fps) 30 + : null; 31 + const frameCount = audioReactive 32 + ? freqFrames!.length 33 + : Math.ceil(buffer.duration * fps); 34 + const EMPTY_FREQ = new Uint8Array(0); 28 35 29 36 const output = new Output({ 30 37 format: new WebMOutputFormat(), ··· 32 39 }); 33 40 34 41 const sourceVideo = new CanvasSource(canvas, { 35 - codec: "vp9", 42 + codec: "vp8", 36 43 bitrate: quality, 37 44 }); 38 45 ··· 46 53 47 54 await output.start(); 48 55 49 - for (let i = 0; i < frames.length; i++) { 50 - draw(canvas, frames[i], options, 1 / fps); 56 + for (let i = 0; i < frameCount; i++) { 57 + const freq = freqFrames ? freqFrames[i] : EMPTY_FREQ; 58 + draw(canvas, freq, options, 1 / fps); 51 59 await sourceVideo.add(i / fps, 1 / fps); 52 - onProgress?.(i + 1, frames.length); 60 + onProgress?.(i + 1, frameCount); 53 61 } 54 62 sourceVideo.close(); 55 63
+2
src/ui/render.ts
··· 89 89 fps, 90 90 quality, 91 91 getOpts(), 92 + def.audioReactive, 92 93 (current, total) => { 93 94 overlay.textContent = `${Math.round((current / total) * 100)}%`; 94 95 }, ··· 111 112 fps, 112 113 quality, 113 114 getOpts(), 115 + def.audioReactive, 114 116 (current, total) => { 115 117 overlay.textContent = `${Math.round((current / total) * 100)}%`; 116 118 },
+5
src/visualizers/index.ts
··· 55 55 inputStyle?: Partial<CSSStyleDeclaration>; 56 56 }>; 57 57 category: string; 58 + audioReactive: boolean; 58 59 default?: boolean; 59 60 }; 60 61 ··· 64 65 params: asciiBarsParams, 65 66 preview: asciiBarsPreview, 66 67 category: asciiBarsCategory, 68 + audioReactive: true, 67 69 }, 68 70 bars: { 69 71 draw: bars, 70 72 params: barsParams, 71 73 preview: barsPreview, 72 74 category: barsCategory, 75 + audioReactive: true, 73 76 }, 74 77 cdbottom: { 75 78 draw: cdbottom, 76 79 params: cdbottomParams, 77 80 preview: cdbottomPreview, 78 81 category: cdbottomCategory, 82 + audioReactive: false, 79 83 }, 80 84 cdtop: { 81 85 draw: cdtop, 82 86 params: cdtopParams, 83 87 preview: cdtopPreview, 84 88 category: cdtopCategory, 89 + audioReactive: false, 85 90 default: true, 86 91 }, 87 92 };