ATH-MaaS/Pixelle-Video · error · RuntimeError

Failed to merge audio and video: {error_msg}

Error message

Failed to merge audio and video: {error_msg}

What it means

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.

Source

Thrown at pixelle_video/services/video.py:512

                    ffmpeg
                    .output(
                        video_stream,
                        mixed_audio,
                        output,
                        vcodec='libx264',  # Re-encode video if padded
                        acodec='aac',
                        audio_bitrate='192k'
                    )
                    .overwrite_output()
                    .run(capture_stdout=True, capture_stderr=True)
                )
            
            logger.success(f"Audio merged successfully: {output}")
            return output
        except ffmpeg.Error as e:
            error_msg = e.stderr.decode() if e.stderr else str(e)
            logger.error(f"FFmpeg merge error: {error_msg}")
            raise RuntimeError(f"Failed to merge audio and video: {error_msg}")
    
    def overlay_image_on_video(
        self,
        video: str,
        overlay_image: str,
        output: str,
        scale_mode: str = "contain"
    ) -> str:
        """
        Overlay a transparent image on top of video
        
        Args:
            video: Base video file path
            overlay_image: Transparent overlay image path (e.g., rendered HTML with transparent background)
            output: Output video file path
            scale_mode: How to scale the base video to fit the overlay size
                - "contain": Scale video to fit within overlay dimensions (letterbox/pillarbox)
                - "cover": Scale video to cover overlay dimensions (may crop)

View on GitHub (pinned to 848b054e4f)

Solutions

  1. Read the FFmpeg stderr in the exception message for the exact stream/codec error.
  2. Re-encode the replacement audio to aac m4a before merging.
  3. Verify both input files are valid with ffprobe (video stream + audio stream present).
  4. Match sample rates/channels between existing and new audio, or rely on replace_audio with explicit -ar/-ac if the API exposes it.

Example fix

// before
service.merge_audio_video(video.mp4, 'music.mp3', 'out.mp4', replace_audio=True)  # codec error
// after
transcode('music.mp3', 'music.m4a', codec='aac', ar=44100)
service.merge_audio_video(video.mp4, 'music.m4a', 'out.mp4', replace_audio=True)
Defensive patterns

Strategy: validation

Validate before calling

import ffmpeg
assert has_audio_stream(video) and has_audio_stream(audio)
audio_probe = ffmpeg.probe(audio)
ar = audio_probe['streams'][0].get('sample_rate')
print('replacement audio sample_rate:', ar)

Type guard

def has_audio_stream(path: str) -> bool:
    try:
        return any(s.get('codec_type') == 'audio' for s in ffmpeg.probe(path)['streams'])
    except Exception:
        return False

Try / catch

try:
    service.merge_audio_video(video, audio, out, replace_audio=True)
except RuntimeError as e:
    if 'Failed to merge audio and video' in str(e):
        logger.error(f'audio merge failed: {e}')
        # transcode replacement audio to aac and retry
    else:
        raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of ATH-MaaS/Pixelle-Video@848b054e4f (2026-08-30). Data as JSON: /api/errors/14ecd22877749e24. Report an issue: GitHub.