{"record":{"id":"c25a89cc0113c163","repo":"harry0703/MoneyPrinterTurbo","slug":"sonilo-audio-exceeds-the-30-mb-limit","errorCode":null,"errorMessage":"Sonilo audio exceeds the 30 MB limit","messagePattern":"Sonilo audio exceeds the 30 MB limit","errorType":"exception","errorClass":"SoniloError","httpStatus":null,"severity":"error","filePath":"app/services/sonilo.py","lineNumber":259,"sourceCode":"            if event_type != \"audio_chunk\":\n                logger.debug(f\"ignoring unsupported Sonilo event: type={event_type}\")\n                continue\n\n            stream_index = event.get(\"stream_index\", 0)\n            if stream_index != 0:\n                continue\n            encoded_chunk = event.get(\"data\") or event.get(\"audio\")\n            if not isinstance(encoded_chunk, str) or not encoded_chunk:\n                raise SoniloError(\"Sonilo returned an empty audio chunk\")\n            try:\n                chunk = base64.b64decode(encoded_chunk, validate=True)\n            except (binascii.Error, ValueError) as exc:\n                raise SoniloError(\"Sonilo returned an invalid audio chunk\") from exc\n            if not chunk:\n                raise SoniloError(\"Sonilo returned an empty audio chunk\")\n            total_bytes += len(chunk)\n            if total_bytes > MAX_GENERATED_AUDIO_BYTES:\n                raise SoniloError(\"Sonilo audio exceeds the 30 MB limit\")\n            output.write(chunk)\n        output.flush()\n        os.fsync(output.fileno())\n\n    if not completed:\n        raise SoniloError(\"Sonilo stream ended before completion\")\n    if total_bytes <= 0:\n        raise SoniloError(\"Sonilo returned no audio data\")\n    return total_bytes, title\n\n\ndef _request_bgm(video_path: str, output_path: str, prompt: str) -> str:\n    \"\"\"请求配乐并在完整协议及音频校验通过后原子保存。\"\"\"\n    output_dir = os.path.dirname(os.path.abspath(output_path))\n    os.makedirs(output_dir, exist_ok=True)\n    descriptor, temp_audio_path = tempfile.mkstemp(\n        prefix=\".sonilo-audio-\",\n        suffix=Path(output_path).suffix or \".m4a\",","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/harry0703/MoneyPrinterTurbo/blob/1f9f19c2021a68d04df228f33e9099a0c947f6f8/app/services/sonilo.py#L241-L277","documentation":"Raised when cumulative decoded audio bytes exceed MAX_GENERATED_AUDIO_BYTES (30 MB). This client-side safety cap enforces that a single video-to-music result stays consistent with the documented maximum input duration (videos are capped at 360 seconds), so an over-30MB stream means either a runaway generation or a protocol anomaly.","triggerScenarios":"Generation runs far longer than the source video (server ignores duration limits); repeated chunks for stream_index 0 due to a server retry loop; a client-side loop bug accumulating a chunk twice; provider changing chunk semantics so the same audio is resent.","commonSituations":"Long (near six-minute) sources with high-bitrate output; a provider incident causing infinite chunk repeats; mismatch between the 360-second input cap and server-side render length.","solutions":["Confirm the source video duration is within MAX_VIDEO_DURATION_SECONDS (360); a misreported container duration can make the server render extra audio.","Check logs for whether byte totals grow steadily or spike; repeated or duplicate chunks indicate a provider bug worth reporting.","If legitimate outputs genuinely exceed 30 MB, raise MAX_GENERATED_AUDIO_BYTES after verifying downstream consumers accept the size.","Retry the task; a one-off runaway stream is transient."],"exampleFix":"# before\nMAX_GENERATED_AUDIO_BYTES = 30 * 1024 * 1024\n# after (only if longer outputs are legitimate)\nMAX_GENERATED_AUDIO_BYTES = 50 * 1024 * 1024","handlingStrategy":"validation","validationCode":"import sonilo\n\n# expected_worst_case: duration_s * provider_max_bitrate_bps / 8\nif expected_worst_case_bytes(source_duration) > sonilo.MAX_GENERATED_AUDIO_BYTES:\n    raise ValueError(\"expected audio exceeds the client 30 MB cap\")","typeGuard":null,"tryCatchPattern":"try:\n    audio = request_bgm(video, out, prompt)\nexcept SoniloError as exc:\n    if \"exceeds the 30 MB limit\" in str(exc):\n        # guard against runaway streams; never resume partial files\n        cleanup_temp_and_retry_once()\n    raise","preventionTips":["Enforce the 360-second source-duration cap at upload so server render length stays bounded.","Never raise the cap blindly; re-check downstream playback and memory limits first."],"tags":["sonilo","size-limit","audio","streaming"],"backgroundTag":null,"analyzedSha":"1f9f19c2021a68d04df228f33e9099a0c947f6f8","analyzedAt":"2026-08-14T19:41:05.568Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}