{"record":{"id":"132d340b8f7f2c5e","repo":"Comfy-Org/ComfyUI","slug":"video-resolution-changes-mid-stream-source-size","errorCode":null,"errorMessage":"Video resolution changes mid-stream ({source_size[0]}x{source_size[1]} -> {frame.width}x{frame.height}); cannot transcode","messagePattern":"Video resolution changes mid-stream \\((.+?)x(.+?) -> (.+?)x(.+?)\\); cannot transcode","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"comfy_api/latest/_input_impl/video_types.py","lineNumber":678,"sourceCode":"                            output = av.open(path, **open_kwargs)\n                            # Add metadata before writing any streams\n                            write_output_metadata(container, output, metadata)\n                            out_video = output.add_stream(\"h264\", rate=rate)\n                            # no B-frames: reordering makes mp4 sample durations follow decode order,\n                            # so irregular-VFR spans and trim windows land wrong\n                            out_video.codec_context.max_b_frames = 0\n                            out_video.width = out_width\n                            out_video.height = out_height\n                            out_video.pix_fmt = pix_fmt\n                            if crf is not None:\n                                out_video.options = {\"crf\": str(crf)}\n                            # source pts pass through (rebased to 0), so variable frame rate survives\n                            out_video.codec_context.time_base = video_stream.time_base\n                            if audio_stream is not None:\n                                out_audio = output.add_stream(\"aac\", rate=sample_rate, layout=layout)\n                        if (frame.width, frame.height) != source_size:\n                            # encoding would silently rescale the new geometry into the old one\n                            raise ValueError(\n                                f\"Video resolution changes mid-stream \"\n                                f\"({source_size[0]}x{source_size[1]} -> {frame.width}x{frame.height}); cannot transcode\"\n                            )\n                        if rotation_k:\n                            if rotation_filter is None:\n                                g = av.filter.Graph()\n                                g_src = g.add_buffer(width=frame.width, height=frame.height,\n                                                     format=frame.format.name, time_base=video_stream.time_base)\n                                tail = g_src\n                                for filter_name, filter_args in {1: [(\"transpose\", \"cclock\")],\n                                                                 2: [(\"hflip\", None), (\"vflip\", None)],\n                                                                 3: [(\"transpose\", \"clock\")]}[rotation_k]:\n                                    step = g.add(filter_name, filter_args)\n                                    tail.link_to(step)\n                                    tail = step\n                                g_sink = g.add(\"buffersink\")\n                                tail.link_to(g_sink)\n                                g.configure()","sourceCodeStart":660,"sourceCodeEnd":696,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy_api/latest/_input_impl/video_types.py#L660-L696","documentation":"The transcode writer configures the output stream once from the first frame (source_size) and then asserts every subsequent frame matches. Streams whose resolution changes mid-way (some webm/avi recordings, concatenated files, broken encodes) cannot be re-muxed into a single fixed-geometry H.264 stream, and silent rescaling would corrupt output, so it raises.","triggerScenarios":"Calling the transcode path on a container whose frames change resolution after the first frame — e.g. concatenated videos of different sizes, or a variable-resolution screen capture.","commonSituations":"Users concatenate clips with ffmpeg without normalizing size; screen recorders that resize mid-recording; corrupted files with a stray frame of different geometry.","solutions":["Split the file at the resolution change and transcode each segment separately","Re-encode with scale to a fixed size first: ffmpeg -i in.mp4 -vf scale=1280:720 fixed.mp4, then use that as input","Drop the offending segment if it is a corrupt trailing frame (trim before the change point)"],"exampleFix":"// before\nvideo_input.save_transcoded('out.mp4')  # resolution changes at frame 500\n\n# after\n# normalize: ffmpeg -i in.mp4 -vf scale=1280:720:force_original_aspect_ratio=1,pad=1280:720 fixed.mp4\nVideoFromFile('fixed.mp4').save_transcoded('out.mp4')","handlingStrategy":"validation","validationCode":"# pre-check with ffprobe that frame sizes are constant\n# ffprobe -select_streams v -show_entries frame=width,height -of csv in.mp4 | sort -u","typeGuard":null,"tryCatchPattern":"try:\n    video_input.save_transcoded(out)\nexcept ValueError as e:\n    if 'resolution changes mid-stream' in str(e):\n        # split at change point or scale-normalize then retry\n        raise","preventionTips":["Scale-normalize clips to one resolution before concatenating","Pre-scan frame dimensions with ffprobe for user-supplied files"],"tags":["video","transcode","resolution-change","corrupt-file"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}