Input subclass, annotate it on the model, and read frames. You manage buffer cleanup between sessions yourself.
Video frames are np.ndarray with shape (height, width, 3), dtype uint8, in RGB channel order.
Declaring input tracks
webcam buffer automatically. You access them via self.input.webcam.
Reading frames
Both methods return the most recent frames and discard any older backlog, so your model always processes the freshest input.try_read() (non-blocking)
Returns a list of the most recent n frames, or None if fewer than n are available. When None is returned the buffer is left untouched.
try_read() reads one frame (n=1). Pass n to read multiple frames at once (e.g. self.input.webcam.try_read(n=4)). The return value is always a list when frames are available, even for n=1.
read(n) (async)
Waits until n frames are available, then returns the most recent n as a list.
read(n) waits until enough frames have arrived, then resumes. Pass a larger n for models that need multiple frames per forward pass (e.g. await self.input.webcam.read(4)).
BufferClosed
In ReactorModel,BufferClosed is not caught automatically. If you use read() and the client disconnects, it raises BufferClosed. Wrap the inner loop in a try/except:
Buffer cleanup
Input buffers are not reset automatically between sessions. You need to close them on disconnect and reset them on connect. Close buffers in@disconnected to signal end-of-input and wake any blocked read() calls:
@connected to re-open for the new session:
read() calls may see leftover frames. If you don’t reset, read() will raise BufferClosed for the new client.
Full example: video-to-video
Next
Audio Output
Add audio output tracks to your model.
The Run Loop
Emitting frames, batches, backpressure, and adaptive frame rates.