268 lines
10 KiB
Markdown
268 lines
10 KiB
Markdown
NIP-53
|
|
======
|
|
|
|
Live Activities
|
|
---------------
|
|
|
|
`draft` `optional`
|
|
|
|
This NIP introduces event kinds to advertise live spaces and the participation of pubkeys in them.
|
|
|
|
## Live Streaming
|
|
|
|
A special event with `kind:30311` "Live Streaming Event" is defined as an _addressable event_ whose tags advertise the content and participants of a live stream.
|
|
|
|
Each `p` tag SHOULD have a **displayable** marker name for the current role (e.g. `Host`, `Speaker`, `Participant`) of the user in the event and the relay information MAY be empty. This event will be constantly updated as participants join and leave the activity.
|
|
|
|
For example:
|
|
|
|
```jsonc
|
|
{
|
|
"kind": 30311,
|
|
"tags": [
|
|
["d", "<unique identifier>"],
|
|
["title", "<name of the event>"],
|
|
["summary", "<description>"],
|
|
["image", "<preview image url>"],
|
|
["t", "hashtag"]
|
|
["streaming", "<url>"],
|
|
["recording", "<url>"], // used to place the edited video once the activity is over
|
|
["starts", "<unix timestamp in seconds>"],
|
|
["ends", "<unix timestamp in seconds>"],
|
|
["status", "<planned, live, ended>"],
|
|
["current_participants", "<number>"],
|
|
["total_participants", "<number>"],
|
|
["p", "91cf9..4e5ca", "wss://provider1.com/", "Host", "<proof>"],
|
|
["p", "14aeb..8dad4", "wss://provider2.com/nostr", "Speaker"],
|
|
["p", "612ae..e610f", "ws://provider3.com/ws", "Participant"],
|
|
["relays", "wss://one.com", "wss://two.com", /*...*/],
|
|
["pinned", "<event id of pinned live chat message>"],
|
|
],
|
|
"content": "",
|
|
// other fields...
|
|
}
|
|
```
|
|
|
|
A distinct `d` tag should be used for each activity. All other tags are optional.
|
|
|
|
Providers SHOULD keep the participant list small (e.g. under 1000 users) and, when limits are reached, Providers SHOULD select which participants get named in the event. Clients should not expect a comprehensive list. Once the activity ends, the event can be deleted or updated to summarize the activity and provide async content (e.g. recording of the event).
|
|
|
|
Clients are expected to subscribe to `kind:30311` events in general or for given follow lists and statuses. Clients MAY display participants' roles in activities as well as access points to join the activity.
|
|
|
|
Live Activity management clients are expected to constantly update `kind:30311` during the event. Clients MAY choose to consider `status=live` events after 1hr without any update as `ended`. The `starts` and `ends` timestamp SHOULD be updated when the status changes to and from `live`
|
|
|
|
The activity MUST be linked to using the [NIP-19](19.md) `naddr` code along with the `a` tag.
|
|
|
|
### Proof of Agreement to Participate
|
|
|
|
Event owners can add proof as the 5th term in each `p` tag to clarify the participant's agreement in joining the event. The proof is a signed SHA256 of the complete `a` Tag of the event (`kind:pubkey:dTag`) by each `p`'s private key, encoded in hex.
|
|
|
|
Clients MAY only display participants if the proof is available or MAY display participants as "invited" if the proof is not available.
|
|
|
|
This feature is important to avoid malicious event owners adding large account holders to the event, without their knowledge, to lure their followers into the malicious owner's trap.
|
|
|
|
### Live Chat Message
|
|
|
|
Event `kind:1311` is live chat's channel message. Clients MUST include the `a` tag of the activity. An `e` tag denotes the direct parent message this post is replying to.
|
|
|
|
```jsonc
|
|
{
|
|
"kind": 1311,
|
|
"tags": [
|
|
["a", "30311:<Community event author pubkey>:<d-identifier of the community>", "<Optional relay url>"],
|
|
],
|
|
"content": "Zaps to live streams is beautiful.",
|
|
// other fields...
|
|
}
|
|
```
|
|
|
|
`q` tags MAY be used when citing events in the `.content` with [NIP-21](21.md).
|
|
|
|
```json
|
|
["q", "<event-id> or <event-address>", "<relay-url>", "<pubkey-if-a-regular-event>"]
|
|
```
|
|
|
|
Hosts may choose to pin one or more live chat messages by updating the `pinned` tags in the live event kind `30311`.
|
|
|
|
### Examples
|
|
|
|
#### Live Streaming
|
|
|
|
```json
|
|
{
|
|
"id": "57f28dbc264990e2c61e80a883862f7c114019804208b14da0bff81371e484d2",
|
|
"pubkey": "1597246ac22f7d1375041054f2a4986bd971d8d196d7997e48973263ac9879ec",
|
|
"created_at": 1687182672,
|
|
"kind": 30311,
|
|
"tags": [
|
|
["d", "demo-cf-stream"],
|
|
["title", "Adult Swim Metalocalypse"],
|
|
["summary", "Live stream from IPTV-ORG collection"],
|
|
["streaming", "https://adultswim-vodlive.cdn.turner.com/live/metalocalypse/stream.m3u8"],
|
|
["starts", "1687182672"],
|
|
["status", "live"],
|
|
["t", "animation"],
|
|
["t", "iptv"],
|
|
["image", "https://i.imgur.com/CaKq6Mt.png"]
|
|
],
|
|
"content": "",
|
|
"sig": "5bc7a60f5688effa5287244a24768cbe0dcd854436090abc3bef172f7f5db1410af4277508dbafc4f70a754a891c90ce3b966a7bc47e7c1eb71ff57640f3d389"
|
|
}
|
|
```
|
|
|
|
#### Live Streaming chat message
|
|
|
|
```json
|
|
{
|
|
"id": "97aa81798ee6c5637f7b21a411f89e10244e195aa91cb341bf49f718e36c8188",
|
|
"pubkey": "3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24",
|
|
"created_at": 1687286726,
|
|
"kind": 1311,
|
|
"tags": [
|
|
["a", "30311:1597246ac22f7d1375041054f2a4986bd971d8d196d7997e48973263ac9879ec:demo-cf-stream", "", "root"]
|
|
],
|
|
"content": "Zaps to live streams is beautiful.",
|
|
"sig": "997f62ddfc0827c121043074d50cfce7a528e978c575722748629a4137c45b75bdbc84170bedc723ef0a5a4c3daebf1fef2e93f5e2ddb98e5d685d022c30b622"
|
|
}
|
|
```
|
|
|
|
## Meeting Spaces
|
|
|
|
Meeting spaces contain one or more video/audio rooms where users can join and participate in the streaming.
|
|
|
|
### Meeting Space Event (kind:30312)
|
|
|
|
A special event with `kind:30312` "Space Host" defines the configuration and properties of a virtual interactive space. Each space has a unique identifier and can host multiple events/meetings.
|
|
|
|
```jsonc
|
|
{
|
|
"kind": 30312,
|
|
"tags": [
|
|
["d", "<unique identifier>"], // Required: Room identifier
|
|
["room", "<name of the room>"], // Required: Display name
|
|
["summary", "<description>"], // Optional: Room description
|
|
["image", "<preview image url>"], // Optional: Room image
|
|
["status", "<open, private, closed>"], // Required: Room accessibility
|
|
["service", "<url>"], // Required: URL to access the room
|
|
["endpoint", "<url>"], // Optional: API endpoint for status/info
|
|
["t", "<hashtag>"], // Optional: Multiple hashtags allowed
|
|
["p", "<pubkey>", "<url>", "<role>", "<proof>"], // Required: At least one provider
|
|
["relays", "<url>", "<url>", /*...*/] // Optional: Preferred relays
|
|
],
|
|
"content": "" // Usually empty, may contain additional metadata
|
|
}
|
|
```
|
|
|
|
Space properties:
|
|
* MUST be either open, private or closed. Closed means the room is not in operation.
|
|
* MAY specify access control policy for private rooms (e.g. invite-only, payment required)
|
|
* MAY persist when not in use
|
|
* MUST have at least one provider with "Host" role
|
|
* MAY have multiple providers with different roles
|
|
|
|
Provider roles (p tags):
|
|
* Host: Full room management capabilities
|
|
* Moderator: Room moderation capabilities
|
|
* Speaker: Allowed to present/speak
|
|
* Optional proof field for role verification
|
|
|
|
### Meeting Room Events (kind:30313)
|
|
|
|
A special event with kind:30313 represents a scheduled or ongoing meeting within a room. It MUST reference its parent room using the d tag.
|
|
|
|
```jsonc
|
|
{
|
|
"kind": 30313,
|
|
"tags": [
|
|
["d", "<event-unique-identifier>"], // Required: Event identifier
|
|
["a", "30312:<pubkey>:<room-id>", "wss://nostr.example.com"], // Required: Reference to parent space, 'd' from 30312
|
|
["title", "<meeting-title>"], // Required: Meeting title
|
|
["summary", "<description>"], // Optional: Meeting description
|
|
["image", "<preview image url>"], // Optional: Meeting image
|
|
["starts", "<unix timestamp>"], // Required: Start time
|
|
["ends", "<unix timestamp>"], // Optional: End time
|
|
["status", "<planned, live, ended>"], // Required: Meeting status
|
|
["total_participants", "<number>"], // Optional: Total registered
|
|
["current_participants", "<number>"], // Optional: Currently active
|
|
["p", "<pubkey>", "<url>", "<role>"], // Optional: Participant with role
|
|
],
|
|
"content": "" // Usually empty, may contain additional metadata
|
|
}
|
|
```
|
|
|
|
Event properties:
|
|
* MUST reference parent room via d tag
|
|
* MUST have a status (planned/live/ended)
|
|
* MUST have a start time
|
|
* MAY track participant counts
|
|
* MAY include participant roles specific to the event
|
|
|
|
Event management:
|
|
* Clients SHOULD update event status regularly when live
|
|
* Events without updates for 1 hour MAY be considered ended
|
|
* starts and ends timestamps SHOULD be updated when status changes
|
|
|
|
### Examples
|
|
|
|
#### Meeting Space (kind:30312)
|
|
|
|
```jsonc
|
|
{
|
|
"kind": 30312,
|
|
"tags": [
|
|
["d", "main-conference-room"],
|
|
["room", "Main Conference Hall"],
|
|
["summary", "Our primary conference space"],
|
|
["image", "https://example.com/room.jpg"],
|
|
["status", "open"],
|
|
["service", "https://meet.example.com/room"],
|
|
["endpoint", "https://api.example.com/room"],
|
|
["t", "conference"],
|
|
["p", "f7234bd4c1394dda46d09f35bd384dd30cc552ad5541990f98844fb06676e9ca", "wss://nostr.example.com/", "Owner"],
|
|
["p", "14aeb..8dad4", "wss://provider2.com/", "Moderator"],
|
|
["relays", "wss://relay1.com", "wss://relay2.com"]
|
|
],
|
|
"content": ""
|
|
}
|
|
```
|
|
|
|
#### Meeting room (kind:30313)
|
|
|
|
```jsonc
|
|
{
|
|
"kind": 30313,
|
|
"tags": [
|
|
["d", "annual-meeting-2025"],
|
|
["a", "30312:f7234bd4c1394dda46d09f35bd384dd30cc552ad5541990f98844fb06676e9ca:main-conference-room", "wss://nostr.example.com"]
|
|
["title", "Annual Company Meeting 2025"],
|
|
["summary", "Yearly company-wide meeting"],
|
|
["image", "https://example.com/meeting.jpg"],
|
|
["starts", "1676262123"],
|
|
["ends", "1676269323"],
|
|
["status", "live"],
|
|
["total_participants", "180"],
|
|
["current_participants", "175"],
|
|
["p", "91cf9..4e5ca", "wss://provider1.com/", "Speaker"],
|
|
],
|
|
"content": ""
|
|
}
|
|
```
|
|
### Room Presence
|
|
|
|
New `kind: 10312` provides an event which signals presence of a listener.
|
|
|
|
The presence event SHOULD be updated at regular intervals and clients SHOULD filter presence events older than
|
|
a given time window.
|
|
|
|
**This kind `10312` is a regular replaceable event, as such presence can only be indicated in one room at a time.**
|
|
|
|
```json
|
|
{
|
|
"kind": 10312,
|
|
"tags": [
|
|
["a" , "<room-a-tag>", "<relay-hint>", "root"],
|
|
["hand", "1"] // hand raised flag
|
|
]
|
|
}
|
|
```
|