Fix exit on window close and ffmpeg with vfr
This commit is contained in:
parent
5f5855e4ed
commit
e4de59be6c
1 changed files with 33 additions and 23 deletions
|
@ -212,19 +212,22 @@ class FrameWriter:
|
||||||
"""Actually write the video"""
|
"""Actually write the video"""
|
||||||
# ffmpeg -f image2 -ts_from_file 2 -i %d.png out.mp4
|
# 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}")
|
logger.info(f"Write frames from {self.tmp_dir.name} to {self.filename}")
|
||||||
(
|
encode = (
|
||||||
ffmpeg
|
ffmpeg
|
||||||
# the magic here is in --ts_from_file which uses the mtime of the file for the interval
|
# 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
|
# this makes it possible to have non-constant intervals between frames, which is usefull
|
||||||
# since we render frames when we get them
|
# since we render frames when we get them
|
||||||
.input(self.tmp_dir.name + "/%07d.png", format="image2", ts_from_file=2)
|
.input(self.tmp_dir.name + "/%07d.png", format="image2", ts_from_file=2)
|
||||||
.output(self.filename, framerate=self.fps)
|
.output(self.filename, vsync="vfr" ) # framerate=self.fps)
|
||||||
.run()
|
|
||||||
)
|
)
|
||||||
|
logger.info(encode.compile())
|
||||||
|
encode.run()
|
||||||
logger.info(f"Rm frame directory: {self.tmp_dir.name}")
|
logger.info(f"Rm frame directory: {self.tmp_dir.name}")
|
||||||
|
# logger.warning(f"RM DISABLED!")
|
||||||
self.tmp_dir.cleanup()
|
self.tmp_dir.cleanup()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Renderer:
|
class Renderer:
|
||||||
def __init__(self, config: Namespace, is_running: BaseEvent):
|
def __init__(self, config: Namespace, is_running: BaseEvent):
|
||||||
self.config = config
|
self.config = config
|
||||||
|
@ -247,19 +250,21 @@ class Renderer:
|
||||||
|
|
||||||
# TODO: get FPS from frame_emitter
|
# TODO: get FPS from frame_emitter
|
||||||
# self.out = cv2.VideoWriter(str(filename), fourcc, 23.97, (1280,720))
|
# self.out = cv2.VideoWriter(str(filename), fourcc, 23.97, (1280,720))
|
||||||
self.fps = 10
|
self.fps = 60
|
||||||
self.frame_size = (1280,720)
|
self.frame_size = (1280,720)
|
||||||
self.hide_stats = False
|
self.hide_stats = False
|
||||||
self.out_writer = self.start_writer() if self.config.render_file else None
|
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
|
self.streaming_process = self.start_streaming() if self.config.render_url else None
|
||||||
|
|
||||||
if self.config.render_window:
|
if self.config.render_window:
|
||||||
cv2.namedWindow("frame", cv2.WND_PROP_FULLSCREEN)
|
pass
|
||||||
cv2.setWindowProperty("frame",cv2.WND_PROP_FULLSCREEN,cv2.WINDOW_FULLSCREEN)
|
# cv2.namedWindow("frame", cv2.WND_PROP_FULLSCREEN)
|
||||||
|
# cv2.setWindowProperty("frame",cv2.WND_PROP_FULLSCREEN,cv2.WINDOW_FULLSCREEN)
|
||||||
else:
|
else:
|
||||||
pyglet.options["headless"] = True
|
pyglet.options["headless"] = True
|
||||||
|
|
||||||
config = pyglet.gl.Config(sample_buffers=1, samples=4)
|
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 = 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_draw', self.on_draw)
|
||||||
self.window.set_handler('on_refresh', self.on_refresh)
|
self.window.set_handler('on_refresh', self.on_refresh)
|
||||||
|
@ -438,6 +443,7 @@ class Renderer:
|
||||||
def check_running(self, dt):
|
def check_running(self, dt):
|
||||||
if not self.is_running.is_set():
|
if not self.is_running.is_set():
|
||||||
self.window.close()
|
self.window.close()
|
||||||
|
self.event_loop.exit()
|
||||||
|
|
||||||
def on_close(self):
|
def on_close(self):
|
||||||
self.is_running.clear()
|
self.is_running.clear()
|
||||||
|
@ -479,10 +485,11 @@ class Renderer:
|
||||||
self.fps_display.draw()
|
self.fps_display.draw()
|
||||||
|
|
||||||
# if streaming, capture buffer and send
|
# if streaming, capture buffer and send
|
||||||
|
try:
|
||||||
if self.streaming_process or self.out_writer:
|
if self.streaming_process or self.out_writer:
|
||||||
buf = pyglet.image.get_buffer_manager().get_color_buffer()
|
buf = pyglet.image.get_buffer_manager().get_color_buffer()
|
||||||
img_data = buf.get_image_data()
|
img_data = buf.get_image_data()
|
||||||
data = img_data.get_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 = np.asanyarray(data).reshape((img_data.height, img_data.width, 4))
|
||||||
img = cv2.cvtColor(img, cv2.COLOR_BGRA2RGB)
|
img = cv2.cvtColor(img, cv2.COLOR_BGRA2RGB)
|
||||||
img = np.flip(img, 0)
|
img = np.flip(img, 0)
|
||||||
|
@ -494,6 +501,8 @@ class Renderer:
|
||||||
self.streaming_process.stdin.write(img.tobytes())
|
self.streaming_process.stdin.write(img.tobytes())
|
||||||
if self.out_writer:
|
if self.out_writer:
|
||||||
self.out_writer.write(img)
|
self.out_writer.write(img)
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception(e)
|
||||||
|
|
||||||
|
|
||||||
def start_writer(self):
|
def start_writer(self):
|
||||||
|
@ -543,10 +552,11 @@ class Renderer:
|
||||||
i=0
|
i=0
|
||||||
first_time = None
|
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_interval(self.check_running, 0.1)
|
||||||
pyglet.clock.schedule(self.check_frames)
|
pyglet.clock.schedule(self.check_frames)
|
||||||
event_loop.run()
|
self.event_loop.run()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# while self.is_running.is_set():
|
# while self.is_running.is_set():
|
||||||
|
|
Loading…
Reference in a new issue