@@ -196,49 +196,42 @@ def export_to_video(
196196 if output_video_path is None :
197197 output_video_path = tempfile .NamedTemporaryFile (suffix = ".mp4" ).name
198198
199+ processed_frames = []
199200 if isinstance (video_frames [0 ], np .ndarray ):
200201 logger .info ("Processing np.ndarray frames for video export." )
201- processed_frames = []
202202 for i , frame in enumerate (video_frames ):
203+ # --- DEBUG PRINTS for RAW frame ---
204+ has_nan = np .isnan (frame ).any ()
205+ has_inf = np .isinf (frame ).any ()
206+ min_val = np .min (frame ) if not has_nan and not has_inf else np .nan
207+ max_val = np .max (frame ) if not has_nan and not has_inf else np .nan
208+ mean_val = np .mean (frame ) if not has_nan and not has_inf else np .nan
209+ logger .info (f"[EXPORT RAW { i } ] shape={ frame .shape } , dtype={ frame .dtype } , "
210+ f"NaNs={ has_nan } , Infs={ has_inf } , "
211+ f"Min={ min_val :.4f} , Max={ max_val :.4f} , Mean={ mean_val :.4f} " )
212+ if has_nan or has_inf :
213+ logger .warning (f" Frame { i } RAW has non-finite values!" )
214+ # ------------------------------------
215+
203216 if frame .dtype != np .float32 :
204- frame = frame .astype (np .float32 ) # Ensure float32 for checks
205-
206- # --- Check for non-finite values ---
207- is_finite = np .isfinite (frame )
208- if not np .all (is_finite ):
209- nan_count = np .isnan (frame ).sum ()
210- inf_count = np .isinf (frame ).sum ()
211- logger .warning (f"[EXPORT WARN] Frame { i } : Non-finite values detected! "
212- f"NaNs: { nan_count } , Infs: { inf_count } " )
213- # Sanitize: Replace NaNs with 0, Infs with 0 or 1
214- frame = np .nan_to_num (frame , nan = 0.0 , posinf = 1.0 , neginf = 0.0 )
215- logger .info (f"[EXPORT INFO] Frame { i } : Non-finite values replaced." )
216-
217- # --- Check for out-of-range values [0.0, 1.0] ---
218- min_val = np .min (frame )
219- max_val = np .max (frame )
220- if min_val < 0.0 or max_val > 1.0 :
221- logger .warning (f"[EXPORT WARN] Frame { i } : Values out of [0.0, 1.0] range. "
222- f"Min={ min_val :.4f} , Max={ max_val :.4f} " )
223- # Clip values to the valid range
224- frame = np .clip (frame , 0.0 , 1.0 )
225- logger .info (f"[EXPORT INFO] Frame { i } : Values clipped to [0.0, 1.0]." )
226-
227- # --- Convert to uint8 ---
228- try :
229- frame_uint8 = (frame * 255.0 ).astype (np .uint8 )
230- processed_frames .append (frame_uint8 )
231- except Exception as e :
232- logger .error (f"[EXPORT ERROR] Frame { i } : Failed to convert to uint8: { e } " )
233- # Fallback: append a black frame
234- if len (video_frames ) > 0 and isinstance (video_frames [0 ], np .ndarray ):
235- processed_frames .append (np .zeros (video_frames [0 ].shape , dtype = np .uint8 ))
236-
237- video_frames = processed_frames # Use the sanitized and converted frames
217+ frame = frame .astype (np .float32 )
218+
219+ # Sanitize
220+ frame = np .nan_to_num (frame , nan = 0.0 , posinf = 1.0 , neginf = 0.0 )
221+ frame = np .clip (frame , 0.0 , 1.0 )
222+
223+ frame_uint8 = (frame * 255.0 ).astype (np .uint8 )
224+ processed_frames .append (frame_uint8 )
225+
226+ video_frames = processed_frames
238227
239228
240229 elif isinstance (video_frames [0 ], PIL .Image .Image ):
241230 video_frames = [np .array (frame ) for frame in video_frames ]
231+
232+ if not video_frames :
233+ logger .error ("No frames to write to video." )
234+ return ""
242235
243236 with imageio .get_writer (
244237 output_video_path , fps = fps , quality = quality , bitrate = bitrate , macro_block_size = macro_block_size
0 commit comments