{"record":{"id":"14ecd22877749e24","repo":"ATH-MaaS/Pixelle-Video","slug":"failed-to-merge-audio-and-video-error-msg","errorCode":null,"errorMessage":"Failed to merge audio and video: {error_msg}","messagePattern":"Failed to merge audio and video: (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"pixelle_video/services/video.py","lineNumber":512,"sourceCode":"                    ffmpeg\n                    .output(\n                        video_stream,\n                        mixed_audio,\n                        output,\n                        vcodec='libx264',  # Re-encode video if padded\n                        acodec='aac',\n                        audio_bitrate='192k'\n                    )\n                    .overwrite_output()\n                    .run(capture_stdout=True, capture_stderr=True)\n                )\n            \n            logger.success(f\"Audio merged successfully: {output}\")\n            return output\n        except ffmpeg.Error as e:\n            error_msg = e.stderr.decode() if e.stderr else str(e)\n            logger.error(f\"FFmpeg merge error: {error_msg}\")\n            raise RuntimeError(f\"Failed to merge audio and video: {error_msg}\")\n    \n    def overlay_image_on_video(\n        self,\n        video: str,\n        overlay_image: str,\n        output: str,\n        scale_mode: str = \"contain\"\n    ) -> str:\n        \"\"\"\n        Overlay a transparent image on top of video\n        \n        Args:\n            video: Base video file path\n            overlay_image: Transparent overlay image path (e.g., rendered HTML with transparent background)\n            output: Output video file path\n            scale_mode: How to scale the base video to fit the overlay size\n                - \"contain\": Scale video to fit within overlay dimensions (letterbox/pillarbox)\n                - \"cover\": Scale video to cover overlay dimensions (may crop)","sourceCodeStart":494,"sourceCodeEnd":530,"githubUrl":"https://github.com/ATH-MaaS/Pixelle-Video/blob/848b054e4fae40dabc62ec58e960b573e83793ac/pixelle_video/services/video.py#L494-L530","documentation":"When the video already has an audio stream, merge_audio_video merges (or replaces) it with the provided audio via ffmpeg. An ffmpeg.Error there is re-raised as this RuntimeError with decoded stderr. This is the merge/replace branch counterpart of error 125.","triggerScenarios":"replace_audio=True with an incompatible audio file; missing -shortest handling causing stream length issues; audio codec not supported by the output container; audio file path invalid while the video path is fine.","commonSituations":"Replacing stereo music with mono voice tracks in a container that rejects the codec; durations wildly mismatched causing sync/encoding issues; ffmpeg builds without libmp3lame when mp3 input is used.","solutions":["Read the FFmpeg stderr in the exception message for the exact stream/codec error.","Re-encode the replacement audio to aac m4a before merging.","Verify both input files are valid with ffprobe (video stream + audio stream present).","Match sample rates/channels between existing and new audio, or rely on replace_audio with explicit -ar/-ac if the API exposes it."],"exampleFix":"// before\nservice.merge_audio_video(video.mp4, 'music.mp3', 'out.mp4', replace_audio=True)  # codec error\n// after\ntranscode('music.mp3', 'music.m4a', codec='aac', ar=44100)\nservice.merge_audio_video(video.mp4, 'music.m4a', 'out.mp4', replace_audio=True)","handlingStrategy":"validation","validationCode":"import ffmpeg\nassert has_audio_stream(video) and has_audio_stream(audio)\naudio_probe = ffmpeg.probe(audio)\nar = audio_probe['streams'][0].get('sample_rate')\nprint('replacement audio sample_rate:', ar)","typeGuard":"def has_audio_stream(path: str) -> bool:\n    try:\n        return any(s.get('codec_type') == 'audio' for s in ffmpeg.probe(path)['streams'])\n    except Exception:\n        return False","tryCatchPattern":"try:\n    service.merge_audio_video(video, audio, out, replace_audio=True)\nexcept RuntimeError as e:\n    if 'Failed to merge audio and video' in str(e):\n        logger.error(f'audio merge failed: {e}')\n        # transcode replacement audio to aac and retry\n    else:\n        raise","preventionTips":["Confirm both inputs contain the expected streams before merge.","Normalize replacement audio to aac, 44.1/48kHz, and matching channel count.","Keep audio durations compatible (use replace_audio or trimming) to avoid sync issues.","Test the ffmpeg merge command for unusual containers before automating it."],"tags":["ffmpeg","audio","muxing"],"backgroundTag":"ffmpeg-audio-mux-failed","analyzedSha":"848b054e4fae40dabc62ec58e960b573e83793ac","analyzedAt":"2026-08-30T03:24:41.468Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}