Problem
In the bundled (PyInstaller) service, speaker diarization fails — transcription completes but every segment is labelled UNKNOWN. The dev (non-frozen) service diarizes correctly; this is specific to the frozen build.
Surfaced while running the native macOS app (#94) end-to-end.
Root cause
torchcodec (transformers'/pyannote's audio backend) ships native libraries libtorchcodec_core{4,5,6,7}.dylib that dynamically link against FFmpeg shared libraries (libavcodec, libavformat, libavutil, libswresample, …). The bundle vendors only the static ffmpeg/ffprobe binaries (scripts/vendor_ffmpeg.sh), not the FFmpeg shared libs, so torchcodec can't dlopen any of its core libs:
pyannote/audio/core/io.py:48: UserWarning:
torchcodec is not installed correctly so built-in audio decoding will fail.
[start of libtorchcodec loading traceback]
FFmpeg version 7: Failed to load dynlib '.../torchcodec/libtorchcodec_core7.dylib'.
FFmpeg version 6: Failed to load dynlib '.../torchcodec/libtorchcodec_core6.dylib'.
...
Transcription still works because WhisperX decodes audio via the ffmpeg subprocess, but pyannote's diarization pipeline relies on torchcodec for audio I/O and degrades.
Options (pick one)
- Vendor FFmpeg shared libraries matching a torchcodec-supported version (4–7) into the bundle and make them resolvable by torchcodec (rpath/
@loader_path), in addition to the static binaries. Most faithful; heaviest.
- Route pyannote audio through the in-memory fallback — load the waveform ourselves (e.g. via the ffmpeg subprocess / soundfile) and pass pyannote a
{'waveform': tensor, 'sample_rate': int} dict, avoiding torchcodec entirely (pyannote documents this fallback in the warning).
- Swap torchcodec for torchaudio's decoder where possible / pin the audio backend so torchcodec isn't used.
Option 2 is likely the smallest, most self-contained fix.
Scope
Service-side / bundled-service packaging (local-transcription-service.md, #95) — the native macOS app is unaffected structurally; it just surfaces the degraded result. Verify with a diarization-enabled transcription (HF token set) in the frozen build after the fix.
Problem
In the bundled (PyInstaller) service, speaker diarization fails — transcription completes but every segment is labelled
UNKNOWN. The dev (non-frozen) service diarizes correctly; this is specific to the frozen build.Surfaced while running the native macOS app (#94) end-to-end.
Root cause
torchcodec(transformers'/pyannote's audio backend) ships native librarieslibtorchcodec_core{4,5,6,7}.dylibthat dynamically link against FFmpeg shared libraries (libavcodec,libavformat,libavutil,libswresample, …). The bundle vendors only the static ffmpeg/ffprobe binaries (scripts/vendor_ffmpeg.sh), not the FFmpeg shared libs, so torchcodec can'tdlopenany of its core libs:Transcription still works because WhisperX decodes audio via the ffmpeg subprocess, but pyannote's diarization pipeline relies on torchcodec for audio I/O and degrades.
Options (pick one)
@loader_path), in addition to the static binaries. Most faithful; heaviest.{'waveform': tensor, 'sample_rate': int}dict, avoiding torchcodec entirely (pyannote documents this fallback in the warning).Option 2 is likely the smallest, most self-contained fix.
Scope
Service-side / bundled-service packaging (
local-transcription-service.md, #95) — the native macOS app is unaffected structurally; it just surfaces the degraded result. Verify with a diarization-enabled transcription (HF token set) in the frozen build after the fix.