9 Commits

Author SHA1 Message Date
fegger 79f1a7ec6e Swap app icon to the v3 design (record button + transcript mic)
- new icon source in icon/ (make_icon_v3.py + masters): near-black
  gradient tile, red record button with white bezel, mic capsule as a
  transcript card with red lines and a cursor
- Android: adaptive icon uses the 512px master as the full-bleed
  background layer (launcher masks crop it to shape) with a transparent
  foreground; old vector foreground and launcher color removed
- desktop: hicolor PNGs replaced at 32-512 px (48 regenerated from the
  master), old SVG removed; install.sh picks them up unchanged
- APK installed on the Fairphone; aapt2 confirms the adaptive icon
2026-09-09 10:19:09 +02:00
fegger 76cf992373 Desktop GUI: Library tab with live sync to the server
- new Record/Library tabs (like the mobile app); the recording UI is
  unchanged inside the Record tab
- Library tab: recording list (date, duration, language, device), detail
  view with summary (scrollable, re-triggerable), agenda checklist with
  coverage marks, and the full timestamped transcript; Library URL field
  (defaults to MEETREC_LIBRARY_URL)
- sync: auto-refresh every 10 s — recordings made on the phone appear on
  the desktop while the tab is open; pending summaries update to done
  automatically and re-fetch
- shared library client in meetrec.py: library_list/library_get_file/
  library_trigger_summary
- validated headlessly (offscreen) against the live server: 6 recordings
  from phone and desktop listed, 68-min meeting detail with 1333-char
  summary and ~100k-char transcript
2026-09-08 21:37:17 +02:00
fegger c4b86213d4 Desktop: M3 feature parity with the Android app
- final_transcribe gains optional speaker labeling and library upload:
  diarize_url runs a second tinydiarize pass and merges the turn times
  onto the quality transcript as 'Sprecher 1/2:' labels (diarize_merge,
  port of the Android Diarization object; failures keep the transcript
  unlabeled); library_url uploads the WAV + txt/srt/json bundle with the
  agenda — the server then generates summary + agenda coverage
- WhisperServerEngine supports diarize mode (tinydiarize form field +
  speaker_turn_next parsing); multipart builder handles multiple files
- CLI: --agenda-file, --diarize-url, --library-url (env vars
  MEETREC_DIARIZE_URL / MEETREC_LIBRARY_URL)
- GUI: Library URL + Diarize URL fields and an agenda editor; upload
  progress lands in the status bar
- validated end-to-end against the live servers: recording -> large-v3
  transcription -> txt/srt/json -> library upload (all four files,
  device=desktop) -> server summary/agenda pipeline ran (honest error
  for a noise-only test recording)
2026-09-08 21:04:53 +02:00
fegger a1df9d4037 Add whisper-server engine: transcribe on a remote whisper.cpp server
- WhisperServerEngine posts multipart/form-data to POST /inference
  (verbose_json) with the same transcribe() contract as the other
  engines, so live and final passes work unchanged; stdlib-only
  multipart builder; HTTP and connection errors surface clean messages
- CLI: --engine whisper-server + --server-url (or MEETREC_SERVER_URL)
- GUI: engine dropdown gains whisper-server; model/device/compute grey
  out (the server owns the model), new Server URL field
- model lives server-side, beam size is a server-start setting in
  whisper.cpp v1.9.3 (documented); verbose_json reports language names
  (german) rather than ISO codes
- validated against the live R9700 server over Tailscale: array input,
  native-rate file input (server-side resample), full final_transcribe
  pipeline, and unreachable-server handling
2026-09-07 12:59:14 +02:00
fegger e5ec95a5fb Add app icon (mic + waveform) and fix desktop categories
- share/icons/hicolor/: SVG source + PNG fallbacks (48-256 px); the
  desktop entry now uses Icon=meetrec instead of a stock theme icon
- install.sh installs the icon into the hicolor tree, refreshes the
  GTK icon cache, and cleans up on uninstall
- Categories fixed to AudioVideo;Audio per the menu spec (bare Audio
  is a subcategory requiring its main category); desktop-file-validate
  is clean now
2026-09-07 11:09:00 +02:00
fegger e14a6bfe9f Record at the input device's native sample rate
- Recorder queries default_samplerate and streams/WAVs at that rate
  instead of forcing 16 kHz (helps devices that don't support it
  natively and keeps recordings at full fidelity)
- new resample_16k() linear resampler: the live rolling window is
  converted to Whisper's 16 kHz before being handed to the engines
- snapshot() now returns (16 kHz audio, absolute start time in s)
- final pass unchanged: faster-whisper (PyAV) and whisper.cpp
  (miniaudio) resample native-rate WAVs themselves
- GUI status shows the active rate; README updated

Validated with real 44.1 kHz and 48 kHz inputs: WAV headers match the
device rate, live-window resampling is length- and spectrum-correct.
2026-09-07 11:04:53 +02:00
fegger 404f3db200 Add native Android app scaffold (M0): whisper.cpp engine via JNI
- android/: Gradle/Kotlin project (AGP 9.4, Compose, NDK 27.1), monorepo
  subdir as planned; whisper.cpp v1.9.3 vendored via pinned fetch script
- core/whisper: JNI wrapper (beam size, threads, language) + WhisperEngine
  Kotlin API mirroring the desktop engine contract
- app (M0 scope): in-app GGML model download from Hugging Face, engine
  load, WAV picker with resampling, on-device transcription, share sheet
- build validated: assembleDebug OK, libwhisper_jni.so + ggml packaged
2026-09-07 11:00:31 +02:00
fegger 66408e291d Add whisper.cpp engine with Vulkan GPU support (AMD/Intel/NVIDIA)
- meetrec.py: engine layer with a common transcribe() contract;
  WhisperCppEngine shells out to whisper-cli, GGML + Silero VAD models
  auto-download to ~/.cache/meetrec; faster-whisper import now lazy;
  new --engine CLI option
- meetrec_gui.py: Engine dropdown; Device/Compute greyed out for
  whisper-cpp; model reload keyed on (engine, model, device, compute)
- install.sh: --whisper-cpp builds whisper.cpp with -DWHISPER_VULKAN=ON,
  installs whisper-cli into the prefix and wires WHISPER_CPP_BIN via a
  generated whisper-cpp.env; build failures degrade to a warning
- launchers source whisper-cpp.env; README documents engines
- Recorder.stop() is now idempotent (GUI close path called it twice)
2026-09-07 10:36:55 +02:00
fegger 18ce1c134c Initial commit: MeetRec — record & transcribe meetings with Whisper
- meetrec.py: CLI recorder with live rolling transcript (faster-whisper)
- meetrec_gui.py: PySide6 GUI reusing the CLI's recording/transcription
  logic, with model/device/compute selection and live transcript
- install.sh: local install into ~/.local (venv, deps, launchers,
  desktop entry), with --model/--no-model/--uninstall
- bin/meetrec, bin/meetrec-cli: launchers
- share/applications/meetrec.desktop: XDG desktop entry
- README.md, requirements.txt, .gitignore
2026-09-07 09:38:32 +02:00