fix: audio playback broken — wrong directory and .wav/.ogg mismatch #11

Closed
opened 2026-04-16 13:17:31 +00:00 by salmaelsoly · 4 comments
Member

Audio directory mismatch

hero_proc launches hero_voice_ui with its own cwd. The WebSocket handler in ws.rs:227 uses a client-provided relative path (data/audio) to write audio files, which resolves against hero_proc's cwd. But ServeDir in main.rs:138 serves from the absolute data_dir() path (~/hero/var/voice/audio/). Files are written to one location, served from another — playback returns 404.

.wav/.ogg filename mismatch

register_audio_via_rpc in ws.rs:144 registers the .wav filename. Then convert_in_background converts the file to .ogg and deletes the original .wav. The UI requests the .wav filename from but only the .ogg file exists on disk — playback fails with "no supported source found".

Screenshot from 2026-04-16 13-41-37

## Audio directory mismatch hero_proc launches hero_voice_ui with its own cwd. The WebSocket handler in `ws.rs:227` uses a client-provided relative path (`data/audio`) to write audio files, which resolves against hero_proc's cwd. But `ServeDir` in `main.rs:138` serves from the absolute `data_dir()` path (`~/hero/var/voice/audio/`). Files are written to one location, served from another — playback returns 404. ## .wav/.ogg filename mismatch `register_audio_via_rpc` in `ws.rs:144` registers the `.wav` filename. Then `convert_in_background` converts the file to `.ogg` and deletes the original `.wav`. The UI requests the `.wav` filename from but only the `.ogg` file exists on disk — playback fails with "no supported source found". ![Screenshot from 2026-04-16 13-41-37](/attachments/84b14725-62ce-427e-8870-9758b00e40bf)
Author
Member

same issue of wav and ogg mismatch when deleting audio

same issue of wav and ogg mismatch when deleting audio
Author
Member

Implementation Spec for Issue #11

Objective

Fix audio playback failures caused by two distinct issues:

  1. Directory mismatch: Audio files are written to a relative path (data/audio/{topic_sid}) that resolves against the process's current working directory, but ServeDir serves from an absolute path (~/hero/var/voice/audio/).
  2. Extension mismatch: Audio is registered with .wav extension but converted to .ogg (with the original .wav deleted), causing playback to fail because the registered filename no longer exists.

Requirements

  • Audio files must be written to the same directory that ServeDir serves from (~/hero/var/voice/audio/{topic_sid})
  • voiceservice.get_audio_path must return an absolute path that is consistent with where the UI server expects files
  • Audio must be registered with .ogg extension after conversion completes, not .wav before conversion
  • voiceservice.delete_audio must handle the .ogg extension correctly
  • Existing audio files should continue to work (backward compatibility for any .wav files that may exist)
  • No breaking changes to the JSON-RPC API signatures

Files to Modify

File Purpose
crates/hero_voice/src/voice/server/rpc.rs Fix DATA_DIR usage and delete_audio to handle both .wav and .ogg
crates/hero_voice_ui/src/ws.rs Register audio with .ogg extension after conversion completes

Implementation Plan

Step 1: Fix the data directory path resolution in rpc.rs

File: crates/hero_voice/src/voice/server/rpc.rs

  • Replace the relative DATA_DIR constant with a function that returns an absolute path
  • The current code uses const DATA_DIR: &str = "data"; which creates relative paths
  • Add a data_dir() function that returns ~/hero/var/voice (or reads from HERO_VOICE_DATA env var), matching the logic in hero_voice_ui/src/main.rs
  • Update audio_dir_for() and transforms_dir_for() to use the new absolute path function

Step 2: Fix delete_audio to handle both .wav and .ogg files

File: crates/hero_voice/src/voice/server/rpc.rs

  • First try to delete the file with the exact filename provided
  • If that fails and the filename ends with .wav, try the .ogg version
  • If that fails and the filename ends with .ogg, try the .wav version
  • Provides backward compatibility for existing .wav files while also handling the new .ogg files correctly

Step 3: Register audio with .ogg extension after conversion completes

File: crates/hero_voice_ui/src/ws.rs

  • In stop_register_convert, change the filename from .wav to .ogg before calling register_audio_via_rpc
  • Update the format parameter from "wav" to "ogg"

Acceptance Criteria

  • Audio files are written to ~/hero/var/voice/audio/{topic_sid}/ regardless of where hero_proc starts the server
  • voiceservice.get_audio_path returns an absolute path
  • ServeDir at /files/audio successfully serves audio files after recording
  • Audio is registered with .ogg extension, matching the final file on disk
  • Playback via the audio player works without 404 errors
  • Playback via the audio player works without "no supported source found" errors
  • voiceservice.delete_audio successfully deletes .ogg files
  • Backward compatibility: existing .wav files (if any) can still be deleted

Notes

  • When hero_proc launches hero_voice_ui, the working directory may be different from where the code expects. The fix ensures all paths are absolute, eliminating this dependency.
  • The implementation honors HERO_VOICE_DATA environment variable if set, falling back to ~/hero/var/voice, matching the existing convention in hero_voice_ui/src/main.rs.
  • After implementing Step 3, the size field in the AudioFileInfo will reflect the original .wav size, not the compressed .ogg size. This is acceptable for display purposes.
## Implementation Spec for Issue #11 ### Objective Fix audio playback failures caused by two distinct issues: 1. **Directory mismatch**: Audio files are written to a relative path (`data/audio/{topic_sid}`) that resolves against the process's current working directory, but `ServeDir` serves from an absolute path (`~/hero/var/voice/audio/`). 2. **Extension mismatch**: Audio is registered with `.wav` extension but converted to `.ogg` (with the original `.wav` deleted), causing playback to fail because the registered filename no longer exists. --- ### Requirements - Audio files must be written to the same directory that `ServeDir` serves from (`~/hero/var/voice/audio/{topic_sid}`) - `voiceservice.get_audio_path` must return an absolute path that is consistent with where the UI server expects files - Audio must be registered with `.ogg` extension after conversion completes, not `.wav` before conversion - `voiceservice.delete_audio` must handle the `.ogg` extension correctly - Existing audio files should continue to work (backward compatibility for any `.wav` files that may exist) - No breaking changes to the JSON-RPC API signatures --- ### Files to Modify | File | Purpose | |------|---------| | `crates/hero_voice/src/voice/server/rpc.rs` | Fix `DATA_DIR` usage and `delete_audio` to handle both `.wav` and `.ogg` | | `crates/hero_voice_ui/src/ws.rs` | Register audio with `.ogg` extension after conversion completes | --- ### Implementation Plan #### Step 1: Fix the data directory path resolution in `rpc.rs` **File**: `crates/hero_voice/src/voice/server/rpc.rs` - Replace the relative `DATA_DIR` constant with a function that returns an absolute path - The current code uses `const DATA_DIR: &str = "data";` which creates relative paths - Add a `data_dir()` function that returns `~/hero/var/voice` (or reads from `HERO_VOICE_DATA` env var), matching the logic in `hero_voice_ui/src/main.rs` - Update `audio_dir_for()` and `transforms_dir_for()` to use the new absolute path function #### Step 2: Fix `delete_audio` to handle both `.wav` and `.ogg` files **File**: `crates/hero_voice/src/voice/server/rpc.rs` - First try to delete the file with the exact filename provided - If that fails and the filename ends with `.wav`, try the `.ogg` version - If that fails and the filename ends with `.ogg`, try the `.wav` version - Provides backward compatibility for existing `.wav` files while also handling the new `.ogg` files correctly #### Step 3: Register audio with `.ogg` extension after conversion completes **File**: `crates/hero_voice_ui/src/ws.rs` - In `stop_register_convert`, change the filename from `.wav` to `.ogg` before calling `register_audio_via_rpc` - Update the format parameter from `"wav"` to `"ogg"` --- ### Acceptance Criteria - [ ] Audio files are written to `~/hero/var/voice/audio/{topic_sid}/` regardless of where `hero_proc` starts the server - [ ] `voiceservice.get_audio_path` returns an absolute path - [ ] `ServeDir` at `/files/audio` successfully serves audio files after recording - [ ] Audio is registered with `.ogg` extension, matching the final file on disk - [ ] Playback via the audio player works without 404 errors - [ ] Playback via the audio player works without "no supported source found" errors - [ ] `voiceservice.delete_audio` successfully deletes `.ogg` files - [ ] Backward compatibility: existing `.wav` files (if any) can still be deleted --- ### Notes - When `hero_proc` launches `hero_voice_ui`, the working directory may be different from where the code expects. The fix ensures all paths are absolute, eliminating this dependency. - The implementation honors `HERO_VOICE_DATA` environment variable if set, falling back to `~/hero/var/voice`, matching the existing convention in `hero_voice_ui/src/main.rs`. - After implementing Step 3, the `size` field in the `AudioFileInfo` will reflect the original `.wav` size, not the compressed `.ogg` size. This is acceptable for display purposes.
Author
Member

Implementation Complete

Test Results

test result: ok. 13 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

All tests pass.

Changes Made

1. Fixed data directory path in rpc.rs

  • Replaced hardcoded const DATA_DIR: &str = "data" with data_dir() function
  • Returns absolute path: ~/hero/var/voice (or HERO_VOICE_DATA env var)
  • Updated audio_dir_for() and transforms_dir_for() to use the new function

2. Fixed delete_audio for .wav/.ogg extension mismatch

  • Now tries exact filename first
  • Falls back to alternate extension (.wav.ogg)
  • Matches metadata by base filename (without extension)

3. Fixed audio registration in ws.rs

  • stop_register_convert() now registers with .ogg extension
  • Matches what convert_in_background() produces

Files Modified

  • crates/hero_voice/src/voice/server/rpc.rs
  • crates/hero_voice_ui/src/ws.rs

Ready for PR.

## Implementation Complete ### Test Results ``` test result: ok. 13 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out ``` All tests pass. ### Changes Made **1. Fixed data directory path in `rpc.rs`** - Replaced hardcoded `const DATA_DIR: &str = "data"` with `data_dir()` function - Returns absolute path: `~/hero/var/voice` (or `HERO_VOICE_DATA` env var) - Updated `audio_dir_for()` and `transforms_dir_for()` to use the new function **2. Fixed `delete_audio` for `.wav/.ogg` extension mismatch** - Now tries exact filename first - Falls back to alternate extension (`.wav` ↔ `.ogg`) - Matches metadata by base filename (without extension) **3. Fixed audio registration in `ws.rs`** - `stop_register_convert()` now registers with `.ogg` extension - Matches what `convert_in_background()` produces ### Files Modified - `crates/hero_voice/src/voice/server/rpc.rs` - `crates/hero_voice_ui/src/ws.rs` Ready for PR.
Author
Member

Acceptance Criteria Verification

1. Audio directory mismatch

  • ws.rs defaults to state.data_dir.join("audio")~/hero/var/voice/audio
  • rpc.rs now uses data_dir()~/hero/var/voice
  • ServeDir serves from same absolute path
  • All paths aligned

2. .wav/.ogg filename mismatch

  • register_audio_via_rpc now registers .ogg extension
  • Matches convert_in_background() output
  • UI requests .ogg which exists on disk

Both issues from the original report are resolved. PR #15 ready for merge.

## Acceptance Criteria Verification **1. Audio directory mismatch** ✅ - `ws.rs` defaults to `state.data_dir.join("audio")` → `~/hero/var/voice/audio` - `rpc.rs` now uses `data_dir()` → `~/hero/var/voice` - `ServeDir` serves from same absolute path - All paths aligned **2. .wav/.ogg filename mismatch** ✅ - `register_audio_via_rpc` now registers `.ogg` extension - Matches `convert_in_background()` output - UI requests `.ogg` which exists on disk Both issues from the original report are resolved. PR #15 ready for merge.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_voice#11
No description provided.