def unregister(self, func: "H264CameraServer"): try: del self.pipelines[func.name] if NT_AVAIL: NetworkDict("/GStreamer").delete(func.name) except KeyError: pass
def __init__(self, visible=True): self.visible = visible self.app = Router() if NT_AVAIL: self.netdict = NetworkDict("/CameraPublisher") self.funcs = {} # {name: route} self.index_route = [ Route("/", LiteralTemplate(self.TEMPLATE, funcs=self.funcs.keys())) ] self.listeners = { "startup": set(), "shutdown": set(), "pipeline_update": set() } self._update()
class GetNT(PutNT): def on_start(self): self.table = NetworkDict(self.settings.path) self.validate_paths() def validate_paths(self): try: val = self.table[self.settings.key] except KeyError: raise ValueError(f"Key does {self.settings.key} not exist.") @dataclass class Inputs: pass @dataclass class Outputs: val: AnyType = None def run(self, inputs): val = self.table.get(self.settings.key, None) if val is None: HookInstance.cancel_output("val") return self.Outputs() return self.Outputs(val=val)
def register(self, func: "H264CameraServer"): if func.name in self.pipelines: raise ValueError("Cannot have duplicate name") pipeline = func.pipeline self.pipelines[func.name] = pipeline if NT_AVAIL: url = self.hook.url.split("/")[2].split(":")[0] NetworkDict(f"/GStreamer/{func.name}")["/streams"] = [ f"rtsp://{url}:{self.port}/{func.name}", ]
class GetNT(PutNT): def on_start(self): self.table = NetworkDict(self.settings.path) @dataclass class Inputs: pass @dataclass class Outputs: val: AnyType = None def run(self, inputs): val = self.table.get(self.settings.key, None) if val is None: HookInstance.cancel_output("val") return self.Outputs() return self.Outputs(val=val)
class CamHook(Hook): # Matches both "camera.mjpg" and "camera.mjpeg" ROUTE_URL = "/{func}.mjpe?g" # Route to bind to STREAM_URL = "/{func}.mjpeg" # Canonical path TEMPLATE = jinja2.Template(""" <html> <head> <title>CameraServer: {{ funcs|length }}</title> </head> <body> <h1>CameraServer</h1> <ul> {% for func in funcs %} <li><a href=".URL">{{ func }}</a></li> {% else %} <li>None</li> {% endfor %} </ul> </body> </html> """.replace("URL", STREAM_URL.replace("{", "{{ ").replace("}", " }}")) # {func} --> {{ func }} ) CAMERA_NAME = "OpenSight: {func}" CAMERA_URL = f"mjpeg:{{url}}{STREAM_URL}?" def __init__(self, visible=True): self.visible = visible self.app = Router() if NT_AVAIL: self.netdict = NetworkDict("/CameraPublisher") self.funcs = {} # {name: route} self.index_route = [ Route("/", LiteralTemplate(self.TEMPLATE, funcs=self.funcs.keys())) ] self.listeners = { "startup": set(), "shutdown": set(), "pipeline_update": set() } self._update() def _update(self): self.app.routes = self.index_route + list(self.funcs.values()) def endpoint(self, func): def image(request): return MjpegResponse(request, func.src.src) return image def register(self, func): if func.id in self.funcs: raise ValueError("Cannot have duplicate name") self.funcs[func.id] = Route(self.ROUTE_URL.format(func=func.id), self.endpoint(func)) self._update() # https://github.com/wpilibsuite/allwpilib/blob/ec9738245d86ec5a535a7d9eb22eadc78dee88b4/wpilibj/src/main/java/edu/wpi/first/wpilibj/CameraServer.java#L313 if NT_AVAIL: ntdict = self.netdict.get_subtable( self.CAMERA_NAME.format(func=func.id)) ntdict["streams"] = [ self.CAMERA_URL.format(url=self.url, func=func.id) ] def unregister(self, func): try: del self.funcs[func.id] except KeyError: pass if NT_AVAIL: self.netdict.delete_table(self.CAMERA_NAME.format(func=func.id)) self._update()
def on_start(self): self.validate_paths() self.table = NetworkDict(self.settings.path)
def on_start(self): self.table = NetworkDict(self.settings.path)