{"record":{"id":"cd20a60d52c4aba1","repo":"harry0703/MoneyPrinterTurbo","slug":"sonilo-video-proxy-is-empty-or-exceeds-the-300-mb","errorCode":null,"errorMessage":"Sonilo video proxy is empty or exceeds the 300 MB limit","messagePattern":"Sonilo video proxy is empty or exceeds the 300 MB limit","errorType":"exception","errorClass":"SoniloError","httpStatus":null,"severity":"error","filePath":"app/services/sonilo.py","lineNumber":196,"sourceCode":"            capture_output=True,\n            text=True,\n            timeout=600,\n            check=False,\n        )\n    except subprocess.TimeoutExpired as exc:\n        _remove_file(proxy_path)\n        raise SoniloError(\"Sonilo video proxy generation timed out\") from exc\n    except OSError as exc:\n        _remove_file(proxy_path)\n        raise SoniloError(\"failed to run FFmpeg for Sonilo video proxy\") from exc\n    if result.returncode != 0:\n        _remove_file(proxy_path)\n        detail = (result.stderr or \"\").strip().replace(\"\\n\", \" \")[-500:]\n        raise SoniloError(f\"failed to generate Sonilo video proxy: {detail}\")\n    proxy_size = os.path.getsize(proxy_path) if os.path.isfile(proxy_path) else 0\n    if proxy_size <= 0 or proxy_size > MAX_PROXY_BYTES:\n        _remove_file(proxy_path)\n        raise SoniloError(\"Sonilo video proxy is empty or exceeds the 300 MB limit\")\n    logger.info(\n        f\"Sonilo video proxy prepared: source={video_path}, size={proxy_size} bytes\"\n    )\n    return proxy_path\n\n\ndef _parse_event(raw_line: bytes) -> dict[str, Any]:\n    \"\"\"严格解析单条 NDJSON，禁止静默忽略截断或非对象响应。\"\"\"\n    try:\n        event = json.loads(raw_line.decode(\"utf-8\"))\n    except (UnicodeDecodeError, json.JSONDecodeError) as exc:\n        raise SoniloError(\"Sonilo returned malformed streaming data\") from exc\n    if not isinstance(event, dict) or not isinstance(event.get(\"type\"), str):\n        raise SoniloError(\"Sonilo returned an invalid streaming event\")\n    return event\n\n\ndef _stream_audio(response: requests.Response, temp_audio_path: str) -> tuple[int, str]:","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/harry0703/MoneyPrinterTurbo/blob/1f9f19c2021a68d04df228f33e9099a0c947f6f8/app/services/sonilo.py#L178-L214","documentation":"Raised after a successful FFmpeg run when the produced proxy file is 0 bytes or larger than MAX_PROXY_BYTES (300 MB). FFmpeg exiting 0 with an empty output usually means the command produced no frames (bad filter graph), and the size cap prevents uploading absurdly large intermediates to Sonilo. The proxy is deleted before raising.","triggerScenarios":"A filter or graph configuration that writes no frames (for example zero-duration output after trimming a source whose duration was misdetected); a proxy encode of a near-360-second high-bitrate clip with quality settings high enough to exceed 300 MB; a full disk where FFmpeg silently truncates but still exits 0.","commonSituations":"Tweaked proxy arguments (CRF, preset, bitrate) that balloon output size; a source video whose header lies about duration causing FFmpeg to emit an empty file; disk-full conditions producing a truncated file.","solutions":["If size was exceeded: increase compression in the proxy command (lower CRF or cap bitrate) so the worst-case 360-second output stays under 300 MB, or raise MAX_PROXY_BYTES if Sonilo accepts larger uploads.","If the file was empty: reproduce the exact ffmpeg command manually and inspect warnings; typically the result of a bad filter or a zero-duration stream.","Check free space on the task temp volume.","Validate the source video with ffprobe (duration, streams) before proxy generation."],"exampleFix":"# before (proxy can exceed 300 MB for long clips)\n\"-c:v\", \"libx264\", \"-crf\", \"18\"\n# after (bounded bitrate keeps worst case under cap)\n\"-c:v\", \"libx264\", \"-crf\", \"23\", \"-maxrate\", \"6M\", \"-bufsize\", \"12M\"","handlingStrategy":"validation","validationCode":"proxy_size = os.path.getsize(proxy_path) if os.path.isfile(proxy_path) else 0\nif not (0 < proxy_size <= sonilo.MAX_PROXY_BYTES):\n    raise ValueError(\n        f\"proxy {proxy_size} bytes outside (0, {sonilo.MAX_PROXY_BYTES}]\"\n    )","typeGuard":null,"tryCatchPattern":"try:\n    proxy = generate_video_proxy(video)\nexcept SoniloError as exc:\n    if \"empty or exceeds\" in str(exc):\n        re_encode_with_stricter_settings(video)  # bounded bitrate, see exampleFix\n    raise","preventionTips":["Encode proxies with maxrate and bufsize caps so the 360-second worst case mathematically stays under 300 MB.","For empty outputs, always reproduce the exact ffmpeg command manually before changing code."],"tags":["ffmpeg","size-limit","validation","video"],"backgroundTag":null,"analyzedSha":"1f9f19c2021a68d04df228f33e9099a0c947f6f8","analyzedAt":"2026-08-14T19:41:05.568Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}