Files
2025-07-17 12:48:52 +01:00

3.6 KiB

NIP-5E

Nostr Live Streams

draft optional dep:53 dep:92 dep:94 dep:40

Describes a way to distribute live video streams via nostr.

"Live Video" in this context implies segmented video streams like HLS or DASH

All other live interactions (chat/zap/raid etc) from NIP-53 are re-used here so that the main stream event is interchangeable.

N94 Stream

A new kind: 1053 event lists a single live stream.

Example:

{
  "kind": 1053,
  "tags": [
    ["title", "<name of the event>"],
    ["summary", "<description>"],
    ["image", "<preview image url>"],
    [
      "variant",
      "dim 1920x1080",
      "bitrate 5000000",
      "m video/mp2t",
      "d 1080p"
    ],
    [
      "variant",
      "dim 1280x720",
      "bitrate 3000000",
      "m video/mp2t",
      "d 720p"
    ],
    [
      "variant",
      "dim 1920x1080",
      "bitrate 6000000",
      "m video/mp4",
      "d 1080p-fmp4"
    ],
    ["t", "hashtag"],
    ["relays", "wss://one.com", "wss://two.com", /*...*/],
    ["pinned", "<event id of pinned live chat message>"],
    ["goal", "<event id of stream goal>"]
  ],
  "content": "",
  // other fields...
}

The variant tag works like imeta tag from NIP-92 and defines a variant stream.

The d entry of the variant tag is used in the NIP-94 segment event for variant following.

N94 Segment

Each segment of the stream is a NIP-94 event which describes where the file can be found and its hash.

{
  "kind": 1063,
  "tags": [
    ["d", "1080p"],
    ["k", "1053"],
    ["e", "<id-of-kind-1053>"],
    ["x", "<sha256>"],
    ["m", "video/mp2t"],
    ["dim", "1920x1080"],
    ["duration", "2.033"],
    ["index", "1234"],
    ["url", "https://example.com/1234.ts"],
    ["fallback", "https://another.com/1234.ts"],
    ["expiration", "1752752349"],
    ["service", "blossom"],
    ...
  ]
  // other fields...
}

Aside from the standard NIP-94 tags:

  • d: Variant stream tag.
  • index: Segment index, a simple counter. Used of ordering.

service tag should be used for extended censorship resitance by looking up the appropriate server list (Blossom) of the uploader and checking for files on alternate servers.

An NIP-40 expiration tag MAY be used to automatically clean up segments after a specified time, which is useful for live streams that are not intended to persist. Producers SHOULD also automatically delete segment files from file servers.

Implementors

Consumers

Clients wishing to implement a player should use MSE or similar technologies which allow appending data to the player buffer.

Other services MAY provide a compatability layer with NIP-53 live streams by producing HLS playlists over a N94 Stream.

Clients SHOULD listen for new segments using a filter like this:

{"kinds":[1063],"#e":["<id-of-kind-1053>"],"limit":10}

Leaving the subscription open will allow clients to be notified immediately as segments are published and can fetch those segments and append them to the player buffer, enabling live playback without delays.

Producers

Segment length SHOULD be carefully considered as a trade off between stream delay and total number of NIP-94 events / segment files.

Using expiration tags on N94 segments and deleting segment files from servers SHOULD be used to cleanup streams which don't want to persist after the stream is finished.

Example implementations:

Player

zap.stream

Producer

n94