Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
203 changes: 203 additions & 0 deletions 76.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
NIP-76
======

Reels Feed — Short-form Video Discovery and Interaction
-------------------------------------------------------

`draft` `optional`

This NIP builds on top of [NIP-71](71.md) to define a standard for **short-form vertical video feeds** (commonly known as "Reels", "Shorts", or "Stories") including feed curation, loop-play behavior, duet/stitch interactions, and client rendering expectations.

NIP-71 defines the event kinds for short videos (`kind:22` and `kind:34236`). This NIP defines the **social layer** on top of those events: how clients discover, surface, rank, and let users interact with short-form content in an infinite-scroll feed experience.

---

## Feed Discovery

Clients wishing to render a Reels-style feed SHOULD subscribe to `kind:22` and `kind:34236` events with the following relay filter:

```json
{
"kinds": [22, 34236],
"limit": 50
}
```

To build a personalized feed, clients SHOULD use the user's follow list (NIP-02) to scope the subscription:

```json
{
"kinds": [22, 34236],
"authors": ["<followed pubkey>", "..."],
"limit": 50
}
```

Clients MAY additionally use hashtag filters via `#t` to build topic-specific feeds.

---

## Client Rendering Requirements

Clients implementing a Reels feed MUST:

- Display videos in a **vertical (portrait) layout** — the recommended aspect ratio is **9:16**
- **Autoplay muted** when the video enters the viewport
- **Loop** the video until the user scrolls away or explicitly stops it
- Provide a visible control to **unmute/mute** audio
- Render the event's `content` field as a caption overlay or below the video

Clients SHOULD:
- Preload the next video in the feed for smooth scrolling
- Display `t` tags as tappable hashtag links
- Show the author's avatar and display name (NIP-01 metadata) overlaid on or beside the video

---

## Duet / Stitch Interaction (Reply Videos)

A user may respond to a short video with their own short video — a "duet" or "stitch". This is expressed as a standard NIP-10 reply from a `kind:22` or `kind:34236` event pointing to the original video event.

### Duet Event

A **duet** plays both the original and the response video side-by-side simultaneously.

```json
{
"kind": 22,
"content": "My duet with this! #duet",
"tags": [
["e", "<original-event-id>", "<relay-url>", "reply"],
["p", "<original-author-pubkey>"],
["t", "duet"],
["title", "Duet with @originalauthor"],
["imeta",
"url https://example.com/my-duet-video.mp4",
"m video/mp4",
"dim 540x1920",
"image https://example.com/my-duet-thumb.jpg",
"duration 28.0"
]
]
}
```

### Stitch Event

A **stitch** plays a clip of the original first, then cuts to the response video sequentially.

```json
{
"kind": 22,
"content": "Replying to this point! #stitch",
"tags": [
["e", "<original-event-id>", "<relay-url>", "reply"],
["p", "<original-author-pubkey>"],
["t", "stitch"],
["stitch-start", "00:00:03.000"],
["stitch-end", "00:00:08.000"],
["title", "Stitch: responding to @originalauthor"],
["imeta",
"url https://example.com/my-stitch-response.mp4",
"m video/mp4",
"dim 1080x1920",
"image https://example.com/stitch-thumb.jpg",
"duration 45.0"
]
]
}
```

| Tag | Description |
|-----|-------------|
| `stitch-start` | Timestamp (`HH:MM:SS.sss`) in the **original** video where the clip begins |
| `stitch-end` | Timestamp (`HH:MM:SS.sss`) in the **original** video where the clip ends |

Clients rendering a stitch SHOULD fetch the original event via the `e` tag and play the clipped segment before playing the response video.

---

## Reels Curation List

A user may publish a curated list of short videos as a "Reels Collection" using `kind:30076` (a parameterized replaceable event).

```json
{
"kind": 30076,
"content": "My favourite cooking reels",
"tags": [
["d", "cooking-reels"],
["title", "Cooking Reels"],
["description", "Short cooking videos I love"],
["e", "<event-id-1>", "<relay-url>"],
["e", "<event-id-2>", "<relay-url>"],
["a", "34236:<pubkey>:<d-tag>", "<relay-url>"],
["t", "cooking"],
["t", "food"]
]
}
```

Clients MAY surface these lists as shareable channels or playlists in their feed UI.

---

## Interaction Events

All standard Nostr interaction NIPs apply to short video events:

| Interaction | NIP | Notes |
|-------------|-----|-------|
| Reactions (likes) | [NIP-25](25.md) | `+`, `-`, or emoji |
| Zaps | [NIP-57](57.md) | Lightning payments |
| Comments | [NIP-10](10.md) | Text replies via `kind:1` |
| Reposts | [NIP-18](18.md) | `kind:6` repost |
| Bookmarks | [NIP-51](51.md) | Save to private/public list |
| Video replies | This NIP | Duet / Stitch via `kind:22` |

---

## Relay Recommendations

Relays that wish to optimize for short-form video content SHOULD:

- Index `kind:22` and `kind:34236` events separately from `kind:1` text notes
- Support `NIP-50` full-text search over video `title` and `content` fields
- Expose a dedicated feed endpoint via `NIP-11` relay info, e.g.:

```json
{
"supported_nips": [76],
"reels_feed": true
}
```

---

## Summary of New Event Kinds and Tags

| Kind | Description |
|------|-------------|
| `22` | Short video (NIP-71, used here for duet/stitch) |
| `34236` | Addressable short video (NIP-71) |
| `30076` | Reels curation collection (this NIP) |

| Tag | Event | Description |
|-----|-------|-------------|
| `t duet` | `kind:22` reply | Marks a video reply as a side-by-side duet |
| `t stitch` | `kind:22` reply | Marks a video reply as a sequential stitch |
| `stitch-start` | `kind:22` reply | Start timestamp for the stitched clip |
| `stitch-end` | `kind:22` reply | End timestamp for the stitched clip |

---

## Relation to Other NIPs

- **NIP-71** — defines `kind:22` and `kind:34236` short video events; this NIP extends them
- **NIP-92** — `imeta` tag used for video metadata
- **NIP-94** — file metadata used within `imeta`
- **NIP-96** — decentralized file storage for video uploads
- **NIP-10** — reply threading for duet/stitch events
- **NIP-25** — reactions
- **NIP-57** — zaps
- **NIP-51** — bookmark/curation lists
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ NIPs listed here are not a protocol checklist. Nothing forces any software to im
- ~~[NIP-72: Moderated Communities](72.md) --- **unrecommended**: try [NIP-29](29.md) instead~~
- [NIP-73: External Content IDs](73.md)
- [NIP-75: Zap Goals](75.md)
- [NIP-76: Reels Feed — Short-form Video Discovery and Interaction](76.md)
- [NIP-77: Negentropy Syncing](77.md)
- [NIP-78: Application-specific data](78.md)
- [NIP-7D: Forum Threads](7D.md)
Expand Down