{"record":{"id":"e3c34993f55a1451","repo":"microsoft/VibeVoice","slug":"ffmpeg-returned-empty-audio-data","errorCode":null,"errorMessage":"ffmpeg returned empty audio data","messagePattern":"ffmpeg returned empty audio data","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"vllm_plugin/scripts/gradio_asr_demo_api_video.py","lineNumber":219,"sourceCode":"        target_sr = target_sr or 16000\n        cmd = [\n            \"ffmpeg\", \"-i\", path,\n            \"-f\", \"f32le\", \"-acodec\", \"pcm_f32le\",\n            \"-ac\", \"1\", \"-ar\", str(target_sr),\n            \"-\"\n        ]\n        process = subprocess.Popen(\n            cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL\n        )\n        audio_bytes, _ = process.communicate()\n        audio_data = np.frombuffer(audio_bytes, dtype=np.float32)\n        \n        print(f\"[DEBUG] ffmpeg loaded: shape={audio_data.shape}, sr={target_sr}\")\n        print(f\"[DEBUG] audio range: min={audio_data.min():.6f}, max={audio_data.max():.6f}\")\n        \n        # Check for silent audio\n        if len(audio_data) == 0:\n            raise RuntimeError(\"ffmpeg returned empty audio data\")\n        if audio_data.max() == 0 and audio_data.min() == 0:\n            print(f\"[WARNING] Audio appears to be completely silent!\")\n        \n        return audio_data, target_sr\n    except Exception as e:\n        raise RuntimeError(f\"Failed to load audio: {e}\")\n\n\ndef get_file_size_mb(file_path: str) -> float:\n    \"\"\"Get file size in MB.\"\"\"\n    try:\n        return os.path.getsize(file_path) / (1024 * 1024)\n    except Exception:\n        return 0.0\n\n\ndef is_video_file(file_path: str) -> bool:\n    \"\"\"Check if the file is a video file based on extension.\"\"\"","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/microsoft/VibeVoice/blob/94da20d98b2fa7688e9cbfaf7692ddb4954f7600/vllm_plugin/scripts/gradio_asr_demo_api_video.py#L201-L237","documentation":"In the Gradio ASR demo script, audio is decoded by shelling out to ffmpeg (subprocess.Popen with stdout=PIPE, stderr=DEVNULL) and reading float32 samples from stdout. If ffmpeg writes zero bytes, np.frombuffer yields an empty array and this RuntimeError fires. stderr is discarded, so ffmpeg's actual error message (bad file, no audio stream, unknown codec, missing ffmpeg) is invisible.","triggerScenarios":"Passing a file ffmpeg cannot decode (corrupt download, DRM-protected media, unsupported container); a video with no audio stream so the -map selects nothing; ffmpeg not installed/failing to exec (though that raises differently); wrong stream-selection flags in cmd causing empty output; zero-length input file.","commonSituations":"Users dragging arbitrary web-downloaded media into the demo; .mp4 recordings from screen capture with muted audio track; systems where a minimal ffmpeg build lacks the needed codec (e.g. no libopus).","solutions":["Verify the file plays locally and has an audio stream: ffprobe -v error -select_streams a -show_entries stream=codec_type <file>.","Pre-install/verify full ffmpeg builds (e.g. apt install ffmpeg or a static build with common codecs).","Patch the script to capture stderr (stderr=subprocess.PIPE) and include it in the error for diagnosis.","Pre-convert awkward sources to 24 kHz mono wav: ffmpeg -i in.mp4 -vn -ac 1 -ar 24000 out.wav, then feed out.wav."],"exampleFix":"# before\nprocess = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)\naudio_bytes, _ = process.communicate()\n\n# after\nprocess = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\naudio_bytes, err = process.communicate()\nif len(audio_bytes) == 0:\n    raise RuntimeError(f\"ffmpeg returned empty audio data: {err.decode(errors='replace')[-500:]}\")","handlingStrategy":"validation","validationCode":"import os, subprocess\n\ndef precheck_media(path: str) -> None:\n    assert os.path.getsize(path) > 0, \"file is empty\"\n    r = subprocess.run(\n        [\"ffprobe\", \"-v\", \"error\", \"-select_streams\", \"a\",\n         \"-show_entries\", \"stream=codec_type\", \"-of\", \"csv=p=0\", path],\n        capture_output=True, text=True)\n    if \"audio\" not in r.stdout:\n        raise ValueError(f\"{path} has no decodable audio stream: {r.stderr.strip()}\")","typeGuard":"def has_audio_stream(path: str) -> bool:\n    r = subprocess.run(\n        [\"ffprobe\", \"-v\", \"error\", \"-select_streams\", \"a\",\n         \"-show_entries\", \"stream=codec_type\", \"-of\", \"csv=p=0\", path],\n        capture_output=True, text=True)\n    return \"audio\" in r.stdout","tryCatchPattern":"try:\n    wave, sr = load_audio_ffmpeg(path)\nexcept RuntimeError as e:\n    if \"empty audio data\" in str(e):\n        raise ValueError(f\"{path} produced no audio; check file integrity and audio stream\")\n    raise","preventionTips":["Capture ffmpeg stderr in your own loaders — DEVNULL hides the root cause.","ffprobe every uploaded file for an audio stream before decode.","Keep a full-featured ffmpeg on PATH in deployment images."],"tags":["ffmpeg","subprocess","audio-decode","demo-script","media"],"backgroundTag":null,"analyzedSha":"94da20d98b2fa7688e9cbfaf7692ddb4954f7600","analyzedAt":"2026-08-15T04:12:07.418Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}