Compare commits

..

5 Commits

Author SHA1 Message Date
Kieran
913fb1d8f8 note about reusing nip53 interaction kinds 2025-07-17 12:48:52 +01:00
Kieran
7c587c37ea expiration tag note 2025-07-17 12:44:44 +01:00
Kieran
8509025e27 add k tag to segment 2025-07-17 12:31:36 +01:00
Kieran
5f33a3d341 minor updates 2025-07-17 12:28:42 +01:00
kieran
39fbfb5ada 5e 2025-07-17 12:28:09 +01:00
4 changed files with 127 additions and 49 deletions

124
5E.md Normal file
View File

@@ -0,0 +1,124 @@
# 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](53.md) 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:
```jsonc
{
"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](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"],
["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](40.md) `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](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 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](https://github.com/v0l/zap.stream/blob/main/src/element/stream/n94-player.tsx)
### Producer
[n94](https://github.com/v0l/zap-stream-core/tree/main/crates/n94)

1
73.md
View File

@@ -20,7 +20,6 @@ There are certain established global content identifiers such as [Book ISBNs](ht
| Geohashes | "geo:`<geohash, lowercase>`" | "geo" | | Geohashes | "geo:`<geohash, lowercase>`" | "geo" |
| Movies | "isan:`<id, without version part>`" | "isan" | | Movies | "isan:`<id, without version part>`" | "isan" |
| Papers | "doi:`<id, lowercase>`" | "doi" | | Papers | "doi:`<id, lowercase>`" | "doi" |
| Music pieces | "isrc:`<id, uppercase>`" | "isrc" |
| Hashtags | "#`<topic, lowercase>`" | "#" | | Hashtags | "#`<topic, lowercase>`" | "#" |
| Podcast Feeds | "podcast:guid:`<guid>`" | "podcast:guid" | | Podcast Feeds | "podcast:guid:`<guid>`" | "podcast:guid" |
| Podcast Episodes | "podcast:item:guid:`<guid>`" | "podcast:item:guid" | | Podcast Episodes | "podcast:item:guid:`<guid>`" | "podcast:item:guid" |

48
F3.md
View File

@@ -1,48 +0,0 @@
NIP-F3
======
Scrobbling
----------
`draft` `optional`
This NIP defines `kind:1073` as a _scrobble_ event. It has the following format:
```yaml
{
"kind": 1073,
"tags": [
["i", "isrc:<code>"],
["title", "<song title>"],
["album", "<song album>", "<optional variant>"],
["artist", "<musician or band>", "<optional variant>"]
]
// other fields...
}
```
### Metadata
`"title"`, `"album"` and `"artist"` should always be included, but in case the ISRC code is also included (as it should unless it's too impossible) ISRC can be seen as the authoritative source for all metadata related to the given song, the other tags being just hints.
### Relays
Scrobbles should be published to the author's "write" relays (as per [NIP-65](65.md)).
### Usage
Given that Nostr is open it makes no sense to speak of a _global_ "most listened" tracks, for example, as _last.fm_ does.
It does make sense, however, for clients to display the "most listened" and other stats in the context of individual relays or groups of relays, as long as such relays are gated to a certain community or trusted to not have sybils or spam.
It also makes sense to display data such as "most listened by your friends", "most listened by friends of friends" and other arbitrary selections.
The same is true for things like a feed of "recently listened" tracks.
#### Commenting on tracks
It makes sense to comment on a track by using a [NIP-22](22.md) with a `"i"` tag containing its ISRC code, as specified in [NIP-73](73.md). That way it's possible to display comments in context with scrobbles on a track page, for example, and whatever else.
#### Correcting History
It shouldn't be hard to "edit" an old scrobble by simply deleting it and creating a new scrobble.

View File

@@ -102,9 +102,11 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
- [NIP-96: HTTP File Storage Integration](96.md) - [NIP-96: HTTP File Storage Integration](96.md)
- [NIP-98: HTTP Auth](98.md) - [NIP-98: HTTP Auth](98.md)
- [NIP-99: Classified Listings](99.md) - [NIP-99: Classified Listings](99.md)
- [NIP-5E: Nostr Live Streams](5E.md)
- [NIP-B0: Web Bookmarks](B0.md) - [NIP-B0: Web Bookmarks](B0.md)
- [NIP-B7: Blossom](B7.md) - [NIP-B7: Blossom](B7.md)
- [NIP-C0: Code Snippets](C0.md) - [NIP-C0: Code Snippets](C0.md)
- [NIP-7D: Threads](7D.md)
- [NIP-C7: Chats](C7.md) - [NIP-C7: Chats](C7.md)
## Event Kinds ## Event Kinds
@@ -147,6 +149,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `1021` | Bid | [15](15.md) | | `1021` | Bid | [15](15.md) |
| `1022` | Bid confirmation | [15](15.md) | | `1022` | Bid confirmation | [15](15.md) |
| `1040` | OpenTimestamps | [03](03.md) | | `1040` | OpenTimestamps | [03](03.md) |
| `1053` | Live Stream | [5E](5E.md) |
| `1059` | Gift Wrap | [59](59.md) | | `1059` | Gift Wrap | [59](59.md) |
| `1063` | File Metadata | [94](94.md) | | `1063` | File Metadata | [94](94.md) |
| `1068` | Poll | [88](88.md) | | `1068` | Poll | [88](88.md) |