# NIP-5E ## Censorship Resistant Live Streams `draft` `optional` Describes a way to distribute live video streams via nostr. **"Live Video" in this context implies segmented video streams like HLS or DASH** ## N94 Stream A new `kind: 1053` event lists a single live stream. Example: ```jsonc { "kind": 1053, "tags": [ ["title", ""], ["summary", ""], ["image", ""], [ "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"] ["starts", ""], ["ends", ""], ["relays", "wss://one.com", "wss://two.com", /*...*/], ["pinned", ""], ], "content": "", // other fields... } ``` The `variant` tag works like `imeta` tag from [NIP-92](92.md) 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](94.md) event which describes where the file can be found and its hash. ```jsonc { "kind": 1063, "tags": [ ["d", "1080p"] ["e", ""], ["x", ""], ["m", "video/mp2t"], ["dim", "1920x1080"], ["duration", "2.033"], ["index", "1234"], ["url", "https://example.com/1234.ts"], ["fallback", "https://another.com/1234.ts"], ["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. ## Implementors ### Consumers Clients wishing to implement a player should use [MSE](https://developer.mozilla.org/en-US/docs/Web/API/Media_Source_Extensions_API) or similar technologies which allow appending data to the player buffer. Other services MAY provide a compatability layer with [NIP-53](53.md) live streams by producing HLS playlists over a N94 Stream. Clients SHOULD follow only a single variant by using a filter like this: `{"kinds":[1063],"#e":[""],"#d":["1080p"],"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. ### 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](https://github.com/v0l/zap.stream/blob/main/src/element/stream/n94-player.tsx) ### Producer [zap-stream-core](https://github.com/v0l/zap-stream-core/blob/ccb2add6073e5bb68191c42613c34f66583e34fc/crates/zap-stream/src/overseer.rs#L340-L380)