nips icon indicating copy to clipboard operation
nips copied to clipboard

Add audio track NIP

Open staab opened this issue 1 year ago • 47 comments

Prior art:

  • 32123 published by wavlake do zap splits wrong and are not published by the artist. Metadata is also json-encoded in the content.
  • 31337 is published by zapstr.live and includes c tags which could be added here, although t probably would suffice. The media tag is missing lots of possible metadata. subject could be a good alternative to title.
  • 1808 isn't replaceable, but includes different urls for download/stream, hash, and waveform.
  • #923 re-defines metadata and doesn't support multiple urls for different uses.

This NIP relies on conventions established by NIPs 94 and 92 to support multiple urls and complete metadata simultaneously. It's extremely minimal, and can easily be extended to support:

  • Categories (NIP 32, t, or c tag)
  • Text tracks (via NIP 92 imeta)
  • Albums (kind 30029 lists)
  • Zap splits (as defined in NIP 52)
  • File metadata via NIP 94

staab avatar Feb 12 '24 22:02 staab

It would be helpful to state the main goal of this NIP. I am totally with you that it would be valuable to center around a standard way of sharing and describing media but without a clear purpose I'm afraid we'll just end up trading opinions about implementation details that might have vastly different objectives.

From my perspective, I would love to be able to publish events so that a user of any client could listen to the song(s) contained in the event and see any relevant metadata. I'm interested to hear if you have other use cases in mind.

A few questions and points of clarification:

  1. Can you please elaborate on wavlake do zap splits wrong?
  2. To the point that events "are not published by the artist", one of our major constraints here is most of our artists do not use Nostr. We would like to change this but it will take some time and will require artists opt-in and secure an nsec (as of now I'm not keen on storing keys for artists and signing on their behalf).
  3. What is the problem with metadata being stored as a json in the event itself?

blastshielddown avatar Feb 12 '24 23:02 blastshielddown

Sure, the goal of this nip is just to have a standard that everyone likes for publishing audio tracks. I think this probably requires that it be 1. replaceable, and 2. support multiple urls with different content types. So no current standard works yet. Of course there are slight differences between what exists so far:

  • Stemstr is doing remixes, and so has e tags to link things together.
  • Wavlake is re-posting as a feed, as a proxy for the artist, so pubkey != artist in this case
  • zapstr.live is more straightforward.

But the three use cases have the same core, and should be interoperable. I would use a separate event kind referring to these base events to implement more targeted use cases if the distinction is really needed (probably only necessary for stemstr).

  1. According to NIP 57 zap tags look like this: ["zap", "82341f882b6eabcd2ba7f1ef90aad961cf074af15b9ef44a09f9d2a8fbfbe6a2", "wss://nostr.oxtr.dev", "1"] but wavlake publishes ["zap", "[email protected]", "lud16"]. I get sort of why this probably happened, since not all artists have a pubkey, but in that case I'd just leave it off and make sure the profile's lud16 is the correct fallback.
  2. Totally get this. The new format should support that use case. If the artist joins, the events could be deleted and re-posted, or we could add some kind of "redirect" tag that points to the new canonical event.
  3. Nothing necessarily (this is how kind 0 works), but if we're starting from scratch a more idiomatic way to do nostr metadata is in tags. New specs should also try to make event content human-readable so social clients can read the events without special casing rendering for them.

I of course recognize that existing apps probably won't migrate, and some apps probably won't even want to use this spec. The proprietary kinds can be supported if clients want access to that content, but continued development should go off a spec that will actually support everything. We could maybe work off of zapstr's kind 31337, but media would have to be added for backward compatibility.

Edit: I managed to argue myself into hijacking zapstr.live's kind 31337 instead of creating a new kind. The media tag is deprecated, but required for compatibility.

staab avatar Feb 12 '24 23:02 staab

Love to see the discussion on this. Yeah, Wavlake zaps ought to be updated now that the lud16 zap tag is no longer within spec. Wavlake zaps were implemented almost a year ago when the NIP-57 spec had this:

Client calculates a recipient's lnurl pay request url from the zap tag on the event being zapped (see Appendix G), or by decoding their lud06 or lud16 field on their profile according to the lnurl specifications

When an event includes a zap tag, clients SHOULD calculate the lnurl pay request based on it's value instead of the profile's field.

[ "zap", "[email protected]", "lud16" ]

joshr4 avatar Feb 13 '24 02:02 joshr4

Wavlake zaps were implemented almost a year ago when the NIP-57 spec had this

Very interesting, I didn't remember that. Maybe we should even bring this back, it seems useful for zapping people that don't have nostr accounts, which is what wavlake uses it for I believe. It probably shouldn't have been removed. But that's all orthogonal to this discussion anyhow.

staab avatar Feb 13 '24 03:02 staab

Looks simple, I like it. But didn't read yet.

fiatjaf avatar Feb 13 '24 12:02 fiatjaf

@pablof7z it seems 31337 is used both in NIP 89 and for zapstr.live. Any preference for how to handle that collision? I think probably creating a new kind for this nip would probably be preferable.

staab avatar Feb 13 '24 17:02 staab

@pablof7z it seems 31337 is used both in NIP 89 and for zapstr.live. Any preference for how to handle that collision? I think probably creating a new kind for this nip would probably be preferable.

NIP 89 doesn't use it, it just mentions it as an example 😅

pablof7z avatar Feb 13 '24 17:02 pablof7z

NIP 89 doesn't use it, it just mentions it as an example 😅

Oh hey, I didn't read closely enough, that's perfect. Back to using 31337. The one area of incompatibility is the p tag, since zapstr uses an unusual version of it. I've added creator tag with a required p tag so plain text is still supported.

For everyone else's reference, here's an example 31337 from zapstr.live to compare against the new spec:

{
  "id": "4688579eb15107da01fb2fcd43b4e72c32fd0d7f75673b543c8c1e7d0a3fcb74",
  "pubkey": "38b405e49614835c083ae103398c510315c3a0366cfa27115995e79e92451058",
  "created_at": 1693135050,
  "kind": 31337,
  "tags": [
    ["d", "wrh81br2ifcfq11un6ah8"],
    ["p", "38b405e49614835c083ae103398c510315c3a0366cfa27115995e79e92451058", "author"],
    ["c", "Electronic"],
    ["media", "https://nostr.build/av/b057855ba5c38a598575e231a82175801d97a0a013d90c6b5761c05a40fecdf4.mp3", "http"],
    ["cover", "https://i.ytimg.com/vi/MCe2pAIMAzg/maxresdefault.jpg"],
    ["subject", "PilotRedSun - useful"],
    ["zap", ""]
  ],
  "content": "PilotRedSun - useful\n\nhttps://zapstr.live/t/naddr1qq2hwung8qckyu3jd9nxxen3xych2m3kv95rsqsqqvzqqqr6dyntly6j\n\nhttps://i.ytimg.com/vi/MCe2pAIMAzg/maxresdefault.jpg",
  "sig": "e040023e0435b787a64ef9bddff1dd6d22808279ac1e05a090406484aace2734e81f5832df4051f3e53134248f78781fc3b7b40993935146913fa1a63fd39499"
}

staab avatar Feb 13 '24 17:02 staab

Not sure what the best practice is for this kind of thing, but since this is intended to be a parameterized replaceable event: would it be helpful to add the a tag to the example so it's explicit what needs to be included? Or maybe there is a better way to reference this requirement without also having also update this doc if NIP-01 changes, that also could work.

From the NIP-01 spec: ["a", <kind integer>:<32-bytes lowercase hex of a pubkey>:<d tag value>, <recommended relay URL, optional>]

blastshielddown avatar Feb 15 '24 15:02 blastshielddown

would it be helpful to add the a tag to the example so it's explicit what needs to be included?

Just so people know what it looks like to a tag the event? I don't think that's necessary, since a tags are pretty well defined and widely used. I did add a reference to NIP 01 though so people know where to look up the term. Let me know if you had something else in mind.

staab avatar Feb 15 '24 16:02 staab

If you're up for it @staab we could publish some test events using this draft spec and see how it behaves in practice

blastshielddown avatar Feb 22 '24 23:02 blastshielddown

Go for it! I'm hoping to hit this in the next week or two. If you want to use Ainsley's music as a pilot I think that would be awesome.

staab avatar Feb 23 '24 00:02 staab

I've just published a test event of one of Ainsley's tracks according to this draft spec, event id: 1d8d62cf5f11d6cb6ce9944170753a0fdbf25ec26573ff68b2eecc761323f46d. It should be readable from our relay (relay.wavlake.com)

Let me know how it works @staab , and if you have any questions or feedback.

blastshielddown avatar Mar 14 '24 18:03 blastshielddown

I've just published a test event of one of Ainsley's tracks according to this draft spec, event id: 1d8d62cf5f11d6cb6ce9944170753a0fdbf25ec26573ff68b2eecc761323f46d. It should be readable from our relay (relay.wavlake.com)

Let me know how it works @staab , and if you have any questions or feedback.

https://njump.me/nevent1qqspmrtzea03r4ktdn5egstsw5aqlkljtmpx2ulldzewanrkzv3lgmgprpmhxue69uhhyetvv9ujumn0wdmksetjv5hxxmmdqgs8wk0myn8v2m79w4g82n9g7mfvvqvrmgjn0j8nsyy0mu5rkg9qukqnkg2aj

Few questions:

What's the a tag in this event? Looks like it's missing the backwards-compatible media tag Is it possible to have Ainsley Costello's pubkey tagged or you don't have that data mapped locally?

pablof7z avatar Mar 15 '24 08:03 pablof7z

Mostly repeating what @pablof7z said:

  • It looks like the a tag is pointing to the same event, which seems nonsensical to me.
  • I'd like to see at least creator (and maybe zap too) pointing to Ainsley if possible.
  • media and subject tags should be included for compatibility with zapstr.live
  • Instead of using artist it would probably be better to do ["creator", <ainsley-pubkey-if-possible-or-name>, "Artist"] following the spec: "creator is the pubkey or plain text name of the track creator. This tag MAY have a mark denoting the creator's role."

staab avatar Mar 15 '24 15:03 staab

Thanks @staab and @pablof7z Just pushed up a revised event.

Per your questions/comments:

  • The a tag follows the spec for parameterized replaceable events. From what I can tell it's accurate but maybe I'm misinterpreting the spec
  • I'm going to leave the zap tag as-is for now (this approach remains the best way for us to tally zaps for tracks) but will add Ainsley's pubkey to an additional creator tag. This should make it easy for a user to zap the artist directly if they want to. Please note: many of our artists do not have npubs so this should not be an expectation (yet)
  • Added media, and subject tags while removing artist, these were oversights

Additionally, I think it might be useful to add a version tag. I've been thinking this for a little while now as I've seen these NIPs evolve and introduce breaking changes. This would at least give clients some reliable expectation in case any event kind were to change in some subtle or dramatic way. I added one in this latest test event as an example.

blastshielddown avatar Mar 15 '24 16:03 blastshielddown

The a tag follows the spec for parameterized replaceable events. From what I can tell it's accurate but maybe I'm misinterpreting the spec

a tags are intended to point to a different event, not itself. So replies to this event would include the tag, but the event itself wouldn't.

I'm going to leave the zap tag as-is for now

I can't argue with this, but be aware that there probably aren't any clients that support the current format.

Additionally, I think it might be useful to add a version tag.

This is an interesting idea, but I'm inclined to think it's not a good solution. If we're going to support multiple formats, we should just create a new kind. Shifting specs are bad, and while I haven't paid much attention to it in the past I think we should be more careful about changing stuff in incompatible ways going forward.

staab avatar Mar 18 '24 22:03 staab

Went to go work on this, and a couple other things:

  • It looks like that example event is p-tagging its own author, which doesn't make much sense to me.
  • There's currently no way to query the creator field if there's no corresponding pubkey, which seems important. Maybe we could use NIP 32 labels? I just drafted https://github.com/nostr-protocol/nips/pull/1129 which relaxes the requirement for L tags.

staab avatar Mar 19 '24 13:03 staab

I couldn't find any docs nor any example events for the 30029 album lists. Can you point me to those?

For audio tracks that are released on albums or EPs I would prefer to have an optional album / track number tag. I propose:

"tags": [
    ["album", "Purple Rain", "01"],    // Album title and Track Number (may contain a leading zeros) 
]

This would make it possible to recreate full albums for a creator (Artist) from only the 31337 events. Otherwise multiple tracks from an album wouldn't have any way to identify which album they belong to.

flox1an avatar Mar 30 '24 22:03 flox1an

I would prefer to have an optional album / track number tag

Tracks could show up on multiple albums, with or without the explicit authorization of the event publisher. 30029 lists for a given track could be easily queried with #a, so I still think that's the better approach.

@blastshielddown any updates?

staab avatar Apr 01 '24 21:04 staab

There's currently no way to query the creator field if there's no corresponding pubkey

Just thinking through your proposal @staab in light of the limitation you outlined. I think I follow but have concerns the schema is getting confusing. For example, if we have two creators for a track and one has a pubkey and the other doesn't, those two creators will be treated totally differently in the event. One would be listed under the creator and p tags with their pubkey, the other would be listed under the arbitrary l tag without any namespace or context via a corresponding L tag. There are also two creator entries per artist if they have a pubkey. All this seems messy to me.

What I would propose is this:

  • use the p tag as intended to reference any creators with a pubkey. I think this should be the only reference to creator pubkeys in the event (if those pubkeys exist)
  • use the creator tag only for readable text values. Values like the name of the artist, songwriter, producer, etc. (plus the description) make sense here

Only problem now is linking the creator with the pubkey, which I'm open to ideas on. One thought: maybe we could use the petname option on the p tag to reference the creator by the readable value in the creator tag? In this way it serves as a self-contained reference to the pubkey. Then clients could easily associate readable names to the pubkey for users and from there it's an easy link to the creator's profile.

blastshielddown avatar Apr 02 '24 14:04 blastshielddown

I agree it's getting quite messy. The change you suggested still doesn't solve the problem of indexing plain-text creators, and I'm still not sure about overloading p. Maybe we should go whole-hog on NIP 32?

["L", "media/creator"],
["l", <pubkey>, "media/creator"],
["l", <plaintext>, "media/creator"],

The challenge this leaves is deduplicating creators referred to both by pubkey and by plaintext. But since pubkeys have profiles, maybe we could just say tracks should prefer pubkeys, and not include duplicates. Thoughts?

staab avatar Apr 02 '24 15:04 staab

Sorry I don't follow how you can't index plain-text values in the creator tag. Wouldn't this also be true for an l tag?

Using l tags like you described is better, I think. I'd like if there were some flexibility in the naming (to allow for things like singer, writer, producer, etc) but that might be better suited for the meta tag later anyway.

blastshielddown avatar Apr 02 '24 18:04 blastshielddown

Sorry I don't follow how you can't index plain-text values in the creator tag. Wouldn't this also be true for an l tag?

Only single-letter tags get indexed by most relay implementations.

I'd like if there were some flexibility in the naming (to allow for things like singer, writer, producer, etc)

We could totally do that, maybe nipxx/singer or something like that. It would be best to include those in the NIP when they become desired. For now I included artist and record_label in the NIP.

staab avatar Apr 02 '24 20:04 staab

Why not just start using music as the namespace for these l tags? music/artist and music/label seem like good starting points.

blastshielddown avatar Apr 02 '24 21:04 blastshielddown

That would be fine, I've just gone over to the position of "names are bad, use meaningless numbers", since we don't know how the NIP will evolve over time (for example, this might be used for podcasts, transcriptions, or any other kind of audio content).

Edit: in the NIP text I'm just using unqualified label namespaces.

staab avatar Apr 02 '24 22:04 staab

Latest sample event per this thread.

blastshielddown avatar Apr 02 '24 22:04 blastshielddown

@blastshielddown sorry, I just realized I'm falling into the NIP 32 trap of using labels for actual values. I've updated the NIP to overload the c tag similar to how l tags are overloaded, but as a simple key/value pair thing. This covers genre and subgenre, as well as any roles any number of people might fulfill. This is sort of a nuclear option, but the design space was feeling too constrained, and I think this supports everything we need, and is properly indexed.

staab avatar Apr 02 '24 22:04 staab

@staab just a thought - if you added a medium tag these events would work for podcast episodes too - ["medium", "music / podcast / audiobook"]

MerryOscar avatar Apr 05 '24 17:04 MerryOscar

@staab just a thought - if you added a medium tag these events would work for podcast episodes too - ["medium", "music / podcast / audiobook"]

We could, but we should probably just use a different kind if we want that. If you think this nip would work for podcasts I can add that.

staab avatar Apr 05 '24 17:04 staab