upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkieran <kieran@harkin.me>2025-02-17 12:00:05 +0000
committerKieran <kieran@harkin.me>2025-07-17 12:28:09 +0100
commit39fbfb5ada692dcbec0a699e82bd963ebda583c5 (patch)
tree3b2519ba4cf5a52c20b8fec901f9ff8d1122ab1c
parent1afb6da049e57dd628ef46a3b0f90300653a66ee (diff)
5e
-rw-r--r--5E.md119
1 files changed, 119 insertions, 0 deletions
diff --git a/5E.md b/5E.md
new file mode 100644
index 0000000..badecae
--- /dev/null
+++ b/5E.md
@@ -0,0 +1,119 @@
1# NIP-5E
2
3## Censorship Resistant Live Streams
4
5`draft` `optional`
6
7Describes a way to distribute live video streams via nostr.
8
9**"Live Video" in this context implies segmented video streams like HLS or DASH**
10
11## N94 Stream
12
13A new `kind: 1053` event lists a single live stream.
14
15Example:
16
17```jsonc
18{
19 "kind": 1053,
20 "tags": [
21 ["title", "<name of the event>"],
22 ["summary", "<description>"],
23 ["image", "<preview image url>"],
24 [
25 "variant",
26 "dim 1920x1080",
27 "bitrate 5000000",
28 "m video/mp2t",
29 "d 1080p"
30 ],
31 [
32 "variant",
33 "dim 1280x720",
34 "bitrate 3000000",
35 "m video/mp2t",
36 "d 720p"
37 ],
38 [
39 "variant",
40 "dim 1920x1080",
41 "bitrate 6000000",
42 "m video/mp4",
43 "d 1080p-fmp4"
44 ],
45 ["t", "hashtag"]
46 ["starts", "<unix timestamp in seconds>"],
47 ["ends", "<unix timestamp in seconds>"],
48 ["relays", "wss://one.com", "wss://two.com", /*...*/],
49 ["pinned", "<event id of pinned live chat message>"],
50 ],
51 "content": "",
52 // other fields...
53}
54```
55
56The `variant` tag works like `imeta` tag from [NIP-92](92.md) and defines a variant stream.
57
58The `d` entry of the `variant` tag is used in the NIP-94 segment event for variant following.
59
60## N94 Segment
61
62Each segment of the stream is a [NIP-94](94.md) event which describes where the file can be found and its hash.
63
64```jsonc
65{
66 "kind": 1063,
67 "tags": [
68 ["d", "1080p"]
69 ["e", "<id-of-kind-1053>"],
70 ["x", "<sha256>"],
71 ["m", "video/mp2t"],
72 ["dim", "1920x1080"],
73 ["duration", "2.033"],
74 ["index", "1234"],
75 ["url", "https://example.com/1234.ts"],
76 ["fallback", "https://another.com/1234.ts"],
77 ["service", "blossom"],
78 ...
79 ]
80 // other fields...
81}
82```
83
84Aside from the standard NIP-94 tags:
85
86- `d`: Variant stream tag.
87- `index`: Segment index, a simple counter. Used of ordering.
88
89`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.
90
91## Implementors
92
93### Consumers
94
95Clients 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.
96
97Other services MAY provide a compatability layer with [NIP-53](53.md) live streams by producing HLS playlists over a N94 Stream.
98
99Clients SHOULD follow only a single variant by using a filter like this:
100
101`{"kinds":[1063],"#e":["<id-of-kind-5053>"],"#d":["1080p"],"limit":10}`
102
103Leaving 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.
104
105### Producers
106
107Segment length SHOULD be carefully considered as a trade off between stream delay and total number of NIP-94 events / segment files.
108
109Using `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.
110
111## Example implementations:
112
113### Player
114
115[zap.stream](https://github.com/v0l/zap.stream/blob/main/src/element/stream/n94-player.tsx)
116
117### Producer
118
119[zap-stream-core](https://github.com/v0l/zap-stream-core/blob/ccb2add6073e5bb68191c42613c34f66583e34fc/crates/zap-stream/src/overseer.rs#L340-L380)