Fix exit on window close and ffmpeg with vfr

This commit is contained in:
Ruben van de Ven 2024-06-25 09:31:02 +02:00
parent 5f5855e4ed
commit e4de59be6c

View file

@ -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():