Files
kapteins-daagbok/client/src/utils/audioBlob.ts
T
elpatron 975c7a2e40 Add voice memos to live journal and event log.
Record short E2E-encrypted audio attachments from the live log, link them to events via __live:voice markers, and play them back in the stream and chronological event table.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-03 14:52:12 +02:00

40 lines
1.1 KiB
TypeScript

export const VOICE_MEMO_MAX_DURATION_SEC = 60
export const VOICE_MEMO_MAX_BLOB_BYTES = 800_000
const MIME_CANDIDATES = [
'audio/webm;codecs=opus',
'audio/webm',
'audio/mp4',
'audio/ogg;codecs=opus'
]
export function pickMediaRecorderMimeType(): string | undefined {
if (typeof MediaRecorder === 'undefined') return undefined
for (const mime of MIME_CANDIDATES) {
if (MediaRecorder.isTypeSupported(mime)) return mime
}
return undefined
}
export function blobToAudioDataUrl(blob: Blob): Promise<string> {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onload = () => resolve(String(reader.result))
reader.onerror = () => reject(new Error('audio_read_failed'))
reader.readAsDataURL(blob)
})
}
export function formatVoiceDuration(seconds: number): string {
const s = Math.max(0, Math.floor(seconds))
const m = Math.floor(s / 60)
const r = s % 60
return `${m}:${String(r).padStart(2, '0')}`
}
export function assertVoiceMemoBlobSize(blob: Blob): void {
if (blob.size > VOICE_MEMO_MAX_BLOB_BYTES) {
throw new Error('VOICE_MEMO_TOO_LARGE')
}
}