OBS Replay Buffer Export Has Video but Zero-Duration Audio for Whisper VOD Triage - How to Fix
Problem: A facilitator saves an OBS Replay Buffer clip into playtest-vod/inbox/. The MKV plays video in VLC, but your nightly ffmpeg extract produces silence or a 0-byte WAV, and Whisper returns an empty transcript. ffprobe reports no audio stream or duration=N/A on the audio track.
Who is affected now: Teams running the June 2026 local Whisper playtest VOD triage stack on Windows 11 facilitator laptops. Replay Buffer is the default “last 2 minutes” capture in community playtest ops—but video-only Replay is a common misconfiguration, not a Whisper bug. This is capture, not CUDA silent CPU fallback or API 413 chunking.
Fastest safe fix: Run ffprobe on the inbox file before Whisper → if audio missing or duration < 1 s, fix OBS Settings → Audio (desktop + mic tracks, same profile as Replay Buffer) → save a 10 s smoke Replay → re-extract mono 16 kHz WAV → confirm Whisper text on smoke → set audio_stream_ok: true and gates.T2_audio: true in playtest_vod_triage_receipt_v1.json → add facilitator OBS checklist to playtest-vod/README.md.
Direct answer
Replay Buffer writes whatever OBS is configured to mux. If the active profile disables global audio, routes game audio to an unmonitored track, or uses Advanced Output with no audio track in the Replay muxer, you get video-only MKV. Whisper has nothing to transcribe; empty output is correct behavior.
Why this issue spikes in June 2026
- Replay Buffer adoption — Playtest ops lists push Replay over full-session upload; facilitators clone OBS “streaming” profiles that mute game audio on Track 2 only.
- Whisper batch gates — Pipelines now fail closed on
T2_audioinstead of filing blank issues. - MKV vs MP4 assumptions — Teams assume “if VLC plays, Whisper works”—VLC shows video while audio track is absent.
- Separate devices — Discord voice on a different device than Desktop Audio capture.
- Fest-week volume — More clips per night; one bad OBS template poisons the whole inbox batch.
Symptoms and search phrases
ffprobeshows onlycodec_type=videostreams.- Audio stream exists but
duration=0.000000orN/A. ffmpeg -vnextract: no output or WAV < 1 s for a 2-minute clip.- Whisper / faster-whisper:
text=""with no error. - OBS Replay Buffer saved indicator flashes; meters looked fine live but file is silent.
- Recent change: new OBS profile for “clean stream” with audio tracks unchecked.
- Batch log: all clips fail
T2_audiowhileT1_ingestpasses.
Root causes (check in order)
- Global audio disabled in OBS profile used for Replay.
- Replay Buffer uses a profile where Tracks 1–6 matrix excludes desktop/game audio.
- Advanced Output — Replay muxer set to video only or wrong track checkbox.
- Wrong capture device — game on HDMI/VR headset not routed to monitored source.
- Separate audio device — Discord on headset OBS does not capture.
- Save after crash — partial MKV with truncated audio (rare; re-save smoke).
- Post-processing — facilitator ran tool that stripped audio before inbox drop.
Beginner path (first 30 minutes)
Prerequisites: OBS Studio 30+, one playtest station, ffmpeg/ffprobe on PATH, playtest-vod/inbox/ folder.
- Pick a failed MKV from inbox (do not delete).
- Run ffprobe gate (Step 2 below)—note stream list.
- Open OBS → Settings → Audio → confirm Desktop Audio and Mic/Aux devices.
- Settings → Output → Replay Buffer — confirm format includes audio (see Step 3).
- Record 10 s of desktop audio + mic test → Save Replay → ffprobe again.
- If smoke passes → re-run one real clip through extract + Whisper smoke.
Common mistake: Testing in OBS Preview with meters moving but Replay profile is a different scene collection without audio sources.
Fastest safe fix path
Step 1 — OBS profile audio checklist
| Setting | Pass |
|---|---|
| Settings → Audio → Desktop Audio | Device matches game output (Speakers/Headset) |
| Settings → Audio → Mic/Aux | Correct mic if voice needed in triage |
| Advanced Audio Properties (gear on source) | Tracks 1–2 enabled for game + mic as needed |
| Mixer meters move during Replay test | Yes, both game and voice if required |
| Profile used for playtest | Documented in playtest-vod/README.md |
Official reference: OBS Audio Guide, Replay Buffer.
Step 2 — ffprobe gate before Whisper (fail closed)
ffprobe -v error -show_entries stream=codec_type,codec_name,duration `
-of json "playtest-vod/inbox/2026-05-24_build-playtest-03_surface-playtest_replay.mkv"
Pass criteria:
| Signal | Pass |
|---|---|
At least one stream with "codec_type": "audio" |
Yes |
Audio duration ≥ 1.0 (or within 5% of video duration) |
Yes |
Audio codec_name not none |
Yes |
Fail: Skip Whisper for that file; move to playtest-vod/quarantine/ and tag facilitator with OBS checklist link.
Step 3 — Replay Buffer output matrix (Advanced Output)
Settings → Output → Recording (or Replay-specific section depending on OBS version):
- Encoder container: MKV or MP4—both OK if audio tracks enabled.
- Audio tracks: Enable Track 1 (and Track 2 if Discord/mic on separate track).
- Replay Buffer must use the same track assignment as your test recording.
If you use Simple Output, ensure Audio is not disabled and Desktop Audio source exists in the active scene.
Step 4 — ffmpeg extract smoke (mono 16 kHz)
ffmpeg -y -i "playtest-vod/inbox/smoke_replay.mkv" -vn -ac 1 -ar 16000 `
"playtest-vod/work/smoke_replay.wav"
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 `
"playtest-vod/work/smoke_replay.wav"
Pass: Printed duration > 1.0 seconds.
Then run Whisper on the WAV only (not the MKV) per local Whisper pipeline—confirms ASR path, not just OBS.
Step 5 — Receipt field audio_stream_ok
Extend batch receipt (per-clip or batch-level):
{
"schema": "playtest_vod_triage_receipt_v1",
"batch_date": "2026-05-24",
"gates": {
"T1_ingest": true,
"T2_audio": true,
"T3_transcript": true
},
"clips": [
{
"file": "2026-05-24_build-playtest-03_surface-playtest_replay.mkv",
"build_id": "2026-05-24-playtest-03",
"surface": "playtest",
"audio_stream_ok": true,
"audio_duration_sec": 118.4
}
]
}
Fail closed: If audio_stream_ok is false, do not set T3_transcript true—prevents empty ghost issues on the triage board.
Working dev path — CI gate snippet
Add pre-batch script scripts/playtest_vod_audio_gate.py (concept):
import json, subprocess, sys
from pathlib import Path
def probe(path: Path) -> dict:
cmd = ["ffprobe", "-v", "error", "-show_entries", "stream=codec_type,duration",
"-of", "json", str(path)]
return json.loads(subprocess.check_output(cmd))
def audio_ok(meta: dict) -> tuple[bool, float]:
best = 0.0
for s in meta.get("streams", []):
if s.get("codec_type") != "audio":
continue
d = s.get("duration")
if d and float(d) > best:
best = float(d)
return best >= 1.0, best
inbox = Path("playtest-vod/inbox")
failed = []
for mkv in inbox.glob("*.mkv"):
ok, dur = audio_ok(probe(mkv))
if not ok:
failed.append({"file": mkv.name, "audio_duration_sec": dur})
if failed:
print(json.dumps({"audio_stream_ok": False, "failed": failed}, indent=2))
sys.exit(1)
print("OK")
| Check | Artifact | Pass |
|---|---|---|
| ffprobe JSON | playtest-vod/logs/probe.json |
audio stream present |
| WAV extract | work/*.wav |
duration > 1 s |
| Whisper smoke | transcripts/smoke.txt |
non-empty text |
| Receipt | playtest_vod_triage_receipt_v1.json |
audio_stream_ok: true |
| Facilitator doc | playtest-vod/README.md |
OBS profile name + track matrix |
Verification checklist
- [ ]
ffprobelists audio stream with duration ≥ 1 s on production Replay clip - [ ] Extracted 16 kHz mono WAV duration matches expectation
- [ ] Whisper returns non-empty text on smoke WAV
- [ ] OBS Replay Buffer test uses same profile as playtest nights
- [ ]
playtest_vod_triage_receipt_v1.jsonhasaudio_stream_ok: trueandT2_audio: true - [ ] Quarantined bad MKVs not merged into fest_public fix lists
- [ ]
build_id+surfaceon filename per playtest isolation
Prevention
- Ship
playtest-vod/README.mdwith OBS profile name, track diagram, and ffprobe one-liner. - Facilitator first-night smoke: 10 s Replay + ffprobe before real session.
- Add
T2_audiogate to nightly batch—see 15 Free Local Whisper tools. - Do not route playtest clips through “stream” profiles that disable desktop audio for copyright.
- Pair with community playtest ops resource consent + capture section.
Troubleshooting
| Symptom | Fix |
|---|---|
| Meters move, file silent | Wrong profile / Advanced track matrix—Step 3 |
| Audio stream, duration 0 | Corrupt save—re-export Replay; try MKV → re-mux with ffmpeg copy |
| Discord audible, game silent | Add game capture + desktop audio source to scene |
| Whisper works on WAV, fails on MKV | Always extract -vn first; do not feed MKV direct if extract fails |
| All clips fail after OBS update | Reset audio devices in Settings → Audio; re-select Desktop Audio device |
| CUDA batch slow but not empty | CUDA fallback help—different issue |
FAQ
Is empty Whisper always OBS fault?
No—prove T2_audio with ffprobe first. Missing audio = capture/config; present audio + empty text = model path, language, or VAD stripping everything.
Should we use MP4 instead of MKV for Replay?
Either works if audio tracks are muxed. MKV is fine; the gate is stream presence, not container.
Can we cloud-upload these MKVs when local Whisper fails?
Only if playtest README allows cloud. Fix audio locally first—413 chunking help does not add audio that was never recorded.
Does ShareX replace OBS Replay?
ShareX can capture region + audio on Windows—still run the same ffprobe gate on inbox files regardless of tool.
Related links
- Local Whisper Playtest VOD Triage Pipeline (2026)
- Local Whisper CUDA Silent CPU Fallback (Windows 11)
- OpenAI Whisper API 413 Payload Too Large
- 15 Free Local Whisper and ffmpeg Playtest VOD Tools
- 15 Free OpenAI Whisper API Chunking Tools
- 18 Free Community Playtest Recruitment and Feedback Ops
- 2026 H2 Steam Playtest Invite Isolation Playbook
- Official: OBS Replay Buffer, ffmpeg ffprobe
Run ffprobe before Whisper—empty transcripts from video-only Replay clips are a capture problem, not an ASR regression.