feat: 1-to-1 message render + web data-lake backend

This commit is contained in:
h
2026-05-31 01:27:40 +02:00
parent f0afb7ec5b
commit 75425d1bee
110 changed files with 10199 additions and 54 deletions
+14
View File
@@ -0,0 +1,14 @@
let current: HTMLMediaElement | null = null;
export function claimPlayback(element: HTMLMediaElement) {
if (current && current !== element) {
current.pause();
}
current = element;
}
export function releasePlayback(element: HTMLMediaElement) {
if (current === element) {
current = null;
}
}
+36
View File
@@ -0,0 +1,36 @@
const BARS = 48;
const MIN_BAR = 0.08;
export async function computeWaveform(
url: string,
bars = BARS
): Promise<number[]> {
const response = await fetch(url);
const buffer = await response.arrayBuffer();
const ctx = new AudioContext();
try {
const audio = await ctx.decodeAudioData(buffer);
const data = audio.getChannelData(0);
const block = Math.max(1, Math.floor(data.length / bars));
const peaks: number[] = [];
for (let i = 0; i < bars; i++) {
const start = i * block;
let max = 0;
for (let j = 0; j < block; j++) {
const value = Math.abs(data[start + j] ?? 0);
if (value > max) {
max = value;
}
}
peaks.push(max);
}
const norm = Math.max(...peaks, 0.0001);
return peaks.map((peak) => Math.max(MIN_BAR, peak / norm));
} finally {
await ctx.close();
}
}
export function flatWaveform(bars = BARS): number[] {
return Array.from({ length: bars }, () => 0.3);
}