Skip to content
This repository was archived by the owner on Mar 21, 2025. It is now read-only.
This repository was archived by the owner on Mar 21, 2025. It is now read-only.

Deliver video frames over WebSocket when JS is allowed #141

@ethanjli

Description

@ethanjli

Refer to:

We can send msgpack blobs of frames (including annotation data/metadata) over a dedicated Action Cable connection. Refer to:

We should use a separate WebSocket connection for the underlying transport of the Action Cable connection because WebSocket is susceptible to head-of-line blocking (refer to https://hpbn.co/websocket/ ). So for example we'd have /cable for normal Action Cable channels, and then /video-cable for the video delivery Action Cable channels.

Probably the simplest approach is to deliver JPEG frames (along with all metadata) over an Action Cable connection, allowing flow control/feedback to be associated with the Action Cable channels used for video frame delivery. Then we'd put frames in a video player component or custom element (e.g. a canvas).

If we don't send the JPEG frames over Turbo Streams, maybe the stream player can be a custom HTML element which also displays accompanying timestamps and (optionally) metrics about dropped frames at ingress from the source and egress to the current browser. Refer to:

Tasks:

  • Make a canvas-based custom element which simply displays frames received over Action Cable (Use Action Cable with MessagePack encoding to deliver video stream frames #153)
  • Try out having one WebSocket connection per video stream, using Action Cable for CSRF and channel integrity (Use Action Cable with MessagePack encoding to deliver video stream frames #153)
  • Deliver video frames with metadata using the actioncable-v1-msgpack subprotocol and the Any Cable client (Use Action Cable with MessagePack encoding to deliver video stream frames #153)
  • If we must multiplex using Action Cable, improve fairness of the scheduling of video-cable utilization, to prevent any one stream from being starved - maybe with round-robin reading from each send channel for a given action cable connection? Not needed - having one WebSocket connection per connection works and is simpler, and it's more like the MJPEG-over-HTTP approach for no-JS browsers.
  • Confirm whether this works in iOS Safari with JS enabled (embedded MJPEG streams don't seem to work there)
  • Add toggle for showing frame timestamp in the stream player
  • Add a local buffer of most-recently-received frames in the stream player, with scrubbing

Metadata

Metadata

Assignees

No one assigned

    Labels

    stage: devOn/for a development versiontype: fixIterations on existing features or infrastructurework: complicatedThe situation is complicated (known unknowns), good practices used

    Type

    No type

    Projects

    Status

    🏗 In progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions