{"record":{"id":"f5687d5f5e79ffbb","repo":"affaan-m/ECC","slug":"ffmpeg-encode-failed-err","errorCode":null,"errorMessage":"ffmpeg encode failed: {err}","messagePattern":"ffmpeg encode failed: (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/taste/grade.py","lineNumber":817,"sourceCode":"                       tone_mode=tone_mode)\n        proc.stdin.write((np.clip(out, 0, 1) * 255).astype(np.uint8).tobytes())\n        buf.clear()\n\n    try:\n        while True:\n            ok, bgr = cap.read()\n            if not ok:\n                break\n            buf.append(_cv2.cvtColor(bgr, _cv2.COLOR_BGR2RGB).astype(np.float32) / 255.0)\n            if len(buf) >= batch:\n                flush()\n        flush()\n    finally:\n        cap.release()\n        proc.stdin.close()\n        err = proc.stderr.read().decode()[-400:]\n        if proc.wait() != 0:\n            raise RuntimeError(f\"ffmpeg encode failed: {err}\")\n    return dst\n","sourceCodeStart":799,"sourceCodeEnd":819,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/taste/grade.py#L799-L819","documentation":"`grade_clip_direct()` pipes raw frames into an FFmpeg subprocess and after the stream ends reads FFmpeg's stderr; if the encoder exits non-zero it raises a RuntimeError with the last 400 bytes of stderr. This detects encode-side failures that only appear at flush/termination — invalid encoder options, corrupted output target, disk full, or an FFmpeg that died mid-stream.","triggerScenarios":"Calling `grade_clip_direct()` where the piped ffmpeg process returns non-zero at wait() — bad `-crf`/encoder args, destination path unwritable, ffmpeg killed or OOM, unsupported output pixel format.","commonSituations":"Very old or unusual FFmpeg builds missing libx264; output volume filling mid-encode; destination file locked by another process; stderr revealing 'Conversion failed' after a frame-size mismatch between declared `-s` and actual frames.","solutions":["Read the stderr captured in the exception (last 400 chars) for the concrete FFmpeg message.","Verify FFmpeg supports libx264: `ffmpeg -encoders | grep libx264`; install a full build if absent.","Check destination disk space and write permissions before encoding.","Ensure probe-derived width/height/fps actually match the source frames so the rawvideo header is correct."],"exampleFix":"// before\ncmd = [..., '-c:v', 'libx264', '-crf', str(crf), ...]   # libx264 absent -> encode failed\n// after\nif b'libx264' not in subprocess.run(['ffmpeg','-encoders'], capture_output=True).stdout:\n    cmd = [c if c != 'libx264' else 'mpeg4' for c in cmd]\nsubprocess.Popen(cmd, stdin=subprocess.PIPE, stderr=subprocess.PIPE, ...)","handlingStrategy":"try-catch","validationCode":"import shutil, subprocess\nassert shutil.which('ffmpeg')\nenc = subprocess.run(['ffmpeg', '-hide_banner', '-encoders'], capture_output=True)\nassert b'libx264' in enc.stdout, 'libx264 encoder unavailable'","typeGuard":null,"tryCatchPattern":"try:\n    grade_clip_direct(src, dst, lut)\nexcept RuntimeError as e:\n    if str(e).startswith('ffmpeg encode failed'):\n        err = str(e).split(':', 1)[-1]\n        logger.error('encoder stderr: %s', err)\n        cleanup_partial(dst)\n        raise EncodeError(dst, err) from e\n    raise","preventionTips":["Check disk space before long encodes","Verify libx264 availability or fall back to another encoder","Confirm probe width/height/fps match actual frames so the rawvideo header is correct","Always read/close the stderr pipe and wait() on the process to surface real exit codes"],"tags":["ffmpeg","subprocess","video-encoding","pipe"],"backgroundTag":"http-error-response","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}