ATH-MaaS/Pixelle-Video · error · RuntimeError

Failed to create video from image: {error_msg}

Error message

Failed to create video from image: {error_msg}

What it means

create_video_from_image builds a video track from a still image (looped for the audio's duration) via ffmpeg. An ffmpeg.Error is re-raised as this RuntimeError with decoded stderr. Failures usually stem from a bad image, bad audio, or encoder unavailability.

Source

Thrown at pixelle_video/services/video.py:675

                    t=audio_duration,  # Force video duration to match audio exactly
                    vcodec='libx264',
                    acodec='aac',
                    pix_fmt='yuv420p',
                    audio_bitrate='192k',
                    preset='medium',
                    crf=23,
                    **{'b:v': '2M'}  # Video bitrate
                )
                .overwrite_output()
                .run(capture_stdout=True, capture_stderr=True)
            )
            
            logger.success(f"Video created from image: {output} (duration: {audio_duration:.3f}s)")
            return output
        except ffmpeg.Error as e:
            error_msg = e.stderr.decode() if e.stderr else str(e)
            logger.error(f"FFmpeg error creating video from image: {error_msg}")
            raise RuntimeError(f"Failed to create video from image: {error_msg}")
    
    def add_bgm(
        self,
        video: str,
        bgm: str,
        output: str,
        bgm_volume: float = 0.3,
        loop: bool = True,
        fade_in: float = 0.0,
        fade_out: float = 0.0,
    ) -> str:
        """
        Add background music to video
        
        Args:
            video: Video file path
            bgm: Background music file path
            output: Output video file path

View on GitHub (pinned to 848b054e4f)

Solutions

  1. Read the FFmpeg stderr in the message for the exact encoder/input error.
  2. Verify the image exists and convert it to a standard RGB PNG/JPG.
  3. Verify the audio file is valid (ffprobe shows an audio stream and finite duration).
  4. Install an ffmpeg build with libx264 (`ffmpeg -encoders | grep 264`) and re-run.

Example fix

// before
service.create_video_from_image('slide.webp', 'voice.mp3', 'out.mp4')  # decode/encoder error
// after
convert_image('slide.webp', 'slide.png')  # standard RGB PNG
assert get_audio_duration('voice.mp3') > 0
service.create_video_from_image('slide.png', 'voice.mp3', 'out.mp4')
Defensive patterns

Strategy: validation

Validate before calling

import ffmpeg
assert os.path.isfile(image) and os.path.getsize(image) > 0
assert has_audio_stream(audio)
assert '264' in subprocess.run(['ffmpeg','-encoders'],capture_output=True,text=True).stdout or True  # warn if libx264 missing

Type guard

def is_valid_audio(path: str) -> bool:
    try:
        probe = ffmpeg.probe(path)
        dur = float(probe['format'].get('duration', 0))
        return any(s.get('codec_type') == 'audio' for s in probe['streams']) and dur > 0
    except Exception:
        return False

Try / catch

try:
    service.create_video_from_image(image, audio, out)
except RuntimeError as e:
    if 'Failed to create video from image' in str(e):
        logger.error(f'image-to-video encode failed: {e}')
        # convert image to RGB PNG, verify audio, retry
    else:
        raise

Prevention

When it happens

Trigger: Image file missing or in an unsupported format; audio duration probe failing so the loop/duration flags get bad values; libx264 not present in the ffmpeg build; invalid fps/size parameters; output container rejecting the chosen encoder.

Common situations: 16-bit or CMYK PNGs the encoder rejects; WebP inputs unsupported by older ffmpeg builds; minimal ffmpeg installs (no libx264) in containers; zero-length audio making duration computation fail.

Related errors


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