@@ -220,6 +220,7 @@ def __init__(self, width: int | None = None, height: int | None = None):
220220 self ._ffmpeg_queue : queue .Queue | None = None
221221 self ._ffmpeg_thread : threading .Thread | None = None
222222 self ._ffmpeg_stop_event : threading .Event | None = None
223+ self ._recording = False
223224 self ._textures : dict [str , rl .Texture ] = {}
224225 self ._target_fps : int = _DEFAULT_FPS
225226 self ._last_fps_log_time : float = time .monotonic ()
@@ -283,39 +284,11 @@ def _close(sig, frame):
283284 self ._render_texture = rl .load_render_texture (self ._width , self ._height )
284285 rl .set_texture_filter (self ._render_texture .texture , rl .TextureFilter .TEXTURE_FILTER_BILINEAR )
285286
286- if RECORD :
287- output_fps = fps * RECORD_SPEED
288- ffmpeg_args = [
289- 'ffmpeg' ,
290- '-v' , 'warning' , # Reduce ffmpeg log spam
291- '-nostats' , # Suppress encoding progress
292- '-f' , 'rawvideo' , # Input format
293- '-pix_fmt' , 'rgba' , # Input pixel format
294- '-s' , f'{ self ._width } x{ self ._height } ' , # Input resolution
295- '-r' , str (fps ), # Input frame rate
296- '-i' , 'pipe:0' , # Input from stdin
297- '-vf' , 'vflip,format=yuv420p' , # Flip vertically and convert to yuv420p
298- '-r' , str (output_fps ), # Output frame rate (for speed multiplier)
299- '-c:v' , 'libx264' ,
300- '-preset' , 'ultrafast' ,
301- ]
302- if RECORD_BITRATE :
303- ffmpeg_args += ['-b:v' , RECORD_BITRATE , '-maxrate' , RECORD_BITRATE , '-bufsize' , RECORD_BITRATE ]
304- ffmpeg_args += [
305- '-y' , # Overwrite existing file
306- '-f' , 'mp4' , # Output format
307- RECORD_OUTPUT , # Output file path
308- ]
309- self ._ffmpeg_proc = subprocess .Popen (ffmpeg_args , stdin = subprocess .PIPE )
310- self ._ffmpeg_queue = queue .Queue (maxsize = 60 ) # Buffer up to 60 frames
311- self ._ffmpeg_stop_event = threading .Event ()
312- self ._ffmpeg_thread = threading .Thread (target = self ._ffmpeg_writer_thread , daemon = True )
313- self ._ffmpeg_thread .start ()
314-
315287 # OFFSCREEN disables FPS limiting for fast offline rendering (e.g. clips)
316288 rl .set_target_fps (0 if OFFSCREEN else fps )
317289
318290 self ._target_fps = fps
291+
319292 self ._set_styles ()
320293 self ._load_fonts ()
321294 self ._patch_text_functions ()
@@ -355,6 +328,39 @@ def _startup_profile_context(self):
355328 print (f"{ green } UI window ready in { elapsed_ms :.1f} ms{ reset } " )
356329 sys .exit (0 )
357330
331+ def begin_recording (self ):
332+ if not RECORD or self ._recording :
333+ return
334+
335+ self ._recording = True
336+ output_fps = self ._target_fps * RECORD_SPEED
337+ ffmpeg_args = [
338+ 'ffmpeg' ,
339+ '-v' , 'warning' , # Reduce ffmpeg log spam
340+ '-nostats' , # Suppress encoding progress
341+ '-f' , 'rawvideo' , # Input format
342+ '-pix_fmt' , 'rgba' , # Input pixel format
343+ '-s' , f'{ self ._width } x{ self ._height } ' , # Input resolution
344+ '-r' , str (self ._target_fps ), # Input frame rate
345+ '-i' , 'pipe:0' , # Input from stdin
346+ '-vf' , 'vflip,format=yuv420p' , # Flip vertically and convert to yuv420p
347+ '-r' , str (output_fps ), # Output frame rate (for speed multiplier)
348+ '-c:v' , 'libx264' ,
349+ '-preset' , 'ultrafast' ,
350+ ]
351+ if RECORD_BITRATE :
352+ ffmpeg_args += ['-b:v' , RECORD_BITRATE , '-maxrate' , RECORD_BITRATE , '-bufsize' , RECORD_BITRATE ]
353+ ffmpeg_args += [
354+ '-y' , # Overwrite existing file
355+ '-f' , 'mp4' , # Output format
356+ RECORD_OUTPUT , # Output file path
357+ ]
358+ self ._ffmpeg_proc = subprocess .Popen (ffmpeg_args , stdin = subprocess .PIPE )
359+ self ._ffmpeg_queue = queue .Queue (maxsize = 60 ) # Buffer up to 60 frames
360+ self ._ffmpeg_stop_event = threading .Event ()
361+ self ._ffmpeg_thread = threading .Thread (target = self ._ffmpeg_writer_thread , daemon = True )
362+ self ._ffmpeg_thread .start ()
363+
358364 def _ffmpeg_writer_thread (self ):
359365 """Background thread that writes frames to ffmpeg."""
360366 while True :
@@ -560,7 +566,7 @@ def render(self):
560566
561567 rl .end_drawing ()
562568
563- if RECORD :
569+ if self . _recording :
564570 image = rl .load_image_from_texture (self ._render_texture .texture )
565571 data_size = image .width * image .height * 4
566572 data = bytes (rl .ffi .buffer (image .data , data_size ))
0 commit comments