Skip to content

SEI Injection Plugin

features = ["sei"]

Useful for embedding timestamps, watermarks, and business metadata in-stream.

SEI is inserted as in-band video NALs (H.264 type 6 / H.265 prefix SEI type 39), so every downstream protocol that remuxes full Annex-B carries it unchanged — including HLS / LL-HLS MPEG-TS segments. Players must parse SEI themselves (e.g. via a WebRTC DataChannel or a custom parser).

POST /sei/api/inject
Content-Type: application/json
{
"stream_path": "live/test",
"payload": "hello",
"payload_encoding": "utf8",
"uuid": "00112233445566778899aabbccddeeff",
"once": true,
"target_path": "live/test_sei"
}
FieldRequiredDescription
stream_pathyesStream path; matches the SEI transform job’s source or target path
payloadyesSEI payload content
payload_encodingnoutf8 (default) or base64
uuidno16-byte UUID (32 hex chars) for user-data-unregistered SEI; random when omitted
oncenotrue (default): insert once on the next eligible frame; false: repeat on every eligible frame until replaced
target_pathnoWhen the stream has no SEI transform job yet, create a source → target job publishing to this path

SEI is inserted on IDR frames by default; set sei.insert_on_every_frame: true to insert on every frame.

  • 200: enqueued; returns job_id / target_path / pending count
  • 400: missing stream_path, empty payload, invalid base64/uuid
  • 404: no live publisher for stream_path
  • 409: stream exists but has no SEI transform job and no target_path was supplied

The transform job republishes the injected bitstream to target_path; the HLS/LL-HLS TS remux of that path preserves SEI NALs as-is. Play the injected stream via the target_path (e.g. /hls/live/test_sei.m3u8).

  • Inject only — no SEI extraction/parsing API.
  • No ID3 timed metadata, EXT-X-DATERANGE, or CMAF emsg; players relying on hls.js ID3 cues cannot consume SEI and need a custom parser.