{"record":{"id":"e2c96f594687bd3c","repo":"ATH-MaaS/Pixelle-Video","slug":"failed-to-concatenate-videos-error-msg","errorCode":null,"errorMessage":"Failed to concatenate videos: {error_msg}","messagePattern":"Failed to concatenate videos: (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"pixelle_video/services/video.py","lineNumber":203,"sourceCode":"                escaped_path = str(abs_path).replace(\"'\", \"'\\\\''\")\n                f.write(f\"file '{escaped_path}'\\n\")\n            filelist = f.name\n        \n        try:\n            logger.debug(f\"Created filelist: {filelist}\")\n            (\n                ffmpeg\n                .input(filelist, format='concat', safe=0)\n                .output(output, c='copy')\n                .overwrite_output()\n                .run(capture_stdout=True, capture_stderr=True)\n            )\n            logger.success(f\"Videos concatenated 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 concat error: {error_msg}\")\n            raise RuntimeError(f\"Failed to concatenate videos: {error_msg}\")\n        finally:\n            if os.path.exists(filelist):\n                os.unlink(filelist)\n    \n    def _concat_filter(self, videos: List[str], output: str) -> str:\n        \"\"\"\n        Concatenate using concat filter (slower but handles different formats)\n        \n        FFmpeg equivalent:\n            ffmpeg -i v1.mp4 -i v2.mp4 -filter_complex \"[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1[v][a]\"\n                   -map \"[v]\" -map \"[a]\" output.mp4\n        \"\"\"\n        try:\n            # Build filter_complex string manually\n            n = len(videos)\n            \n            # Build input stream labels: [0:v][0:a][1:v][1:a]...\n            stream_spec = \"\".join([f\"[{i}:v][{i}:a]\" for i in range(n)])","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/ATH-MaaS/Pixelle-Video/blob/848b054e4fae40dabc62ec58e960b573e83793ac/pixelle_video/services/video.py#L185-L221","documentation":"_concat_demuxer runs ffmpeg with the concat demuxer (-f concat -safe 0 -i filelist). If the ffmpeg subprocess fails, ffmpeg-python raises ffmpeg.Error, and this handler wraps its stderr into a RuntimeError with the 'Failed to concatenate videos' prefix. The actual cause is in the captured FFmpeg stderr text.","triggerScenarios":"Files listed in the filelist do not exist or are unreadable; inputs have mismatched codecs/resolutions/timebases that the demuxer cannot concat; `-safe 0` omitted for absolute paths (not in this implementation, but path quoting issues); corrupted or non-media files passed as inputs.","commonSituations":"Concatenating clips from different sources/encoders; a temp segment was deleted before concatenation; files with non-ASCII paths mishandled; codec mismatch (h264 vs vp9) requiring re-encode via the filter method instead.","solutions":["Read the FFmpeg stderr in the exception message — it names the failing input or codec issue.","Verify every path in `videos` exists and is a valid, readable media file (`ffprobe` each one).","Ensure all inputs share codec, resolution, and timebase, or force re-encoding (the concat filter path) instead of the stream-copy demuxer.","Re-encode/re-export problem inputs to a uniform format (e.g. h264/aac mp4) before concatenating."],"exampleFix":"// before\nservice.concat_videos(['a.mp4', 'b.webm'], 'out.mp4')  # demuxer fails: codec mismatch\n// after\n# normalize inputs first, then concat\nfor f in ['a.mp4', 'b.webm']:\n    normalize_to_h264_mp4(f)\nservice.concat_videos(['a.mp4', 'b.mp4'], 'out.mp4')","handlingStrategy":"try-catch","validationCode":"for v in videos:\n    assert os.path.isfile(v), f'missing input: {v}'\n    import ffmpeg as ff\n    info = ff.probe(v)\n    assert info['streams'], f'no streams in {v}'","typeGuard":"def is_valid_media(path: str) -> bool:\n    try:\n        return bool(ffmpeg.probe(path).get('streams'))\n    except Exception:\n        return False","tryCatchPattern":"try:\n    service.concat_videos(videos, out)\nexcept RuntimeError as e:\n    if 'Failed to concatenate videos' in str(e):\n        logger.error(f'ffmpeg concat demuxer failed: {e}')\n        # inspect stderr in message; re-encode inputs or fall back to filter concat\n    else:\n        raise","preventionTips":["Normalize all inputs to the same codec/resolution/timebase (h264+aac mp4) before concat.","ffprobe every input in CI before running long concat jobs.","Keep intermediate segment files alive until concat completes (no premature temp cleanup).","Avoid exotic codecs/containers for intermediates."],"tags":["ffmpeg","concat","subprocess"],"backgroundTag":"ffmpeg-concat-failed","analyzedSha":"848b054e4fae40dabc62ec58e960b573e83793ac","analyzedAt":"2026-08-30T03:24:41.468Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}