openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 200 supported car makes and models.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123 lines
3.4 KiB

3 days ago
from argparse import ArgumentParser
4 days ago
from msgq.visionipc import VisionIpcClient, VisionStreamType
from cereal.messaging import SubMaster
4 days ago
import os
import signal
import subprocess
from subprocess import DEVNULL
import time
import atexit
from random import randint
4 days ago
DEFAULT_DISPLAY = ":99"
4 days ago
RESOLUTION = "2160x1080"
PIXEL_DEPTH = "24"
FRAMERATE = 20
3 days ago
DEFAULT_OUTPUT = "output.mp4"
DEMO_ROUTE = "a2a0ccea32023010/2023-07-27--13-01-19/0"
4 days ago
def wait_for_video():
sm = SubMaster(['uiDebug'])
no_frames_drawn = True
while no_frames_drawn:
sm.update()
no_frames_drawn = sm['uiDebug'].drawTimeMillis == 0.
def ensure_xvfb(display: str):
xvfb_cmd = ["Xvfb", display, "-screen", "0", f"{RESOLUTION}x{PIXEL_DEPTH}"]
4 days ago
xvfb_proc = subprocess.Popen(xvfb_cmd, stdout=DEVNULL, stderr=DEVNULL)
time.sleep(1)
4 days ago
if xvfb_proc.poll() is not None:
raise RuntimeError(f"Failed to start Xvfb on display {display}")
4 days ago
return xvfb_proc
3 days ago
def main(route: str, output_filepath: str, start_seconds: int, end_seconds: int):
assert end_seconds > start_seconds, 'end must be greater than start'
display = ':' + str(randint(99, 999))
3 days ago
duration = end_seconds - start_seconds
4 days ago
env = os.environ.copy()
env["DISPLAY"] = display
4 days ago
env["QT_QPA_PLATFORM"] = "xcb"
print(f'starting xvfb on display {display}')
xvfb_proc = ensure_xvfb(display)
4 days ago
atexit.register(lambda: xvfb_proc.terminate()) # Ensure cleanup on exit
ui_args = ["./selfdrive/ui/ui"]
ui_proc = subprocess.Popen(ui_args, env=env, stdout=DEVNULL, stderr=DEVNULL)
atexit.register(lambda: ui_proc.terminate())
replay_proc = subprocess.Popen(["./tools/replay/replay", "-c", "1", "-s", str(start_seconds), "--no-loop", "--demo"], env=env, stdout=DEVNULL, stderr=DEVNULL)
4 days ago
atexit.register(lambda: replay_proc.terminate())
# Wait for video data
wait_for_video()
time.sleep(2)
4 days ago
# Start FFmpeg
ffmpeg_cmd = [
"ffmpeg",
3 days ago
"-y",
4 days ago
"-video_size",
RESOLUTION,
"-framerate",
str(FRAMERATE),
"-f",
"x11grab",
"-draw_mouse",
"0",
"-i",
env.get('DISPLAY'),
4 days ago
"-c:v",
"libx264",
"-preset",
"ultrafast",
"-pix_fmt",
"yuv420p",
3 days ago
output_filepath,
4 days ago
]
ffmpeg_proc = subprocess.Popen(ffmpeg_cmd, env=env, stdout=DEVNULL, stderr=DEVNULL)
atexit.register(lambda: ffmpeg_proc.terminate())
3 days ago
print(f'starting at {start_seconds} seconds and clipping {duration} seconds')
time.sleep(duration)
4 days ago
# Stop FFmpeg gracefully
ffmpeg_proc.send_signal(signal.SIGINT)
ffmpeg_proc.wait(timeout=5)
# Clean up
ui_proc.terminate()
ui_proc.wait(timeout=5)
xvfb_proc.terminate()
xvfb_proc.wait(timeout=5)
3 days ago
print(f"Recording complete: {output_filepath}")
4 days ago
if __name__ == "__main__":
3 days ago
p = ArgumentParser(
prog='clip.py',
description='Clip your openpilot route.',
epilog='comma.ai'
)
p.add_argument('-r', '--route', help='Route', default=DEMO_ROUTE)
p.add_argument('-o', '--output', help='Output clip to (.mp4)', default=DEFAULT_OUTPUT)
p.add_argument('-s', '--start', help='Start clipping at <start> seconds', type=int, required=True)
p.add_argument('-e', '--end', help='Stop clipping at <end> seconds', type=int, required=True)
args = p.parse_args()
4 days ago
try:
3 days ago
main(args.route, args.output, args.start, args.end)
4 days ago
except KeyboardInterrupt:
print("Interrupted by user")
except Exception as e:
print(f"Error: {e}")
finally:
# Ensure all processes are terminated
atexit._run_exitfuncs()