Requires Python 3.8 or later.
Run pip install gabriel-client
Create an instance of websocket_client.WebsocketClient
. Then call
the launch()
method. The WebsocketClient
constructor's arguments are host
,
port
, producer_wrappers
(a list of
websocket_client.ProducerWrapper
instances), and consumer
(a
function called whenever a new result is available).
opencv_adater.OpencvAdapter
provides producer_wrappers
and a consumer.
push_source.Source
provides producer_wrappers
.
Use of either of these classes is optional. You can define your own producers
and/or a consumer, and just use WebsocketClient
with these. OpencvAdapter
is
intended for clients that send image frames from a webcam or a video file,
without doing early discard. OpencvAdapter.consumer
decodes images returned
by the server and then calls the consume_frame
callback that was passed to the
OpencvAdapter
's constructor. This consumer will not work when a
ResultWrapper
contains more than one result, or a result that is not an
image. However, you can still use the producer from OpencvAdapter
and write
your own custom consumer. The OpencvAdapter
requires OpenCV to be
installed and accessible to Python. The
opencv-python package is a convenient
way to install OpenCV for Python. If you do not use OpencvAdapter
, you do not
have to have OpenCV installed.
If you choose to write your own ProducerWrapper
, you must pass a
coroutine function
as the producer
argument to the constructor of ProducerWrapper
. The
producer
is run on an
asyncio event loop,
so it is important that the producer
does not include any blocking code. This
would cause the whole event loop to block.
If you need to run blocking code to get an input for Gabriel, you can use
push_source.Source
. You should also use push_source.Source
whenever you want
to run the code to produce a frame before a token is available.
push_source.Source
should always be used for sending frames that pass early
discard filters. Create an instance of push_source.Source
and include the
ProducerWrapper
returned from push_source.Source.get_producer_wrapper()
in
the list of producer_wrappers
you pass to the constructor of
WebsocketClient
. You can then pass the push_source.Source
instance to a separate process started using the multiprocessing
module. When
results are ready, send them with push_source.Source.send()
.
push_source.Source.send()
should only ever be called from one process. Create
at least one push_source.Source
per process that you want to send frames from.
Frames sent with push_source.Source.send()
are not guaranteed to be sent to
the server. As soon as a token becomes available, the most recent unsent frame
will be sent. If push_source.Source.send()
is called multiple times before a
token becomes available, only the most recent frame will actually be sent to the
server. If a token becomes available before the next frame is ready, Gabriel
will send the next frame after push_source.Source.send()
is called.
push_source.Source
will not block the event loop.
If you want the client to ignore results, you can pass
push_source.consumer
as the consumer
argument to WebsocketClient
.
WebsocketClient
does not run producers until there is a token available to
send a result from them. This guarantees that producers are not run more
frequently than they need to be, and when results are sent to the server, they
are as recent as possible. However, running the producer introduces a delay
between when a token comes back and when the next frame is sent.
push_source.Source
allows frames to be generated asynchronously from tokens
returning. The two downsides to this approach are:
- Some frames might be generated and never sent.
- When a token does come back, the last frame sent to a
push_source.Source
instance might have been generated a while ago. In practice, hopefully tokens will be returned to the client at a reasonable rate.
If you want to measure average round trip time (RTT) and frames per second
(FPS), use measurement_client.MeasurementClient
in place of WebsocketClient
.
average RTT and FPS information will be printed automatically, every
output_freq
frames.
- The round trip example
client
uses
OpencvAdapter
. - The one way example producer client uses a custom producer.
- The one way example
push client
uses
push_source.Source
. - The OpenRTiST
playback stream client
uses
MeasurementClient
.
Update the version number in setup.py. Then follow these instructions.