ATH-MaaS/Pixelle-Video · error · RuntimeError

Failed to trim video: {error_msg}

Error message

Failed to trim video: {error_msg}

What it means

_trim_video_to_duration wraps any ffmpeg-python error raised while trimming the input video to the target duration and re-raises it as RuntimeError with ffmpeg's stderr appended. This means the ffmpeg trim command failed (bad input, unsupported codec, invalid seek times), not a Python logic error.

Source

Thrown at pixelle_video/services/video.py:918

        output = self._get_unique_temp_path("trimmed", os.path.basename(video))
        
        try:
            # Use stream copy when possible for fast trimming
            input_stream = ffmpeg.input(video, t=target_duration)
            output_kwargs = {"vcodec": "copy"}
            if self.has_audio_stream(video):
                output_kwargs["acodec"] = "copy"
            (
                input_stream
                .output(output, **output_kwargs)
                .overwrite_output()
                .run(capture_stdout=True, capture_stderr=True, quiet=True)
            )
            return output
        except ffmpeg.Error as e:
            error_msg = e.stderr.decode() if e.stderr else str(e)
            logger.error(f"FFmpeg error trimming video: {error_msg}")
            raise RuntimeError(f"Failed to trim video: {error_msg}")
    
    def _pad_video_to_duration(self, video: str, target_duration: float, pad_strategy: str = "freeze") -> str:
        """
        Pad video to specified duration by extending the last frame or adding black frames
        
        Args:
            video: Input video file path
            target_duration: Target duration in seconds
            pad_strategy: Padding strategy - "freeze" (freeze last frame) or "black" (black screen)
        
        Returns:
            Path to padded video (temp file)
        
        Raises:
            RuntimeError: If FFmpeg execution fails
        """
        output = self._get_unique_temp_path("padded", os.path.basename(video))
        

View on GitHub (pinned to 848b054e4f)

Solutions

  1. Read the stderr text embedded in the RuntimeError message — it names the exact ffmpeg failure
  2. Confirm ffmpeg is installed and on PATH (`ffmpeg -version`)
  3. Verify the input video plays and the trim start/duration values are positive and within the video length
  4. Check output directory permissions and free disk space

Example fix

// before
output = service._trim_video_to_duration('clip.mp4', 0)
// after
duration = max(0.1, min(requested, probe_duration('clip.mp4')))
output = service._trim_video_to_duration('clip.mp4', duration)
Defensive patterns

Strategy: try-catch

Validate before calling

import shutil
from pathlib import Path

def validate_trim_inputs(video: str, duration: float) -> None:
    if not Path(video).exists():
        raise FileNotFoundError(video)
    if duration <= 0:
        raise ValueError(f'duration must be > 0, got {duration}')
    if shutil.which('ffmpeg') is None:
        raise RuntimeError('ffmpeg not on PATH')

Try / catch

try:
    trimmed = service._trim_video_to_duration(video, target)
except RuntimeError as e:
    logger.error(f'trim ffmpeg stderr: {e}')
    raise VideoProcessingError(video, target) from e

Prevention

When it happens

Trigger: merge_audio_video calls _trim_video_to_duration and ffmpeg exits non-zero: corrupt/unreadable input video, an output path that is not writable, '-ss'/'-t' values that are invalid (negative, or beyond stream bounds in some formats), or a missing system ffmpeg binary.

Common situations: ffmpeg not installed or not on PATH; input file truncated or in a container ffmpeg cannot demux; disk full so the output can't be written; passing a duration of 0 or negative.

Related errors


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