InfiniteTalk video-to-video#1141
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces support for using a source video (src_video) as conditional input in the InfiniteTalk runner, including AV1 to H.264 transcoding, video duration extraction, and proper cleanup of temporary files in a finally block. It also updates configuration files and adds a shell script for running InfiniteTalk with a single video. Feedback focuses on improving robustness and portability: wrapping the video reader in a try-except block to handle corrupted files, cleaning up old temporary files before creating new ones to prevent disk space leaks, and replacing hardcoded absolute paths in the shell script with relative paths.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| def _get_cond_video_duration(self, video_path): | ||
| if not _is_video(video_path): | ||
| return None | ||
| if VideoReader is None: | ||
| raise ImportError("decord is required for InfiniteTalk video cond_video inputs.") | ||
| vr = VideoReader(video_path, ctx=cpu(0)) | ||
| frame_count = len(vr) | ||
| fps = float(vr.get_avg_fps() or self.target_fps) | ||
| del vr | ||
| gc.collect() | ||
| if frame_count <= 0 or fps <= 0: | ||
| return None | ||
| return frame_count / fps |
There was a problem hiding this comment.
The VideoReader initialization and avg FPS retrieval can raise exceptions (e.g., decord.DECORDError or RuntimeError) if the video file is corrupted, empty, or has an unsupported format. To prevent the entire inference pipeline from crashing, wrap the video loading and processing in a try...except block and return None on failure.
| def _get_cond_video_duration(self, video_path): | |
| if not _is_video(video_path): | |
| return None | |
| if VideoReader is None: | |
| raise ImportError("decord is required for InfiniteTalk video cond_video inputs.") | |
| vr = VideoReader(video_path, ctx=cpu(0)) | |
| frame_count = len(vr) | |
| fps = float(vr.get_avg_fps() or self.target_fps) | |
| del vr | |
| gc.collect() | |
| if frame_count <= 0 or fps <= 0: | |
| return None | |
| return frame_count / fps | |
| def _get_cond_video_duration(self, video_path): | |
| if not _is_video(video_path): | |
| return None | |
| if VideoReader is None: | |
| raise ImportError("decord is required for InfiniteTalk video cond_video inputs.") | |
| try: | |
| vr = VideoReader(video_path, ctx=cpu(0)) | |
| frame_count = len(vr) | |
| fps = float(vr.get_avg_fps() or self.target_fps) | |
| del vr | |
| gc.collect() | |
| if frame_count <= 0 or fps <= 0: | |
| return None | |
| return frame_count / fps | |
| except Exception as exc: | |
| logger.warning(f"Failed to read video duration for {video_path}: {exc}") | |
| return None |
| def _prepare_cond_video_path(self, cond_video): | ||
| if not _is_video(cond_video): | ||
| return cond_video | ||
|
|
||
| codec = self._get_video_codec(cond_video) | ||
| if codec != "av1": | ||
| return cond_video | ||
|
|
||
| fd, output_video_path = tempfile.mkstemp(prefix="infinitetalk_input_h264_", suffix=".mp4") | ||
| os.close(fd) | ||
| cmd = [ | ||
| ffmpeg.get_ffmpeg_exe(), | ||
| "-y", | ||
| "-i", | ||
| cond_video, | ||
| "-c:v", | ||
| "libx264", | ||
| "-c:a", | ||
| "copy", | ||
| output_video_path, | ||
| ] | ||
| try: | ||
| subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) | ||
| except Exception: | ||
| if os.path.exists(output_video_path): | ||
| os.remove(output_video_path) | ||
| raise | ||
| self.cond_video_temp_path = output_video_path | ||
| logger.info(f"Converted AV1 cond_video to H.264: {output_video_path}") | ||
| return output_video_path |
There was a problem hiding this comment.
If _prepare_cond_video_path is called multiple times or if there is an existing temporary file from a previous run, self.cond_video_temp_path will be overwritten without deleting the old temporary file, leading to disk space leaks. Clean up any existing temporary file by calling self._remove_cond_video_temp_path() before creating a new one.
def _prepare_cond_video_path(self, cond_video):
if not _is_video(cond_video):
return cond_video
codec = self._get_video_codec(cond_video)
if codec != "av1":
return cond_video
self._remove_cond_video_temp_path()
fd, output_video_path = tempfile.mkstemp(prefix="infinitetalk_input_h264_", suffix=".mp4")
os.close(fd)
cmd = [
ffmpeg.get_ffmpeg_exe(),
"-y",
"-i",
cond_video,
"-c:v",
"libx264",
"-c:a",
"copy",
output_video_path,
]
try:
subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
except Exception:
if os.path.exists(output_video_path):
os.remove(output_video_path)
raise
self.cond_video_temp_path = output_video_path
logger.info(f"Converted AV1 cond_video to H.264: {output_video_path}")
return output_video_path| lightx2v_path=/data/nvme4/gushiqiao/new/LightX2V | ||
| model_path=/data/nvme0/yongyang/models/x2v_models/wan/Wan2.1-I2V-14B-480P/ |
There was a problem hiding this comment.
The script contains hardcoded absolute paths (/data/nvme4/... and /data/nvme0/...) that are specific to your local environment. This makes the script non-portable and will fail for other users. Consider using relative paths or environment variables to make these paths configurable.
| lightx2v_path=/data/nvme4/gushiqiao/new/LightX2V | |
| model_path=/data/nvme0/yongyang/models/x2v_models/wan/Wan2.1-I2V-14B-480P/ | |
| lightx2v_path="." | |
| model_path="./models/Wan2.1-I2V-14B-480P" |
| --src_video /data/nvme4/gushiqiao/new/InfiniteTalk/examples/single/ref_video.mp4 \ | ||
| --audio_path /data/nvme4/gushiqiao/new/InfiniteTalk/examples/single/1.wav \ |
There was a problem hiding this comment.
These paths are also hardcoded to absolute paths in your local environment. Consider using relative paths or environment variables to make them portable.
| --src_video /data/nvme4/gushiqiao/new/InfiniteTalk/examples/single/ref_video.mp4 \ | |
| --audio_path /data/nvme4/gushiqiao/new/InfiniteTalk/examples/single/1.wav \ | |
| --src_video ./examples/single/ref_video.mp4 \ | |
| --audio_path ./examples/single/1.wav \ |
No description provided.