Skip to content

Add NIP-XX: Nostr Internet Radio#1975

Open
zeSchlausKwab wants to merge 10 commits into
nostr-protocol:masterfrom
zeSchlausKwab:nostr-internet-radio
Open

Add NIP-XX: Nostr Internet Radio#1975
zeSchlausKwab wants to merge 10 commits into
nostr-protocol:masterfrom
zeSchlausKwab:nostr-internet-radio

Conversation

@zeSchlausKwab
Copy link
Copy Markdown

What this adds

A standard for publishing internet radio stations on Nostr as kind:31237 events, enabling decentralized radio directories and cross-app compatibility. Current open solutions use awkward semi-community driven flows to maintain quality of their registries leading to broken streams and outdated metadata. The direct monetization could incentivize station runners and listeners to maintain station entries ensuring a cleaner registry.

Why we need this

Current radio directories are centralized platforms that control discovery and can deplatform stations. Users lose their favorites when services shut down, and there's no interoperability between radio apps.

How it works

  • Radio stations publish their streaming URLs and metadata directly to Nostr
  • Users maintain portable favorites across any compatible app
  • Developers can build interoperable radio clients using the standard
  • Social features use existing NIPs (comments, live chat) rather than reinventing them

Key benefits

  • Censorship-resistant station publishing
  • Portable user data (no vendor lock-in)
  • Direct listener-to-station micropayments
  • Community-driven quality maintenance
  • Works with existing Nostr social features

Implementation

Builds on proven Nostr patterns:

  • Uses NIP-78 for favorites (not redefined here)
  • References NIP-25/NIP-53 for social features
  • Integrates with NIP-89 for app discovery
  • Focuses only on radio-specific functionality

Working reference implementation: WaveFunc

Request for feedback

This introduces kind:31237 without conflicting with existing NIPs. Looking for community input on the event structure and integration approach.

Copy link
Copy Markdown
Member

@staab staab left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this looks good, and I like the idea. Most of my comments are oriented at brevity, it's not necessary to re-define stuff common to the entire protocol or advise on security/privacy stuff. I have a few suggestions related to data modeling, most important being indexable tags — on nostr only single-character tags are indexable, so if you want location or language to be indexed you need to use l or g (or something).

Comment thread XX.md Outdated
"tags": [
["d", "<station-identifier>"],
["name", "<station-name>"],
["t", "<genre>"],
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using c as defined in #1043

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, i'll definitely contemplate that.

Comment thread XX.md Outdated
["d", "<station-identifier>"],
["name", "<station-name>"],
["t", "<genre>"],
["language", "<ISO-639-1-code>"],
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be nice to search by language, l is already used elsewhere for language

Comment thread XX.md
["t", "<genre>"],
["language", "<ISO-639-1-code>"],
["countryCode", "<ISO-3166-2-code>"],
["location", "<human-readable-location>"],
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

g might be a useful addition for locating stations by geohash

Comment thread XX.md Outdated
["location", "<human-readable-location>"],
["thumbnail", "<image-url>"],
["website", "<station-website>"],
["client", "<client-name>", "<handler-address>", "<relay-hint>"]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be left out of the nip, since this tag is defined elsewhere and can be applied as needed by the implementation.

Comment thread XX.md

### Content Format

The `content` field MUST contain a JSON string with the following structure:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Data modeling is conventionally done with tags; content should generally be human readable (kind 0 notwithstanding). Moving streams to tags might be done using something like imeta, for example:

"tags": [
  ["stream", "url https://stream.example.com/radio.mp3", "format audio/mpeg", "bitrate 12800", "codec mp3", "sampleRate 44100"]
]

Idiosyncratic, I know. But it requires less json-in-json, and you can include multiple stream tags.

Comment thread XX.md Outdated
Comment on lines +9 to +31
## Rationale

Traditional internet radio directories are centralized services controlled by single entities, making them vulnerable to censorship, takedowns, and service discontinuation. Radio stations and listeners lack data portability between different platforms and applications.

This specification leverages Nostr's decentralized infrastructure to create an open, censorship-resistant radio ecosystem where:

- Radio stations can publish their metadata and streaming information directly
- Users maintain portable favorites lists across applications
- Developers can build interoperable radio clients without vendor lock-in
- Communities can engage around stations through comments and live chat
- Discovery happens through the network rather than centralized algorithms
- Organic, decentralized maintenance of station entries helps keep quality high and mitigate broken links
- Direct listener-to-station monetization becomes possible through Nostr's native micropayment capabilities

## Overview

This specification defines radio station events and describes how existing Nostr protocols can be used to create a complete radio ecosystem:

- **Radio Station Events** (`kind:31237`) - Station metadata and streaming information (defined in this NIP)
- **Live Chat Messages** - Real-time chat during streaming using existing live chat protocols
- **Station Comments** - Persistent discussion threads using existing comment protocols
- **Favorites Management** - Personal and curated station collections using [NIP-78](78.md)
- **Application Discovery** - Handler registration using [NIP-89](89.md)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should all be removed, NIPs are better when they're terse

Comment thread XX.md Outdated

- The `d` tag value SHOULD be descriptive and stable for the station
- Multiple stations can be published by the same pubkey using different `d` tags
- Clients SHOULD use the station name as a fallback identifier
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fallback for an event with no d tag is an empty string

Comment thread XX.md
Comment on lines +162 to +166
### Streaming Compatibility

- Support multiple stream formats for broader client compatibility
- Include quality metadata to enable adaptive streaming
- Mark one stream as `primary` for default selection
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is too vague, it's better to just define expected metadata tags as they become necessary. primary is fine, but I would just assume the first stream is the default

Comment thread XX.md Outdated
Comment on lines +174 to +189
### Privacy Considerations

- The `client` tag has privacy implications - clients SHOULD allow opt-out
- Station owners can moderate chat/comments by maintaining block lists
- Consider rate limiting for chat messages to prevent spam

## Security Considerations

- Validate stream URLs before playback to prevent malicious redirects
- Sanitize station descriptions when rendering markdown content
- Implement reasonable limits on metadata size to prevent DoS attacks
- Verify signatures on all events before processing

## Backwards Compatibility

This specification introduces new event kinds that do not conflict with existing NIPs. Clients that don't understand `kind:31237` can safely ignore these events without affecting other functionality.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is all out of scope or defined elsewhere in the protocol

Comment thread XX.md Outdated
Comment on lines +195 to +197
## Conclusion

This specification enables a decentralized internet radio ecosystem built on Nostr's foundation of censorship resistance and data portability. By standardizing station metadata, social features, and application discovery, it creates interoperability between radio clients while preserving user autonomy and freedom of choice.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is redundant

…usion from XX.md to streamline content and focus on essential specifications.
…ty; change example value to a random identifier and clarify default behavior.
…ocument and focus on the core specifications of the radio station events.
… stream object specifications and discovery requirements.
Change tag name from 't' to 'c' for station categories and add facet parameter.
Update example to demonstrate new tag format and correct website URL.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants