deepfakes/faceswap · critical · FaceswapError
There is a mismatch between the number of frames found in th
Error message
There is a mismatch between the number of frames found in the video file ({len(pts_time)}) and the number of frames found in the alignments file ({len(self.data)}).\nThis can be caused by a number of issues:\n - The video has a Variable Frame Rate and FFMPEG is having a hard time calculating the correct number of frames.\n - You are working with a Merged Alignments file. This is not supported for your current use case.\nYou should either extract the video to individual frames, re-encode the video at a constant frame rate and re-run extraction or work with a dedicated alignments file for your requested video. What it means
Raised by Alignments.save_timecodes/update flow (lib/align/alignments.py) after merging video frame timestamps (pts_time from FFProbe) into the alignments data: the number of keys in the alignments file must equal the number of frames FFProbe found in the video. A mismatch means the alignments were generated against a different frame set than the current video.
Source
Thrown at lib/align/alignments.py:198
sample_filename = next(fname for fname in self.data)
basename = sample_filename[:sample_filename.rfind("_")]
ext = os.path.splitext(sample_filename)[-1]
logger.debug("sample filename: '%s', base filename: '%s' extension: '%s'",
sample_filename, basename, ext)
logger.info("Saving video meta information to Alignments file")
for idx, pts in enumerate(pts_time):
meta: dict[T.Literal["pts_time", "keyframe"], int] = {"pts_time": pts,
"keyframe": idx in keyframes}
key = f"{basename}_{idx + 1:06d}{ext}"
if key not in self.data:
self.data[key] = AlignmentsEntry(video_meta=meta)
else:
self.data[key].video_meta = meta
logger.debug("Alignments count: %s, timestamp count: %s", len(self.data), len(pts_time))
if len(self.data) != len(pts_time):
raise FaceswapError(
"There is a mismatch between the number of frames found in the video file "
f"({len(pts_time)}) and the number of frames found in the alignments file "
f"({len(self.data)}).\nThis can be caused by a number of issues:"
"\n - The video has a Variable Frame Rate and FFMPEG is having a hard time "
"calculating the correct number of frames."
"\n - You are working with a Merged Alignments file. This is not supported for "
"your current use case."
"\nYou should either extract the video to individual frames, re-encode the "
"video at a constant frame rate and re-run extraction or work with a dedicated "
"alignments file for your requested video.")
self._io.save()
# << VALIDATION >> #
def frame_exists(self, frame_name: str) -> bool:
"""Check whether a given frame_name exists within the alignments :attr:`data`.
Parameters
----------View on GitHub (pinned to f530cb7508)
Solutions
- Extract the video to individual PNG frames and run the job against the frames folder instead of the video file
- Re-encode the video at a constant frame rate (e.g. ffmpeg -i in.mp4 -vsync cfr -r <fps> out.mp4) and re-run extraction
- Use a dedicated alignments file for this video rather than a merged alignments file (check with the alignments tool that frame counts match)
Example fix
# before: VFR video used directly faceswap.py align -a alignments.fsa -v input.mov # -> frame count mismatch # after: re-encode CFR first ffmpeg -i input.mov -vsync cfr -r 30 -pix_fmt yuv420p input_cfr.mp4 faceswap.py align -a alignments_cfr.fsa -v input_cfr.mp4
Defensive patterns
Strategy: validation
Validate before calling
import subprocess, json
def ffprobe_frame_count(video):
out = subprocess.check_output([
"ffprobe", "-v", "error", "-select_streams", "v:0",
"-count_packets", "-show_entries", "stream=nb_read_packets",
"-of", "json", video])
return json.loads(out)["streams"][0]["nb_read_packets"]
# compare against len(alignments.frames) before running the video-meta job Try / catch
try:
alignments.save_timecodes(...)
except FaceswapError as err:
if "mismatch between the number of frames" in str(err):
# fall back to frames-based workflow
extract_to_frames(video)
else:
raise Prevention
- Prefer extracted image sequences over raw video for alignment jobs
- Normalize videos to CFR before extraction (ffmpeg -vsync cfr)
- Keep one alignments file per video; never merge across clips
When it happens
Trigger: Calling the alignments tool job that writes video metadata (e.g. 'extract'/'sort' video-meta update) on a Variable Frame Rate video where FFProbe miscounts frames, or supplying an alignments file that covers more than one video (merged alignments) or was built from extracted frames then reused against a re-encoded video.
Common situations: Processing a screen recording or phone-captured VFR video; using one combined alignments file across multiple clips; re-encoding a video (changing frame count) after extraction; ffmpeg/ffprobe version differences in frame counting.
Related errors
- The given shape {shape} is not valid. Valid shapes: {list(sh
- Dictionary keys {sorted(inbound)} should be a subset of data
- You have selected the mask type '{mask_type}' but at least o
- The input file '{input_location}' is not a valid video
- Video file '{file_path}' does not exist
AI-assisted analysis of deepfakes/faceswap@f530cb7508 (2026-08-15).
Data as JSON: /api/errors/0159eada119a10ce.
Report an issue: GitHub.