From e4de59be6c38e401ab5529e7ed45f025af014546 Mon Sep 17 00:00:00 2001 From: Ruben van de Ven Date: Tue, 25 Jun 2024 09:31:02 +0200 Subject: [PATCH] Fix exit on window close and ffmpeg with vfr --- trap/renderer.py | 56 ++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/trap/renderer.py b/trap/renderer.py index 58d98ae..accc117 100644 --- a/trap/renderer.py +++ b/trap/renderer.py @@ -212,17 +212,20 @@ class FrameWriter: """Actually write the video""" # ffmpeg -f image2 -ts_from_file 2 -i %d.png out.mp4 logger.info(f"Write frames from {self.tmp_dir.name} to {self.filename}") - ( + encode = ( ffmpeg # the magic here is in --ts_from_file which uses the mtime of the file for the interval # this makes it possible to have non-constant intervals between frames, which is usefull # since we render frames when we get them .input(self.tmp_dir.name + "/%07d.png", format="image2", ts_from_file=2) - .output(self.filename, framerate=self.fps) - .run() + .output(self.filename, vsync="vfr" ) # framerate=self.fps) ) + logger.info(encode.compile()) + encode.run() logger.info(f"Rm frame directory: {self.tmp_dir.name}") + # logger.warning(f"RM DISABLED!") self.tmp_dir.cleanup() + class Renderer: @@ -247,19 +250,21 @@ class Renderer: # TODO: get FPS from frame_emitter # self.out = cv2.VideoWriter(str(filename), fourcc, 23.97, (1280,720)) - self.fps = 10 + self.fps = 60 self.frame_size = (1280,720) self.hide_stats = False self.out_writer = self.start_writer() if self.config.render_file else None self.streaming_process = self.start_streaming() if self.config.render_url else None - if self.config.render_window: - cv2.namedWindow("frame", cv2.WND_PROP_FULLSCREEN) - cv2.setWindowProperty("frame",cv2.WND_PROP_FULLSCREEN,cv2.WINDOW_FULLSCREEN) + if self.config.render_window: + pass + # cv2.namedWindow("frame", cv2.WND_PROP_FULLSCREEN) + # cv2.setWindowProperty("frame",cv2.WND_PROP_FULLSCREEN,cv2.WINDOW_FULLSCREEN) else: pyglet.options["headless"] = True config = pyglet.gl.Config(sample_buffers=1, samples=4) + # , fullscreen=self.config.render_window self.window = pyglet.window.Window(width=self.frame_size[0], height=self.frame_size[1], config=config) self.window.set_handler('on_draw', self.on_draw) self.window.set_handler('on_refresh', self.on_refresh) @@ -438,6 +443,7 @@ class Renderer: def check_running(self, dt): if not self.is_running.is_set(): self.window.close() + self.event_loop.exit() def on_close(self): self.is_running.clear() @@ -479,21 +485,24 @@ class Renderer: self.fps_display.draw() # if streaming, capture buffer and send - if self.streaming_process or self.out_writer: - buf = pyglet.image.get_buffer_manager().get_color_buffer() - img_data = buf.get_image_data() - data = img_data.get_data() - img = np.asanyarray(data).reshape((img_data.height, img_data.width, 4)) - img = cv2.cvtColor(img, cv2.COLOR_BGRA2RGB) - img = np.flip(img, 0) - # img = cv2.flip(img, cv2.0) + try: + if self.streaming_process or self.out_writer: + buf = pyglet.image.get_buffer_manager().get_color_buffer() + img_data = buf.get_image_data() + data = img_data.get_data() # alternative: .get_data("RGBA", image_data.pitch) + img = np.asanyarray(data).reshape((img_data.height, img_data.width, 4)) + img = cv2.cvtColor(img, cv2.COLOR_BGRA2RGB) + img = np.flip(img, 0) + # img = cv2.flip(img, cv2.0) - # cv2.imshow('frame', img) - # cv2.waitKey(1) - if self.streaming_process: - self.streaming_process.stdin.write(img.tobytes()) - if self.out_writer: - self.out_writer.write(img) + # cv2.imshow('frame', img) + # cv2.waitKey(1) + if self.streaming_process: + self.streaming_process.stdin.write(img.tobytes()) + if self.out_writer: + self.out_writer.write(img) + except Exception as e: + logger.exception(e) def start_writer(self): @@ -543,10 +552,11 @@ class Renderer: i=0 first_time = None - event_loop = pyglet.app.EventLoop() + self.event_loop = pyglet.app.EventLoop() pyglet.clock.schedule_interval(self.check_running, 0.1) pyglet.clock.schedule(self.check_frames) - event_loop.run() + self.event_loop.run() + # while self.is_running.is_set():