├── .gitignore ├── docs ├── chatprotocols.txt ├── examples │ ├── license │ │ ├── licenseslugs.txt │ │ ├── licenses.json │ │ └── license.md │ ├── value │ │ ├── valueslugs.txt │ │ └── lnaddress.md │ ├── transcripts │ │ ├── example.json │ │ ├── example.vtt │ │ └── transcripts.md │ ├── chapters │ │ ├── example.json │ │ ├── exampleComplex.json │ │ └── jsonChapters.md │ └── publishers │ │ └── publishers.md ├── schema │ ├── tag-hover.png │ ├── tag-inserted.png │ ├── attribute-hover.png │ ├── first-child-tag.png │ ├── start-tag-completion.png │ ├── podcast-wrapper.xsd │ ├── strip-annotation.xslt │ ├── podcast-example.xml │ └── podcast-schema.md ├── tags │ ├── podping.md │ ├── funding.md │ ├── locked.md │ ├── season.md │ ├── integrity.md │ ├── source.md │ ├── soundbite.md │ ├── value.md │ ├── episode.md │ ├── chapters.md │ ├── license.md │ ├── images-(deprecated).md │ ├── content-link.md │ ├── transcript.md │ ├── publisher.md │ ├── block.md │ ├── podroll.md │ ├── txt.md │ ├── trailer.md │ ├── value-recipient.md │ ├── remote-item.md │ ├── chat.md │ ├── social-interact.md │ ├── location.md │ ├── update-frequency.md │ ├── guid.md │ ├── alternate-enclosure.md │ ├── person.md │ ├── value-time-split.md │ ├── medium.md │ ├── live-item.md │ └── image.md ├── 1.0.md └── other-recommendations.md ├── .vs ├── ProjectSettings.json ├── slnx.sqlite ├── podcast-namespace │ └── v16 │ │ └── .suo └── VSWorkspaceState.json ├── proposal-docs ├── chat │ ├── chatprotocols.txt │ └── chat.md ├── hive-account-name │ └── hive-account-name.md ├── social │ ├── platforms.md │ └── social.md ├── podping │ └── podping.md ├── license │ └── license.md ├── bonusItem │ └── bonusItem.md ├── opensubscribe │ └── opensubscribe.md ├── value-webmonetization │ └── value-webmonetization.md ├── updateFrequency │ └── updateFrequency.md └── API │ └── Chapters.md ├── apgtrss1.png ├── apgtrss2.png ├── socialprotocols.txt ├── contributors.txt ├── serviceslugs.txt ├── existing-namespaces.txt ├── letters └── letter-to-apple.md ├── COPYING.txt ├── podcasting2.0.md └── categories.json /.gitignore: -------------------------------------------------------------------------------- 1 | /.vs/ 2 | .vscode/settings.json 3 | -------------------------------------------------------------------------------- /docs/chatprotocols.txt: -------------------------------------------------------------------------------- 1 | irc 2 | xmpp 3 | nostr 4 | matrix -------------------------------------------------------------------------------- /.vs/ProjectSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "CurrentProjectSetting": null 3 | } -------------------------------------------------------------------------------- /proposal-docs/chat/chatprotocols.txt: -------------------------------------------------------------------------------- 1 | irc 2 | xmpp 3 | nostr 4 | matrix -------------------------------------------------------------------------------- /apgtrss1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Podcastindex-org/podcast-namespace/HEAD/apgtrss1.png -------------------------------------------------------------------------------- /apgtrss2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Podcastindex-org/podcast-namespace/HEAD/apgtrss2.png -------------------------------------------------------------------------------- /.vs/slnx.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Podcastindex-org/podcast-namespace/HEAD/.vs/slnx.sqlite -------------------------------------------------------------------------------- /docs/examples/license/licenseslugs.txt: -------------------------------------------------------------------------------- 1 | ARR 2 | CC-BY-4.0 3 | CC-BY-NC-4.0 4 | CC-BY-NC-ND-4.0 5 | POD-V4V-1.0 -------------------------------------------------------------------------------- /docs/examples/value/valueslugs.txt: -------------------------------------------------------------------------------- 1 | bitcoin 2 | lightning 3 | keysend 4 | lnaddress 5 | amp 6 | wallet 7 | node -------------------------------------------------------------------------------- /socialprotocols.txt: -------------------------------------------------------------------------------- 1 | disabled 2 | activitypub 3 | twitter 4 | lightning 5 | atproto 6 | hive 7 | matrix 8 | nostr 9 | -------------------------------------------------------------------------------- /docs/schema/tag-hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Podcastindex-org/podcast-namespace/HEAD/docs/schema/tag-hover.png -------------------------------------------------------------------------------- /docs/schema/tag-inserted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Podcastindex-org/podcast-namespace/HEAD/docs/schema/tag-inserted.png -------------------------------------------------------------------------------- /.vs/podcast-namespace/v16/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Podcastindex-org/podcast-namespace/HEAD/.vs/podcast-namespace/v16/.suo -------------------------------------------------------------------------------- /docs/schema/attribute-hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Podcastindex-org/podcast-namespace/HEAD/docs/schema/attribute-hover.png -------------------------------------------------------------------------------- /docs/schema/first-child-tag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Podcastindex-org/podcast-namespace/HEAD/docs/schema/first-child-tag.png -------------------------------------------------------------------------------- /docs/schema/start-tag-completion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Podcastindex-org/podcast-namespace/HEAD/docs/schema/start-tag-completion.png -------------------------------------------------------------------------------- /.vs/VSWorkspaceState.json: -------------------------------------------------------------------------------- 1 | { 2 | "ExpandedNodes": [ 3 | "", 4 | "\\proposal-docs" 5 | ], 6 | "SelectedNode": "\\proposal-docs\\recommendations", 7 | "PreviewInSolutionExplorer": false 8 | } -------------------------------------------------------------------------------- /proposal-docs/hive-account-name/hive-account-name.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # WITHDRAWN - The "podcast:hiveAccount" Specification 4 | 5 | Version 1.0 by Brian of London - 2021.06.08 6 | 7 | Withdrawn - It's handled better by `customKey` and `customValue` in the [`value block`](value/value.md) -------------------------------------------------------------------------------- /docs/schema/podcast-wrapper.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /docs/schema/strip-annotation.xslt: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/tags/podping.md: -------------------------------------------------------------------------------- 1 | # Podping 2 | 3 | `` 4 | 5 | This element allows feed owners to signal to aggregators that the feed sends out [`Podping`](https://github.com/Podcastindex-org/podping) notifications when changes are made to it, reducing the need for frequent speculative feed polling. 6 | 7 | ### Parent 8 | 9 | `` 10 | 11 | ### Count 12 | 13 | Single 14 | 15 | ## Examples 16 | 17 | ```xml 18 | 19 | ``` 20 | -------------------------------------------------------------------------------- /contributors.txt: -------------------------------------------------------------------------------- 1 | Tom Rossi 2 | James Cridland 3 | Guilherme Dellagustin 4 | Kevin Finn 5 | Dave Jones 6 | Daniel J. Lewis 7 | Andreas Hubel 8 | Christopher Isene 9 | Todd Cochrane 10 | Adam Curry 11 | @PhoneBoy 12 | Ben Slinger 13 | Martin Mouritzen 14 | Andy Beard 15 | Andy Valencia 16 | Matt Basta 17 | Mitch Downey 18 | @Muppet1856 19 | Douglas Kastle 20 | Andy Lehman 21 | Daniel Siebiesiuk 22 | Jon Buda 23 | Justin Jackson 24 | Tyler Lacy 25 | @brianoflondon 26 | Angelo at Blubrry 27 | Stacey Goers 28 | Stuart Moore 29 | @PofMagicfingers 30 | @Bigaston 31 | Alecks Gates 32 | Dave Keeshan 33 | Steven Bell 34 | @dergigi 35 | CTHTC 36 | @kenCode 37 | @Agorise 38 | @Dwev 39 | ... add your name as you contribute! 40 | -------------------------------------------------------------------------------- /docs/examples/transcripts/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "segments": [ 4 | { 5 | "speaker": "Darth Vader", 6 | "startTime": 0.5, 7 | "endTime": 0.75, 8 | "body": "I" 9 | }, 10 | { 11 | "speaker": "Darth Vader", 12 | "startTime": 1, 13 | "endTime": 1.25, 14 | "body": "am" 15 | }, 16 | { 17 | "speaker": "Darth Vader", 18 | "startTime": 1.5, 19 | "endTime": 2.0, 20 | "body": "your" 21 | }, 22 | { 23 | "speaker": "Darth Vader", 24 | "startTime": 2.25, 25 | "endTime": 2.50, 26 | "body": "father." 27 | }, 28 | { 29 | "speaker": "Luke", 30 | "startTime": 2.75, 31 | "endTime": 3.0, 32 | "body": "Nooooo" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /serviceslugs.txt: -------------------------------------------------------------------------------- 1 | acast 2 | amazon 3 | anchor 4 | apple 5 | audible 6 | audioboom 7 | backtracks 8 | bitcoin 9 | blubrry 10 | buzzsprout 11 | captivate 12 | castos 13 | castopod 14 | facebook 15 | fireside 16 | fyyd 17 | google 18 | gpodder 19 | hypercatcher 20 | kasts 21 | libsyn 22 | mastodon 23 | megafono 24 | megaphone 25 | omnystudio 26 | overcast 27 | paypal 28 | pinecast 29 | podbean 30 | podcastaddict 31 | podcastguru 32 | podcastindex 33 | podcasts 34 | podchaser 35 | podcloud 36 | podfriend 37 | podiant 38 | podigee 39 | podnews 40 | podomatic 41 | podserve 42 | podverse 43 | redcircle 44 | relay 45 | resonaterecordings 46 | rss 47 | shoutengine 48 | simplecast 49 | slack 50 | soundcloud 51 | spotify 52 | spreaker 53 | tiktok 54 | transistor 55 | twitter 56 | whooshkaa 57 | youtube 58 | zencast 59 | -------------------------------------------------------------------------------- /docs/examples/transcripts/example.vtt: -------------------------------------------------------------------------------- 1 | WEBVTT 2 | 3 | 00:00:00.000 --> 00:00:02.760 4 | In today's episode, you'll learn whether or not you 5 | 6 | 00:00:02.760 --> 00:00:06.090 7 | should have a podcast trailer. And if so, what should you 8 | 9 | 00:00:06.090 --> 00:00:11.610 10 | include in one? Welcome to Podcasting Q&A, where you learn 11 | 12 | 00:00:11.610 --> 00:00:15.750 13 | the best tips and strategies to launch, grow and monetize your 14 | 15 | 00:00:15.750 --> 00:00:18.630 16 | podcast. This week's question comes from Gillian. 17 | 18 | 00:00:19.080 --> 00:00:21.450 19 | Hi Buzzsprout, Gillian here from breaking through 20 | 21 | 00:00:21.450 --> 00:00:25.350 22 | careers podcast. My question is, do we need a podcast trailer? 23 | -------------------------------------------------------------------------------- /docs/tags/funding.md: -------------------------------------------------------------------------------- 1 | # Funding 2 | 3 | `` 4 | 5 | This tag lists possible donation/funding links for the podcast. The content of the tag is the recommended string to be used with the link. 6 | 7 | ### Parent 8 | 9 | ``, `` or [``](live-item.md) 10 | 11 | ### Count 12 | 13 | Multiple 14 | 15 | ### Node value 16 | 17 | This is a free form string supplied by the creator which they expect to be displayed in the app next to the link. Please do not exceed `128 characters` for the node value or it may be truncated by aggregators. 18 | 19 | ### Attributes 20 | 21 | - **url (required):** The URL to be followed to fund the podcast. 22 | 23 | ### Examples 24 | 25 | ```xml 26 | Support the show! 27 | ``` 28 | 29 | ```xml 30 | Become a member! 31 | ``` 32 | -------------------------------------------------------------------------------- /docs/tags/locked.md: -------------------------------------------------------------------------------- 1 | # Locked 2 | 3 | `` 4 | 5 | This tag may be set to `yes` or `no`. The purpose is to tell other podcast hosting platforms whether they are allowed to import this feed. A value of `yes` means that any attempt to import this feed into a new platform should be rejected. 6 | 7 | ### Parent 8 | 9 | `` 10 | 11 | ### Count 12 | 13 | Single 14 | 15 | ### Node value 16 | 17 | The node value must be "yes" or "no". 18 | 19 | ### Attributes 20 | 21 | - **owner (optional):** The owner attribute is an email address that can be used to verify ownership of this feed during move and import operations. This could be a public email or a virtual email address at the hosting provider that redirects to the owner's true email address. 22 | 23 | ### Examples 24 | 25 | ```xml 26 | yes 27 | ``` 28 | 29 | ```xml 30 | no 31 | ``` 32 | -------------------------------------------------------------------------------- /docs/tags/season.md: -------------------------------------------------------------------------------- 1 | # Season 2 | 3 | `` 4 | 5 | This element allows for identifying which episodes in a podcast are part of a particular "season", with an optional season name attached. 6 | 7 | ### Parent 8 | 9 | `` 10 | 11 | ### Count 12 | 13 | Single 14 | 15 | ### Node Value 16 | 17 | The node value is an integer, and represents the season "number". It is required. 18 | 19 | ### Attributes 20 | 21 | - **name:** (optional) - This is the "name" of the season. If this attribute is present, applications are free to **not** show the season number to the end user, and may use it simply for chronological sorting and grouping purposes. 22 | 23 | Please do not exceed `128 characters` for the name attribute. 24 | 25 | ### Examples 26 | 27 | ```xml 28 | 5 29 | ``` 30 | 31 | ```xml 32 | 3 33 | ``` 34 | 35 | ```xml 36 | 1 37 | ``` 38 | 39 | ```xml 40 | 3 41 | ``` 42 | -------------------------------------------------------------------------------- /docs/examples/chapters/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.2.0", 3 | "chapters": 4 | [ 5 | { 6 | "startTime": 0, 7 | "title": "Intro" 8 | }, 9 | { 10 | "startTime": 168, 11 | "title": "Hearing Aids", 12 | "img": "https://example.com/images/hearing_aids.jpg" 13 | }, 14 | { 15 | "startTime": 260, 16 | "title": "Progress Report" 17 | }, 18 | { 19 | "startTime": 410, 20 | "title": "Namespace", 21 | "img": "https://example.com/images/namepsace_example.jpg", 22 | "url": "https://github.com/Podcastindex-org/podcast-namespace" 23 | }, 24 | { 25 | "startTime": 3990, 26 | "title": "Just Break Up", 27 | "img": "https://example.com/images/justbreakuppod.png" 28 | }, 29 | { 30 | "startTime": 4600, 31 | "title": "Donations", 32 | "url": "https://example.com/paypal_link" 33 | }, 34 | { 35 | "startTime": 5510, 36 | "title": "The Big Players" 37 | }, 38 | { 39 | "startTime": 5854, 40 | "title": "Spread the Word" 41 | }, 42 | { 43 | "startTime": 6089, 44 | "title": "Outro" 45 | } 46 | ] 47 | } -------------------------------------------------------------------------------- /docs/tags/integrity.md: -------------------------------------------------------------------------------- 1 | # Integrity 2 | 3 | `` 4 | 5 | This element defines a method of verifying integrity of the media given either an [SRI-compliant integrity string](https://www.w3.org/TR/SRI/) (preferred) or a base64 encoded PGP signature. This element is optional within a [``](alternate-enclosure.md) element. It allows to ensure that the file has not been tampered with. 6 | 7 | ### Parent 8 | 9 | [``](alternate-enclosure.md) 10 | 11 | ### Count 12 | 13 | Single 14 | 15 | ### Attributes 16 | 17 | - **type:** (required) Type of integrity, either "sri" or "pgp-signature". 18 | - **value:** (required) Value of the sri string or base64 encoded pgp signature. 19 | 20 | ### Examples 21 | 22 | ```xml 23 | 24 | 25 | 26 | 27 | 28 | ``` 29 | -------------------------------------------------------------------------------- /docs/tags/source.md: -------------------------------------------------------------------------------- 1 | # Source 2 | 3 | `` 4 | 5 | This element defines a uri location for a [``](alternate-enclosure.md) media file. It is meant to be used as a child of the [``](alternate-enclosure.md) element. At least one `` element must be present within every [``](alternate-enclosure.md) element. 6 | 7 | ### Parent 8 | 9 | [``](alternate-enclosure.md) 10 | 11 | ### Count 12 | 13 | Multiple 14 | 15 | ### Attributes 16 | 17 | - **uri:** (required) This is the uri where the media file resides. 18 | - **contentType:** (optional) This is a string that declares the mime-type of the file. It is useful if the transport mechanism is different than the file being delivered, as is the case with a torrents. 19 | 20 | ### Examples 21 | 22 | ```xml 23 | 24 | 25 | 26 | 27 | 28 | 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/tags/soundbite.md: -------------------------------------------------------------------------------- 1 | # Soundbite 2 | 3 | `` 4 | 5 | Points to one or more soundbites within a podcast episode. The intended use includes episodes previews, discoverability, audiogram generation, episode highlights, etc. It should be assumed that the audio/video source of the soundbite is the audio/video given in the item's [``](https://cyber.harvard.edu/rss/rss.html#ltenclosuregtSubelementOfLtitemgt) element. 6 | 7 | ### Parent 8 | 9 | `` 10 | 11 | ### Count 12 | 13 | Multiple 14 | 15 | ### Node value 16 | 17 | This is a free form string from the podcast creator to specify a title for the soundbite. If the podcaster does not provide a value for the soundbite title, then leave the value blank, and podcast apps can decide to use the episode title or some other placeholder value in its place. Please do not exceed `128 characters` for the node value or it may be truncated by aggregators. 18 | 19 | ### Attributes 20 | 21 | - **startTime (required):** The time where the soundbite begins 22 | - **duration (required):** How long is the soundbite (recommended between 15 and 120 seconds) 23 | 24 | ### Examples 25 | 26 | ```xml 27 | 28 | ``` 29 | 30 | ```xml 31 | Why the Podcast Namespace Matters 32 | ``` 33 | -------------------------------------------------------------------------------- /docs/tags/value.md: -------------------------------------------------------------------------------- 1 | # Value 2 | 3 | `` 4 | 5 | This element designates the cryptocurrency or payment layer that will be used, the transport method for transacting the payments, and a suggested amount denominated in the given cryptocurrency. 6 | 7 | This element can exist at either the `` or `` level. When it exists at the `` level, it should be treated as an "override" of whatever is defined at the `` level. 8 | 9 | This is a complex tag, so implementors are HIGHLY encouraged to read the companion [document](../examples/value/value.md) for a complete understanding of how this tag works and what it is capable of. 10 | 11 | ### Parent 12 | 13 | `` or `` 14 | 15 | ### Count 16 | 17 | Multiple 18 | 19 | ### Node Value 20 | 21 | The node value must be one or more [``](value-recipient.md) elements. 22 | 23 | ### Attributes 24 | 25 | - **type:** (required) This is the service slug of the cryptocurrency or protocol layer. 26 | - **method:** (required) This is the transport mechanism that will be used. 27 | - **suggested:** (optional) This is an optional suggestion on how much cryptocurrency to send with each payment. 28 | 29 | ### Examples 30 | 31 | ```xml 32 | 37 | ``` 38 | -------------------------------------------------------------------------------- /docs/tags/episode.md: -------------------------------------------------------------------------------- 1 | # Episode 2 | 3 | `` 4 | 5 | This element exists largely for compatibility with the [``](season.md) tag. But, it also allows for a similar idea to what "name" functions as in that element. 6 | 7 | ### Parent 8 | 9 | `` 10 | 11 | ### Count 12 | 13 | Single 14 | 15 | ### Node Value 16 | 17 | The node value is a decimal number. It is required. 18 | 19 | ### Attributes 20 | 21 | - **display:** (optional) - If this attribute is present, podcast apps and aggregators are encouraged to show its value instead of the purely numerical node value. This attribute is a string. 22 | 23 | The episode numbers are decimal, so numbering such as `100.5` is acceptable if there was a special mini-episode published between two other episodes. In that scenario, the number would help with proper chronological sorting, while the `display` attribute could specify an alternate special "number" (a moniker) to display for the episode in a podcast player app UI. 24 | 25 | Please do not exceed `32 characters` for the display attribute. 26 | 27 | ### Examples 28 | 29 | ```xml 30 | 3 31 | ``` 32 | 33 | ```xml 34 | 315.5 35 | ``` 36 | 37 | ```xml 38 | 204 39 | ``` 40 | 41 | ```xml 42 | 9 43 | ``` 44 | -------------------------------------------------------------------------------- /docs/tags/chapters.md: -------------------------------------------------------------------------------- 1 | # Chapters 2 | 3 | `` 4 | 5 | Links to an external file (see example file) containing chapter data for the episode. See the [jsonChapters.md](../examples/chapters/jsonChapters.md) file for a description of the file syntax for chapters syntax. And, see the [example.json](../examples/chapters/example.json) example file for a real world example. 6 | 7 | Benefits with this approach are that chapters do not require altering audio files, and the chapters can be edited after publishing, since they are a separate file that can be requested on playback (or cached with download). JSON chapter information also allows chapters to be displayed by a wider range of playback tools, including web browsers (which typically have no access to ID3 tags), thus greatly simplifying chapter support; and images can be retrieved on playback, rather than bloating the filesize of the audio. The data held is compatible with normal ID3 tags, thus requiring no additional work for the publisher. 8 | 9 | ### Parent 10 | 11 | `` 12 | 13 | ### Count 14 | 15 | Single 16 | 17 | ### Attributes 18 | 19 | - **url (required):** The URL where the chapters file is located. 20 | - **type (required):** Mime type of file - JSON prefered, 'application/json+chapters'. 21 | 22 | ### Examples 23 | 24 | ```xml 25 | 26 | ``` 27 | -------------------------------------------------------------------------------- /docs/tags/license.md: -------------------------------------------------------------------------------- 1 | # License 2 | 3 | `` 4 | 5 | This element defines a license that is applied to the audio/video content of a single episode, or the audio/video of the podcast as a whole. Custom licenses must always include a url attribute. Implementors are encouraged to read the license tag companion [document](../examples/license/license.md) for a more complete picture of what this tag is intended to accomplish. 6 | 7 | ### Parent 8 | 9 | `` or `` 10 | 11 | ### Count 12 | 13 | Single 14 | 15 | ### Node Value 16 | 17 | The node value must be a lower-cased reference to a license "identifier" defined in the companion [license list](../examples/license/licenses.json) file if the license being used is a well-known, public license. Or, if it is a custom license, it must be a free form abbreviation of the name of the license as you reference it publicly. Please do not exceed `128 characters` for the node value or it may be truncated by aggregators. 18 | 19 | ### Attributes 20 | 21 | - **url:** (optional) This is a url that points to the full, legal language of the license being referenced. This attribute is optional for well-known public licenses. For new, or custom licenses it is required. 22 | 23 | ### Examples 24 | 25 | ```xml 26 | CC-BY-NC-ND-4.0 27 | ``` 28 | 29 | ```xml 30 | my-podcast-license-v1 31 | ``` 32 | -------------------------------------------------------------------------------- /docs/tags/images-(deprecated).md: -------------------------------------------------------------------------------- 1 | # Images (Deprecated) 2 | 3 | `` 4 | 5 | *Important: This tag is now deprecated. The new [podcast:image](image.md) tag should be used instead* 6 | 7 | This tag, when present, allows for specifying many different image sizes in a compact way at either the episode or channel level. The syntax is borrowed from the HTML5 [srcset](https://html.spec.whatwg.org/multipage/images.html#srcset-attributes) syntax. It allows for describing multiple image sources with width and pixel hints directly in the attribute. Although the HTML5 `srcset` attribute allows relative urls, absolute urls are required in this tag - since the feed url may not represent an appropriate base url for relativization. 8 | 9 | ### Parent 10 | 11 | `` or `` 12 | 13 | ### Count 14 | 15 | Single 16 | 17 | ### Attributes 18 | 19 | - **srcset** (required) A string that denotes each image url followed by a space and the pixel width, with each one separated by a comma. See the example for a clear view of the syntax. 20 | 21 | ### Examples 22 | 23 | Example of specifying four different image sizes: 24 | 25 | ```xml 26 | 32 | ``` 33 | -------------------------------------------------------------------------------- /docs/tags/content-link.md: -------------------------------------------------------------------------------- 1 | # Content Link 2 | 3 | `` 4 | 5 | The `contentLink` tag is used to indicate that the content being delivered by the parent element can be found at an external location instead of, or in addition to, the tag itself within an app. In most instances it is used as a fallback link for the user to use when the app itself can't handle a certain content delivery directly. 6 | 7 | For instance, perhaps a podcast feed specifies a [``](live-item.md) to deliver a live stream to apps. The feed may also give a `` pointing to YouTube and Twitch versions of the live stream as well, just in case the listener uses an app that doesn't fully support live streaming content. 8 | 9 | ### Parent 10 | 11 | `` or [``](live-item.md) 12 | 13 | ### Count 14 | 15 | Multiple 16 | 17 | ### Node Value 18 | 19 | The node value is a free-form string meant to explain to the user where this content link points and/or the nature of its purpose. 20 | 21 | ### Attributes 22 | 23 | - **href** (required) A string that is the uri pointing to content outside of the application. 24 | 25 | ### Examples 26 | 27 | (under ``) 28 | 29 | ```xml 30 | Watch this episode on YouTube! 31 | ``` 32 | 33 | (under [``](live-item.md)) 34 | 35 | ```xml 36 | Live on YouTube! 37 | ``` 38 | 39 | ```xml 40 | Chat on Twitter! 41 | ``` 42 | -------------------------------------------------------------------------------- /docs/tags/transcript.md: -------------------------------------------------------------------------------- 1 | # Transcript 2 | 3 | `` 4 | 5 | This tag is used to link to a transcript or closed captions file. Multiple tags can be present for multiple transcript formats. 6 | 7 | Detailed file format information and example files are [here](../examples/transcripts/transcripts.md). 8 | 9 | ### Parent 10 | 11 | `` 12 | 13 | ### Count 14 | 15 | Multiple 16 | 17 | ### Attributes 18 | 19 | - **url (required):** URL of the podcast transcript. 20 | - **type (required):** Mime type of the file such as `text/plain`, `text/html`, `text/vtt`, `application/json`, `application/x-subrip` 21 | - **language (optional):** The language of the linked transcript. If there is no language attribute given, the linked file is assumed to be the same language that is specified by the RSS `` element. 22 | - **rel (optional):** If the rel="captions" attribute is present, the linked file is considered to be a closed captions file, regardless of what the mime type is. In that scenario, time codes are assumed to be present in the file in some capacity. 23 | 24 | ### Examples 25 | 26 | ```xml 27 | 28 | ``` 29 | 30 | ```xml 31 | 32 | ``` 33 | 34 | ```xml 35 | 41 | ``` 42 | 43 | ```xml 44 | 45 | ``` 46 | -------------------------------------------------------------------------------- /docs/tags/publisher.md: -------------------------------------------------------------------------------- 1 | # Publisher 2 | 3 | `` 4 | 5 | This element allows a podcast feed to link to it's "publisher feed" parent. This is useful when a parent publishing entity wants to attest ownership over all of the podcast feeds it owns/publishes. This element must contain exactly one `` element pointing to the publisher feed. For widest compatibility, it is highly recommended to use the `feedUrl` attribute of the [``](remote-item.md) element in this capacity. 6 | 7 | For complete implementation details regarding publisher feeds and how to create them, please see the full publisher feed [documentation](../examples/publishers/publishers.md) and the `publisher` medium [here](./medium.md). 8 | 9 | ### Parent 10 | 11 | `` 12 | 13 | ### Count 14 | 15 | Single 16 | 17 | ### Example: 18 | 19 | ```xml 20 | 21 | <![CDATA[It's A Mood]]> 22 | A value4value happenstance music show. 23 | https://example.org/itsamood 24 | Sovereign Feeds 25 | Mike Neumann 26 | 469b403f-db2d-574c-9db9-96dbb4f6561c 27 | podcast 28 | 29 | 30 | 31 | 32 | <![CDATA[Runnin']]> 33 | Wed, 03 Apr 2024 02:06:28 +0000 34 | ... 35 | 36 | 37 | ``` 38 | -------------------------------------------------------------------------------- /proposal-docs/social/platforms.md: -------------------------------------------------------------------------------- 1 | ### Social Platform / Protocol 2 | 3 | Note: Draft - trying to figure out if the platform/protocol list should be a separate file. 4 | 5 | The and elements both contain a platform and protocol element. This is a list of suitable platforms and protocols 6 | 7 | - `platform` (required): This is the platform id. It can be one of the following: 8 | - `protocol` (required): This is the protocol name. It can be one of the following: 9 | 10 | | `platform` | `protocol` | 11 | | ---------- | ------------------| 12 | | castopod | activitypub | 13 | | mastodon | activitypub | 14 | | peertube | activitypub | 15 | | | xmpp | 16 | | | irc | 17 | | matrix | matrix | 18 | | facebook | facebook | 19 | | twitter | twitter | 20 | | instagram | instagram | 21 | | slack | slack | 22 | | discord | discord | 23 | | castgarden | hive | 24 | | 3speak | hive | 25 | | peakd | hive | 26 | | fountain | lightningcomments | 27 | 28 | 29 | - `platform` (required): This is the platform id. It can be one of the following: 30 | - castopod 31 | - mastodon 32 | - peertube 33 | - facebook 34 | - twitter 35 | - instagram 36 | - slack 37 | - discord 38 | - cast.garden 39 | - 3speak 40 | - peakd.com 41 | - fountain 42 | - … 43 | - `protocol` (required): This is the protocol name. It can be one of the following: 44 | - activitypub 45 | - xmpp 46 | - irc 47 | - matrix 48 | - facebook 49 | - twitter 50 | - instagram 51 | - slack 52 | - discord 53 | - hive 54 | - lightningcomments (see #347) 55 | - … 56 | -------------------------------------------------------------------------------- /docs/tags/block.md: -------------------------------------------------------------------------------- 1 | # Block 2 | 3 | `` 4 | 5 | This element allows a podcaster to express which platforms are allowed to publicly display this feed and its contents. In its basic form, it is a direct drop-in replacement for the `` tag, but allows for greater flexibility by the inclusion of the `id` attribute and by including multiple copies of itself in the feed. 6 | 7 | Platforms should not ingest a feed for public display/use if their slug exists in the `id` of a `yes` block tag, or if an unbounded `yes` block tag exists (meaning block all public ingestion). Conversely, if a platform finds their slug in the `id` of a `no` block tag, they are free to ingest that feed for public display/usage. 8 | 9 | In plain language, the sequence of discovery an ingesting platform should use is as follows: 10 | 11 | 1. Does `no` exist in this feed? Safe to ingest. 12 | 2. Does `yes` exist in this feed? Do not ingest. 13 | 3. Does `yes` exist in this feed? Do not ingest. 14 | 15 | ### Parent 16 | 17 | `` 18 | 19 | ### Count 20 | 21 | Multiple 22 | 23 | ### Attributes 24 | 25 | - **id** (optional) A single entry from the [service slug list](https://github.com/Podcastindex-org/podcast-namespace/blob/main/serviceslugs.txt). 26 | 27 | ### Node value 28 | 29 | The node value must be "yes" or "no". 30 | 31 | ### Examples 32 | 33 | ```xml 34 | 35 | yes 36 | ``` 37 | 38 | ```xml 39 | 40 | no 41 | ``` 42 | 43 | ```xml 44 | 45 | yes 46 | yes 47 | ``` 48 | 49 | ```xml 50 | 51 | yes 52 | no 53 | no 54 | ``` 55 | -------------------------------------------------------------------------------- /proposal-docs/podping/podping.md: -------------------------------------------------------------------------------- 1 | # The "podcast:podping" Specification 2 | 3 | Version 1.0 by Brian of London - 2021.06.08 4 | 5 |
6 | 7 | ## Purpose 8 | 9 | The Podping notification system is rapidly developing as a new standard for signalling new episodes of podcasts to reduce constant polling. Once a new episode or entirely new podcast is sent out as a podping on the Hive blockchain, aggregators and apps can query the feed. 10 | 11 | However, as pointed out in issue https://github.com/Podcastindex-org/podcast-namespace/issues/258, there is, as yet, no way to know which feeds are using Podping. 12 | 13 | This tag proposal will allow feed owners and the hosts of multiple feeds, to signal that future updates will be sent via Podping and there is no need to speculatively poll this rss feed. 14 | 15 | An additional benefit will derive if feeds signal the name or names of the Hive accounts authorized to send Podpings. These authorized Hive accounts will be included in a `` tag 16 | 17 | ## API Requirements 18 | 19 | This tag can also contribute to a future API endpoint for the PodcastIndex which can easily return whether or not any given RSS feed is using Podping and return the Hive accounts authorized to send pings. 20 | 21 | ## Specification 22 | 23 | For the `` tag there is only one optional attribute `usesPodping` which will usually be set to `True` though could be set to `False` to specifically opt out of using Poding and indicate a feed must be polled by legacy RSS polling methods. 24 | 25 | For the optional but helpful `` tag there is one attribute, a single value with a single Hive account which is allowed to issue `podpings` for this feed. 26 | 27 | ## Example 28 | 29 | ```xml 30 | 31 | 32 | 33 | 34 | 35 | ``` 36 | 37 | ## Example 38 | 39 | ```xml 40 | 41 | ``` 42 | 43 | or 44 | 45 | ```xml 46 | 47 | ``` 48 | -------------------------------------------------------------------------------- /docs/examples/chapters/exampleComplex.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.2.0", 3 | "author": "John Doe", 4 | "title": "Episode 7 - Making Progress", 5 | "podcastName": "John's Awesome Podcast", 6 | "chapters": 7 | [ 8 | { 9 | "startTime": 0, 10 | "title": "Intro" 11 | }, 12 | { 13 | "startTime": 168, 14 | "title": "Hearing Aids" 15 | }, 16 | { 17 | "startTime": 260, 18 | "title": "Progress Report" 19 | }, 20 | { 21 | "startTime": 410, 22 | "title": "Namespace", 23 | "img": "https://example.com/images/namepsace_example.jpg", 24 | "url": "https://github.com/Podcastindex-org/podcast-namespace" 25 | }, 26 | { 27 | "startTime": 3990, 28 | "title": "Just Break Up", 29 | "img": "https://example.com/images/justbreakuppod.png", 30 | "url": "https://twitter.com/justbreakuppod" 31 | }, 32 | { 33 | "startTime": 4200, 34 | "title": "Played song by artist", 35 | "img": "https://i.discogs.com/R-249504-1334592212.jpeg?bucket=discogs-images&fit=contain&format=auto&height=600&quality=90&width=600&signature=wMI9I0mHkbVxkkryQrN1JkkzhwFsrereuom9Lmfa92w%3D", 36 | "url": "https://www.discogs.com/Rick-Astley-Never-Gonna-Give-You-Up/master/96559", 37 | "value": "" 38 | }, 39 | { 40 | "startTime": 4600, 41 | "title": "Donations", 42 | "url": "https://example.com/paypal_link" 43 | }, 44 | { 45 | "startTime": 4826, 46 | "img": "https://example.com/images/parisfrance.jpg", 47 | "toc": false, 48 | "location": { 49 | "name": "Eiffel Tower, Paris", 50 | "geo": "geo:42.3417649,-70.9661596" 51 | } 52 | }, 53 | { 54 | "startTime": 5510, 55 | "title": "The Big Players" 56 | }, 57 | { 58 | "startTime": 5854, 59 | "title": "Spread the Word" 60 | }, 61 | { 62 | "startTime": 6089, 63 | "title": "Outro" 64 | } 65 | ] 66 | } 67 | -------------------------------------------------------------------------------- /docs/tags/podroll.md: -------------------------------------------------------------------------------- 1 | # Podroll 2 | 3 | `` 4 | 5 | This element allows for a podcaster to include references to one or more podcasts in its `` as a way of "recommending" other podcasts to their listener. It's normally shown in user interfaces as "creator recommendations", or "shows you might like". 6 | 7 | ### Parent 8 | 9 | `` 10 | 11 | ### Count 12 | 13 | Single 14 | 15 | ### Node value 16 | 17 | The node value must be one or more [``](remote-item.md) elements. 18 | 19 | ### Examples 20 | 21 | ```xml 22 | 23 | 24 | 25 | 26 | 27 | ``` 28 | 29 | Above, the simplest way to use a podroll, using the [one mandatory value for the `remoteItem`](remote-item.md). 30 | 31 | ```xml 32 | 33 | 38 | 43 | 48 | 49 | ``` 50 | 51 | Above, a recommended podroll entry. It includes the `feedUrl` as well as the `feedGuid`, to help podcast apps discover shows without the GUID if they need to. It also includes a title, which is helpful for humans, and potentially for display in the app. 52 | 53 | If information differs, information discoverable from the GUID always takes precedence. RSS feeds can change; the [GUID](guid.md) does not. 54 | 55 | While the remoteItem includes an optional `itemGuid`, it is not expected that a podroll would normally link to individual episodes. 56 | 57 | (Humans: you can [put a GUID into the search box](https://podcastindex.org/search?q=917393e3-1b1e-5cef-ace4-edaa54e1f810&type=all) on the Podcast Index website). 58 | -------------------------------------------------------------------------------- /docs/tags/txt.md: -------------------------------------------------------------------------------- 1 | # Txt 2 | 3 | `` 4 | 5 | This element holds free-form text and is modeled after the DNS "[TXT](https://en.wikipedia.org/wiki/TXT_record)" record. It's meant to allow for usages that might be niche or otherwise not rise to the level of needing a dedicated tag. Just like TXT records in DNS allowed for new things like [SPF](https://en.wikipedia.org/wiki/Sender_Policy_Framework#Implementation) to evolve, this tag can allow novel techniques to be created and sandboxed without a formalization process. 6 | 7 | ### Parent 8 | 9 | `` or `` 10 | 11 | ### Count 12 | 13 | Multiple 14 | 15 | ### Attributes 16 | 17 | - **purpose** (optional) A service specific string that will be used to denote what purpose this tag serves. This could be something like "example.com" if it's a third party hosting platform needing to insert this data, or something like "verify", "release" or any other free form bit of info that is useful to the end consumer that needs it. The free form nature of this tag requires that this attribute is also free formed. This value should not exceed `128 characters`. 18 | 19 | ### Purposes 20 | 21 | The following are a list of strings known to be in common use. This list is in no way exhaustive. As new purposes come into common use, this list will be updated by the community to reflect that. 22 | 23 | - `verify` - The node value is expected to contain a string that is given by a third party platform to a podcaster in order to prove that they are the owner of the feed and are in control of it. This is meant to replace the need for emails to exist in feeds. See example section below. 24 | - `applepodcastsverify` - Same as above but [used by Apple](https://help.apple.com/itc/podcasts_connect/#/itcb54353390:~:text=podcast%3Atxt%20purpose%3D%E2%80%9C-,applepodcastsverify,-%E2%80%9D%3E). 25 | 26 | ### Node value 27 | 28 | This is a free form string. Please do not exceed `4000 characters` for the node value or it may be truncated by aggregators. 29 | 30 | ### Examples 31 | 32 | ```xml 33 | naj3eEZaWVVY9a38uhX8FekACyhtqP4JN 34 | ``` 35 | 36 | ```xml 37 | S6lpp-7ZCn8-dZfGc-OoyaG 38 | ``` 39 | 40 | ```xml 41 | 05124 42 | ``` 43 | 44 | ```xml 45 | 2022-10-26T04:45:30.742Z 46 | ``` 47 | -------------------------------------------------------------------------------- /docs/tags/trailer.md: -------------------------------------------------------------------------------- 1 | # Trailer 2 | 3 | `` 4 | 5 | This element is used to define the location of an audio or video file to be used as a trailer for the entire podcast or a specific season. There can be more than one trailer present in the channel of the feed. This element is basically just like an [``](https://cyber.harvard.edu/rss/rss.html#ltenclosuregtSubelementOfLtitemgt) with the extra `pubdate` and `season` attributes added. 6 | 7 | If there is more than one trailer tag present in the channel, the most recent one (according to its `pubdate`) should be chosen as the preview by default within podcast apps. 8 | 9 | ### Parent 10 | 11 | `` 12 | 13 | ### Count 14 | 15 | Multiple 16 | 17 | ### Node Value 18 | 19 | The node value is a string, which is the title of the trailer. It is required. Please do not exceed `128 characters` for the node value or it may be truncated by aggregators. 20 | 21 | ### Attributes 22 | 23 | - **url:** (required) This is a url that points to the audio or video file to be played. This attribute is a string. 24 | - **pubdate:** (required) The date the trailer was published. This attribute is an RFC2822 formatted date string. 25 | - **length:** (recommended) The length of the file in bytes. This attribute is a number. 26 | - **type:** (recommended) The mime type of the file. This attribute is a string. 27 | - **season:** (optional) If this attribute is present it specifies that this trailer is for a particular season number. This attribute is a number. 28 | 29 | If the `season` attribute is present, it must be a number that matches the format of the [``](season.md) tag. So, for a podcast that has 3 published seasons, a new `` tag can be put in the channel to later be matched up with a `4` tag when it is published within a new ``. 30 | 31 | #### Examples 32 | 33 | ```xml 34 | Coming April 1st, 2021 40 | ``` 41 | 42 | ```xml 43 | Season 4: Race for the Whitehouse 50 | 51 | (later matches with) 52 | 53 | 4 54 | ``` 55 | -------------------------------------------------------------------------------- /docs/tags/value-recipient.md: -------------------------------------------------------------------------------- 1 | # Value Recipient 2 | 3 | `` 4 | 5 | The `valueRecipient` tag designates various destinations for payments to be sent to during consumption of the enclosed media. Each recipient is considered to receive a "split" of the total payment according to the number of shares given in the `split` attribute. 6 | 7 | This element may only exist within a parent [``](value.md) element. 8 | 9 | There is no limit on how many `valueRecipient` elements can be present in a given [``](value.md) element. 10 | 11 | This is a complex tag, so implementors are HIGHLY encouraged to read the companion [document](../examples/value/value.md) for a complete understanding of how this tag works and what it is capable of. 12 | 13 | ### Parent 14 | 15 | [``](value.md) 16 | 17 | ### Count 18 | 19 | Multiple 20 | 21 | ### Attributes 22 | 23 | - **name** (recommended) A free-form string that designates who or what this recipient is. 24 | - **customKey** (optional) The name of a custom record key to send along with the payment. 25 | - **customValue** (optional) A custom value to pass along with the payment. This is considered the value that belongs to the `customKey`. 26 | - **type** (required) A slug that represents the type of receiving address that will receive the payment. 27 | - **address** (required) This denotes the receiving address of the payee. 28 | - **split** (required) The number of shares of the payment this recipient will receive. 29 | - **fee** (optional) If this attribute is not specified, it is assumed to be false. 30 | 31 | ### Examples 32 | 33 | ```xml 34 | 35 | 41 | 47 | 53 | 60 | 61 | ``` 62 | -------------------------------------------------------------------------------- /docs/tags/remote-item.md: -------------------------------------------------------------------------------- 1 | # Remote Item 2 | 3 | `` 4 | 5 | This element provides a way to "point" to another feed or an `` in another feed in order to obtain some sort of data that the other feed or feed item has. This allows a podcast app to know where to go and fetch the data being requested. What data is being requested is determined by the parent item. For instance, if the parent item is a [``](podroll.md) element, then the remote feed's `` metadata is needed. 6 | 7 | Using the `feedGuid` attribute is the preferred way to address a remote feed since, but there are times when an app may not have access to a list of resolvable [``](guid.md)'s. In that case, it can be beneficial to include the `feedUrl` attribute for those cases as a fallback. If both are present and the app is capable the `feedGuid` should be resolved and used. 8 | 9 | ### Parent 10 | 11 | `` or [``](podroll.md) or [``](value-time-split.md) or [``](publisher.md) 12 | 13 | ### Count 14 | 15 | Multiple 16 | 17 | ### Attributes 18 | 19 | - **feedGuid** (required) The [``](guid.md) of the remote feed being pointed to. 20 | - **feedUrl** (optional) The url of the remote feed being pointed to. 21 | - **itemGuid** (optional) If this remote item element is intended to point to an `` in the remote feed, this attribute should contain the value of the `` of that ``. 22 | - **medium** (optional) If the feed being pointed to is not of medium type 'podcast', this attribute should contain it's [``](medium.md) type from the [list](./medium.md#medium) of types available in this document. The reason this is helpful is to give the app a heads up on what type of data this is expected to be since that may affect the way it approaches fetch and display. 23 | - **title** (optional) A string that represents the title of the remote item. The purpose of this attribute is to give a hint to apps so that they can display the title without having to do a remote lookup. 24 | 25 | ### Examples 26 | 27 | ```xml 28 | 29 | ``` 30 | 31 | ```xml 32 | 36 | ``` 37 | 38 | ```xml 39 | 46 | ``` 47 | -------------------------------------------------------------------------------- /proposal-docs/chat/chat.md: -------------------------------------------------------------------------------- 1 | # The "podcast:chat" Specification 2 | 3 | Version 1.0 by Dave Jones - 2022.04.10 4 | 5 |
6 | 7 | ## Purpose 8 | The `` tag allows a podcaster to attach information to either the `channel` or an `item` about where the 9 | "official" chat for either the podcast or a specific episode is to be found. Just like `` 10 | functions for social media, the `chat` tag will function for ephemeral chat. There are many protocols in use across 11 | the internet for chat based communication. This tag is meant to be flexible enough to adapt to whichever protocol the 12 | podcaster wants to use. 13 | 14 | This tag can exist at the `channel` or `item` level. It's presence at a particular level governs how it should be 15 | treated. If found at the `item` level, this should be treated as the information for that specific episode, 16 | overriding what is at the `channel` level. If this tag is found at the `channel` level, it would be considered the 17 | chat for the entire podcast and is recommended to be an "always on" chat room experience. 18 | 19 | If a podcast has an "always on" style chat service it is recommended to link that at the `channel` level and do not 20 | use the `` tag at the `item` level. 21 | 22 | ## Chat Element 23 | ``

24 | 25 | ### Parent 26 |   `` or `` 27 | 28 | ### Count 29 |   Single 30 | 31 | ### Attributes 32 | - **server** (required) The fqdn of a chat server that serves as the "bootstrap" server to connect to. 33 | - **protocol** (required) The [protocol](chatprotocols.txt) in use on the server. 34 | - **accountId** (recommended) The account id of the podcaster on the server or platform being connected to. 35 | - **space** (optional) Some chat systems have a notion of a chat "space" or "room" or "topic". This attribute will serve 36 | that purpose. 37 | 38 | 39 | Example (IRC): 40 | ```xml 41 | 47 | ``` 48 | 49 | Example (XMPP): 50 | ```xml 51 | 57 | ``` 58 | 59 | Example (Nostr): 60 | ```xml 61 | 67 | ``` 68 | 69 | Discussions: 70 | - https://github.com/Podcastindex-org/podcast-namespace/discussions/502 -------------------------------------------------------------------------------- /docs/tags/chat.md: -------------------------------------------------------------------------------- 1 | # Chat 2 | 3 | `` 4 | 5 | This element allows a podcaster to attach information to either the ``, `` or [``](live-item.md) about where the "official" chat for either the podcast or a specific episode or live event is to be found. Just like [``](social-interact.md) functions for social media, the `` tag will function for ephemeral chat. There are many protocols in use across the internet for chat based communication. This tag is meant to be flexible enough to adapt to whichever protocol the podcaster wants to use. 6 | 7 | This element's presence at a particular level governs how it should be treated. If found at the `` or [``](live-item.md) level, this should be treated as the information for that specific episode, overriding what is at the `` level. If this tag is found at the `` level, it would be considered the chat for the entire podcast and is recommended to be an "always on" chat room experience. 8 | 9 | If a podcast has an "always on" style chat service it is recommended to link that at the `` level and do not use the `` tag at the `` or [``](live-item.md) level. 10 | 11 | ### Parent 12 | 13 | `` or `` or [``](live-item.md) 14 | 15 | ### Count 16 | 17 | Single 18 | 19 | ### Attributes 20 | 21 | - `server` (required) The fqdn of a chat server that serves as the "bootstrap" server to connect to. 22 | - `protocol` (required) The [protocol](../chatprotocols.txt) in use on the server. 23 | - `accountId` (recommended) The account id of the podcaster on the server or platform being connected to. 24 | - `space` (optional) Some chat systems have a notion of a chat "space" or "room" or "topic". This attribute will serve that purpose. 25 | 26 | ### Example (IRC): 27 | 28 | ```xml 29 | 35 | ``` 36 | 37 | ### Example (XMPP): 38 | 39 | ```xml 40 | 46 | ``` 47 | 48 | ### Example (Nostr): 49 | 50 | ```xml 51 | 57 | ``` 58 | 59 | ### Example (Matrix): 60 | 61 | ```xml 62 | 68 | ``` 69 | -------------------------------------------------------------------------------- /docs/examples/license/licenses.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "All Rights Reserved", 4 | "shortname": "ARR", 5 | "version": null, 6 | "description": "The copyright holder reserves, or holds for their own use, all the rights provided by copyright law, such as distribution, performance, and creation of derivative works; that is, they have not waived any such right.", 7 | "commercial": false, 8 | "attribution": false, 9 | "derivatives": false, 10 | "link": "https://en.wikipedia.org/wiki/All_rights_reserved" 11 | }, 12 | { 13 | "name": "Creative Commons Attribution", 14 | "shortname": "CC-BY-4.0", 15 | "version": "4.0", 16 | "description": "You are free to copy and redistribute the material in any medium or format for any purpose, even commercially. You are free to remix, transform, and build upon the material for any purpose, even commercially. You must give appropriate credit , provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.", 17 | "commercial": true, 18 | "attribution": true, 19 | "derivatives": false, 20 | "link": "https://creativecommons.org/licenses/by/4.0/" 21 | }, 22 | { 23 | "name": "Creative Commons Attribution - NonCommercial", 24 | "shortname": "CC-BY-NC-4.0", 25 | "version": "4.0", 26 | "description": "You are free to copy and redistribute the material in any medium or format. You are free to remix, transform, and build upon the material. You must give appropriate credit , provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.", 27 | "commercial": false, 28 | "attribution": true, 29 | "derivatives": true, 30 | "link": "https://creativecommons.org/licenses/by-nc/4.0/deed.en" 31 | }, 32 | { 33 | "name": "Creative Commons Attribution - NonCommercial - NoDerivs", 34 | "shortname": "CC-BY-NC-ND-4.0", 35 | "version": "4.0", 36 | "description": "You are free to copy and redistribute the material in any medium or format. You must give appropriate credit , provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.", 37 | "commercial": false, 38 | "attribution": true, 39 | "derivatives": false, 40 | "link": "https://creativecommons.org/licenses/by-nc-nd/4.0/deed.en" 41 | }, 42 | { 43 | "name": "Podcast V4V License", 44 | "shortname": "POD-V4V-1.0", 45 | "version": "1.0", 46 | "description": "", 47 | "commercial": true, 48 | "attribution": true, 49 | "derivatives": false, 50 | "link": "/license/v4v-4.0.md" 51 | } 52 | ] -------------------------------------------------------------------------------- /docs/schema/podcast-example.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1 4 | 5 | Support the show 6 | 7 | Austin, TX 8 | 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678 9 | yes 10 | Becky Smith 11 | Adam Curry 12 | Adam Curry 13 | Adam Curry 14 | Dave Jones 15 | Dave Jones 16 | Dave Jones 17 | 1 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /docs/examples/value/lnaddress.md: -------------------------------------------------------------------------------- 1 | ## The 'lnaddress' Recipient Type 2 | 3 | An `lnaddress` address is a 4 | "[lightning address](https://github.com/andrerfneves/lightning-address/blob/master/DIY.md)" that resolves to the uri of 5 | a payment options file which contains one or more payment destination addresses. For example, an `lnaddress` of 6 | "johndoe@example.com" would be converted to the uri "https://example.com/.well-known/lnurlp/johndoe/options" which MUST 7 | contain an appropriately formatted JSON file. 8 | 9 | ## Options File 10 | 11 | The payment options file MUST contain a JSON object that holds exactly one `options` array. The purpose of the payment 12 | options file is to hold all the various payment receipt methods (and corresponding destination info for each) that a 13 | user has available to them. It looks like this: 14 | 15 | ```json 16 | { 17 | "status": "OK", 18 | "options": [ 19 | { 20 | "type": "lnurlp", 21 | "callback": "https://example.com/v1/lnurlp/johndoe/pay", 22 | "minSendable": 1000, 23 | "maxSendable": 1000000000000, 24 | "metadata": "[[\"text/plain\",\"Pay @johndoe on example wallet\"]]", 25 | "commentAllowed": 500 26 | }, 27 | { 28 | "type": "keysend", 29 | "pubkey": "03b6f613e88bd874177c28c6ad83b3baba43c4c656f56be1f8df84669556054b79", 30 | "customData": [ 31 | { 32 | "customKey": "906608", 33 | "customValue": "01hIWsCYxdBJzlDvu5zpT3" 34 | } 35 | ] 36 | } 37 | ] 38 | } 39 | ``` 40 | 41 | ### Options array 42 | 43 | Each member of the `options` array is a distinct payment method describing a payment destination for a user. The 44 | properties available for an "option" depends on it's `type` and should be taken from the definition of that type as it 45 | exists in the primary documentation. Using the above example, we can see that there are two payment options defined 46 | for user John Doe - `lnurlp` and `keysend`. The structure and properties for `lnurlp` are defined 47 | [here](https://github.com/lnurl/luds/blob/luds/06.md), while the structure and properties for `keysend` are defined 48 | [here](#keysend-option). 49 | 50 | ## Keysend option 51 | 52 | The `keysend` payment option has a type of `keysend` and has the following properties: 53 | 54 | * `pubkey`(required) - The public address of the lightning node that will receive the keysend payment. 55 | * `customData` - An array that contains two members: 56 | * `customKey` - A text value that defines a routing key for the receiving node. 57 | * `customValue` - A text value that defines a routing value for the receiving node. 58 | 59 | The `customData` array is optional for cases where the receiving node is a front-end for a multi-wallet 60 | system. In this context, the `customKey` will be what the receiving system looks up inside the payment in order to 61 | retreive the `customValue` which is a virtual wallet identifier. 62 | 63 | ## BOLT12 option 64 | 65 | Under development... -------------------------------------------------------------------------------- /docs/examples/license/license.md: -------------------------------------------------------------------------------- 1 | # The "podcast:license" Specification 2 | 3 | Version 1.0 by Benjamin Bellamy - 2021.03.05 4 | 5 |
6 | 7 | ## Purpose 8 | 9 | Podcasting is an open ecosystem where information travel freely from platform to platform, but that does not mean that podcasts are free. 10 | The fact that podcast files are available for anyone to download does not mean that anyone is allowed to do anything with them. 11 | But how can one know what is permitted? It is often difficult, or even impossible, to know - even more if you want to manage that automatically. 12 | This situation creates awkward conflicts where everyone acts in good faith, everyone shares the same goal (growing audiences for podcasts) but everyone disagrees on what is acceptable. 13 | 14 | - Can the podcast be locally copied? Then can the copy be shared? Should it be fetched from the original location only? 15 | - Can the podcast be shared/played for free? 16 | - Can the podcast be shared/played for a fixed fee? For a subscription fee? 17 | - Can the podcast be used to display ads on it? 18 | - Can it be used for audio insertion? Pre-roll, mid-roll, post-roll? 19 | - Can it be trimmed, cut, edited? Translated? Dubbed? 20 | - Can the shownotes be trimmed, cut, edited? Converted from HTML to plain text? 21 | 22 | We have seen in the past Podcasters demanding to have their podcast removed from a platform because they felt they were being stolen from, even if that would mean less audience for them. 23 | If we can provide a way to make what is allowed and what is forbidden crystal clear, we will avoid such conflicts. 24 | 25 | Please note that this document is about what can be done after the podcast is published, not before. 26 | (For instance, using copyrighted music or copyrighted material in a podcast is not the subject here.) 27 | 28 | You may read [PODCASTING LEGAL GUIDE: RULES FOR THE REVOLUTION](https://wiki.creativecommons.org/wiki/Podcasting_Legal_Guide) for more information. 29 | 30 | This matter is very complex so this specification only intends to scratch its surface in its current version. 31 | 32 | ## Specification 33 | 34 | - **\[License Slug from [License List](licenseslugs.txt) or Custom Liense name]** 35 | 36 | Channel (optional | single) 37 | 38 | Item (optional | single) 39 | 40 | This element allows a podcaster to specify a license for a podcast or an episode. 41 | 42 | - `url` (required): This is the url to the license file. 43 | 44 | Examples: 45 | 46 | - `(CC BY-ND 4.0)` 47 | - `(CC BY-NC-ND 4.0)` 48 | - `© My Company 2021 - All Rights Reserved` 49 | 50 | Discussion here: 51 | 52 | - (https://github.com/Podcastindex-org/podcast-namespace/issues/177) 53 | - (https://podcastindex.social/web/statuses/105839486748529374) 54 | -------------------------------------------------------------------------------- /proposal-docs/license/license.md: -------------------------------------------------------------------------------- 1 | # The "podcast:license" Specification 2 | 3 | Version 1.0 by Benjamin Bellamy - 2021.03.05 4 | 5 |
6 | 7 | ## Purpose 8 | 9 | Podcasting is an open ecosystem where information travel freely from platform to platform, but that does not mean that podcasts are free. 10 | The fact that podcast files are available for anyone to download does not mean that anyone is allowed to do anything with them. 11 | But how can one know what is permitted? It is often difficult, or even impossible, to know - even more if you want to manage that automatically. 12 | This situation creates awkward conflicts where everyone acts in good faith, everyone shares the same goal (growing audiences for podcasts) but everyone disagrees on what is acceptable. 13 | 14 | - Can the podcast be locally copied? Then can the copy be shared? Should it be fetched from the original location only? 15 | - Can the podcast be shared/played for free? 16 | - Can the podcast be shared/played for a fixed fee? For a subscription fee? 17 | - Can the podcast be used to display ads on it? 18 | - Can it be used for audio insertion? Pre-roll, mid-roll, post-roll? 19 | - Can it be trimmed, cut, edited? Translated? Dubbed? 20 | - Can the shownotes be trimmed, cut, edited? Converted from HTML to plain text? 21 | 22 | We have seen in the past Podcasters demanding to have their podcast removed from a platform because they felt they were being stolen from, even if that would mean less audience for them. 23 | If we can provide a way to make what is allowed and what is forbidden crystal clear, we will avoid such conflicts. 24 | 25 | Please note that this document is about what can be done after the podcast is published, not before. 26 | (For instance, using copyrighted music or copyrighted material in a podcast is not the subject here.) 27 | 28 | You may read [PODCASTING LEGAL GUIDE: RULES FOR THE REVOLUTION](https://wiki.creativecommons.org/wiki/Podcasting_Legal_Guide) for more information. 29 | 30 | This matter is very complex so this specification only intends to scratch its surface in its current version. 31 | 32 | ## Specification 33 | 34 | - **\[License Slug from SPDX List]** 35 | 36 | Channel (optional | single) 37 | 38 | Item (optional | single) 39 | 40 | This element allows a podcaster to specify a license for a podcast or an episode. 41 | 42 | - `url` (required): This is the url to the license file. 43 | 44 | Examples: 45 | - `(CC BY-ND 4.0)` 46 | - `(CC BY-NC-ND 4.0)` 47 | - `© My Company 2021 - All Rights Reserved` 48 | 49 | 50 | Discussion here: 51 | - (https://github.com/Podcastindex-org/podcast-namespace/issues/177) 52 | - (https://podcastindex.social/web/statuses/105839486748529374) 53 | - (https://spdx.org/licenses/) 54 | 55 | -------------------------------------------------------------------------------- /docs/tags/social-interact.md: -------------------------------------------------------------------------------- 1 | # Social Interact 2 | 3 | `` 4 | 5 | The `socialInteract` tag allows a podcaster to attach the url of a "root post" of a comment thread to an episode, or to the podcast as a whole. This "root post" is treated as the canonical location of where the comments and discussion around the episode or podcast will take place. This can be thought of as the "official" social media comment space for the episode or podcast. If a protocol such as "activitypub" is used, or some other protocol that allows programmatic API access, these comments can be directly pulled into the app, and replies can be posted back to the thread from the app itself. 6 | 7 | If multiple `socialInteract` tags are given for an `` or the ``, the `priority` attribute is strongly recommended to give the app an indication as to which comments to display first. 8 | 9 | This tag can also be used as a signal to platforms and apps that the podcaster does not want public comments shown alongside the episode or podcast. For this purpose a `protocol` value of "disabled" can be specified, with no other attributes or node value present. 10 | 11 | ### Parent 12 | 13 | `` or `` 14 | 15 | ### Count 16 | 17 | Multiple 18 | 19 | ### Attributes 20 | 21 | - **protocol** (required) The [protocol](https://github.com/Podcastindex-org/podcast-namespace/blob/main/socialprotocols.txt) in use for interacting with the comment root post. 22 | - **uri** (required) The uri/url of root post comment. 23 | - **accountId** (recommended) The account id (on the commenting platform) of the account that created this root post. 24 | - **accountUrl** (optional) The public url (on the commenting platform) of the account that created this root post. 25 | - **priority** (optional) When multiple socialInteract tags are present, this integer gives order of priority. A lower number means higher priority. 26 | 27 | Example (simple): 28 | 29 | ```xml 30 | 35 | ``` 36 | 37 | Example (complex): 38 | 39 | ```xml 40 | 47 | 54 | ``` 55 | 56 | Example (disabled): 57 | 58 | ```xml 59 | 60 | ``` 61 | 62 | - For **activitypub**, Mastodon or Pleroma's posting API returns a URI (a fully-formed URL with a GUID in it), and a URL (the HTML page where the comment lives). While both of these are acceptable values for the `uri` field referenced in the `socialInteract` specification, we'd recommend using the URI value. 63 | -------------------------------------------------------------------------------- /docs/1.0.md: -------------------------------------------------------------------------------- 1 | # RSS Namespace Extension for Podcasting (Tag Specification) 2 | 3 | A wholistic RSS namespace for podcasting that is meant to synthesize the fragmented world of podcast namespaces. As 4 | elements are canonized, they will be added to this document so developers can begin implementation. The 5 | specifications below are considered locked and the team will prioritize backward compatibility. We are operating 6 | under the [Rules for Standards-Makers](http://scripting.com/2017/05/09/rulesForStandardsmakers.html). 7 | 8 | The namespace for this extension is `https://podcastindex.org/namespace/1.0`. Clients which recognize this namespace 9 | must also recognize `https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md` as identical. The 10 | suggested tag prefix for use in XML is `podcast`, but clients should support alternate prefixes for this namespace. 11 | If your application generates RSS feeds and you implement one or more elements below, you will need to link this 12 | document in your XML: 13 | 14 | ```xml 15 | 16 | ``` 17 | 18 | ## Podcast Tags 19 | 20 | Each tag below exists in the podcast namespace within the specified parent. All attributes are required unless 21 | explicitly specified as optional. Anywhere the url of a hyper-text based resource is specified, it must be given as 22 | `https:` and not `http:`. 23 | 24 | ## Table of Contents 25 | 26 | - [Transcript](tags/transcript.md) 27 | - [Locked](tags/locked.md) 28 | - [Funding](tags/funding.md) 29 | - [Chapters](tags/chapters.md) 30 | - [Soundbite](tags/soundbite.md) 31 | - [Person](tags/person.md) 32 | - [Location](tags/location.md) 33 | - [Season](tags/season.md) 34 | - [Episode](tags/episode.md) 35 | - [Trailer](tags/trailer.md) 36 | - [License](tags/license.md) 37 | - [Alternate Enclosure](tags/alternate-enclosure.md) 38 | - [Source](tags/source.md) 39 | - [Integrity](tags/integrity.md) 40 | - [Guid](tags/guid.md) 41 | - [Value](tags/value.md) 42 | - [Value Recipient](tags/value-recipient.md) 43 | - [Medium](tags/medium.md) 44 | - [Live Item](tags/live-item.md) 45 | - [Content Link](tags/content-link.md) 46 | - [Social Interact](tags/social-interact.md) 47 | - [Block](tags/block.md) 48 | - [Txt](tags/txt.md) 49 | - [Remote Item](tags/remote-item.md) 50 | - [Podroll](tags/podroll.md) 51 | - [Update Frequency](tags/update-frequency.md) 52 | - [Podping](tags/podping.md) 53 | - [Value Time Split](tags/value-time-split.md) 54 | - [Chat](tags/chat.md) 55 | - [Publisher](tags/publisher.md) 56 | - [Image](tags/image.md) 57 | 58 | ## Deprecated 59 | - [Images](tags/images-(deprecated).md) -------------------------------------------------------------------------------- /proposal-docs/bonusItem/bonusItem.md: -------------------------------------------------------------------------------- 1 | # The "podcast:bonusItem" Specification 2 | 3 | Version 1.0 by [Franco Solerio](https://github.com/francosolerio)
4 | January 10th, 2022 5 | 6 | ## Purpose 7 | 8 | With Value4Value podcasters can give their audience the possibility to send payments in response to the action of listening to a show. After a few months from its invention many shows already demonstrated that audiences embrace this possibility and reward podcasters, creating a virtuous loop that favours the production of more and better content. It is also evident that single listeners contribute in very different degrees, from big amounts to nothing. This can be attributed to many reasons, just to name a few: use of apps that still don't support Podcasting 2.0, the listener's financial condition, culture ad good will, the podcaster's ability to stimulate contribution both by improving the quality of their show and istigating listeners to contribute. 9 | 10 | The purpose of the `` block is to give podcasters another way to stimulate active contribution from the listeners by publishing bonus content on the same RSS feed, and making it available on the same app the listener already uses to consume regular episodes. 11 | 12 | Being available only on apps that support the specification, other than encouraging the financial contributions from the listeners, bonus content would give a competitive advantage and stimulate the adoption of the apps that support Podcasting 2.0 features. 13 | 14 | 15 | ## Process 16 | 17 | When the app parses the RSS feed, it stores and displays both the content of the usual `` blocks available in the standard RSS specification and the bonus items contained in `` blocks. The former are displayed as usual, while bonus content is displayed in a way that marks it as available for playing only when some conditions are met. 18 | 19 | The conditions can be specified in the `` block in terms of amount of money contributed in a specific timeframe. More than one alternative condition can be specified. 20 | 21 | Examples: 22 | - A bonus episode can be played by listeners who contributed with at least 10'000 sats in the last month. 23 | - An hystoric archive of episodes from the previous years is available for those who sent at least 100'000 sats in their lifetime. 24 | 25 | 26 | ## Structure: 27 | 28 | The structure of a `` block is identical to that of a regular `` block, with the addition of a `` sub-item: 29 | 30 | ```xml 31 | 32 | ... 33 | ... 34 | ... 35 | 36 | ... 37 | 41 | 42 | ``` 43 | 44 | ### Sub-elements of \ 45 | - `` (required) This specifies the mandatory condition to make the bonus item available to the user. 46 | It has one required and one optional attribute. 47 | 48 | #### Attributes of \ 49 | - `minimumAmount` (required) specifies the minimum amount the user has to contribute to have access to the bonus item. The type of payment is the one specified in the \ block contained at the \ level. 50 | - `timeFrame` (optional) specifies the time, in seconds, to be considered for reaching the specified amount. If not present the time interval to be considered valid to reach the minimum amount is infinite. 51 | -------------------------------------------------------------------------------- /docs/tags/location.md: -------------------------------------------------------------------------------- 1 | # Location 2 | 3 | `` 4 | 5 | _Revised in 2025:_ This tag is intended to describe the location of editorial focus, or the source of production 6 | for a podcast's content; answering the question "where is this podcast about?" or "where was the podcast made?". 7 | The tag has many use cases and is one of the more complex ones. 8 | 9 | > [!IMPORTANT] 10 | > You are **highly encouraged** to read the 11 | > full [implementation document](../examples/location/location.md) 12 | > before starting to code for it. This document includes rationale and example code. 13 | 14 | ### Parent 15 | 16 | `` or `` or `` 17 | 18 | ### Count 19 | 20 | Multiple 21 | 22 | ### Node Value 23 | 24 | This is a free-form string meant to be a human readable location. It may conform to conventional location 25 | verbiage (i.e. "Austin, TX"), but it shouldn't be depended on to be parseable in any specific way. This value 26 | cannot be blank. Please do not exceed `128 characters` for the node value or it may be truncated by aggregators. This 27 | value is mostly intended as a "display" value and it's **highly encouraged** to use the other recommended attributes to 28 | define the actual location parameters. 29 | 30 | ### Attributes 31 | 32 | - **rel:** (recommended) The `rel` attribute can contain one of the following possible values: 33 | - `"subject"` (default) - The location refers to what/where the content is about. 34 | - `"creator"` - The location refers to where the content was recorded or produced. 35 | - **geo:** (recommended) A latitude and longitude in geoURI form, following [RFC5870](https://datatracker.ietf.org/doc/html/rfc5870) (i.e. "geo:30.2672,97.7431"). 36 | - **osm:** (recommended) The [OpenStreetMap](https://www.openstreetmap.org/#map=13/41.39239/2.14036) identifier of this place. Made by taking the first character of the [OSM object type](https://locationiq.com/glossary/osm-type) (Node, Way, Relation), followed by the ID. (i.e. "R113314") 37 | - **country:** (recommended) A two-letter code for the country, following [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) 38 | 39 | > [!NOTE] 40 | > While all elements are "recommended", **the location tag works best when all elements are populated.** The [implementation document](../examples/location/location.md) goes into more detail. An example location generator (entirely in JavaScript) is [over here](https://jamescridland.github.io/podcast-location-generator/). 41 | 42 | ### Examples 43 | 44 | - A podcast _made in_ [Austin TX](https://www.openstreetmap.org/relation/113314) in the US: 45 | 46 | ```xml 47 | Austin 53 | ``` 54 | 55 | - A podcast about the [Birmingham Civil Rights Museum](https://www.openstreetmap.org/relation/6930627) in Birmingham, AL: 56 | 57 | ```xml 58 | Birmingham Civil Rights Museum 64 | ``` 65 | 66 | - A podcast _made in_ [Marlow, England](https://www.openstreetmap.org/relation/3727240) - _about_ [Dreamworld](https://www.openstreetmap.org/relation/16317988), a themepark in Australia: 67 | 68 | ```xml 69 | Marlow 75 | Dreamworld 81 | ``` 82 | -------------------------------------------------------------------------------- /docs/tags/update-frequency.md: -------------------------------------------------------------------------------- 1 | # Update Frequency 2 | 3 | `` 4 | 5 | This element allows a podcaster to express their intended release schedule as structured data and text. 6 | 7 | ### Parent 8 | 9 | `` 10 | 11 | ### Count 12 | 13 | Single 14 | 15 | ### Node value 16 | 17 | The node value is a free-form string, which might be displayed alongside other information about the podcast. Please do not exceed `128 characters` for the node value or it may be truncated by aggregators. 18 | 19 | ### Attributes 20 | 21 | - **complete (optional):** Boolean specifying if the podcast has no intention to release further episodes. If not set, this should be assumed to be false. 22 | - **dtstart (optional):** The `date` or `datetime` the recurrence rule begins as an [ISO8601-fornmatted](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) string. If the `rrule` contains a value for `COUNT`, then this attribute is required. If the `rrule` contains a value for `UNTIL`, then the value of this attribute must be formatted to the same date/datetime standard. 23 | - **rrule (recommended):** A recurrence rule as defined in [iCalendar RFC 5545 Section 3.3.10](https://www.rfc-editor.org/rfc/rfc5545#section-3.3.10). 24 | 25 | ### Examples 26 | 27 | Recreating most of Apple Podcasts Connect's "Update Frequency" values is easily achieved: 28 | 29 | ```xml 30 | Daily 31 | 32 | Weekly 33 | 34 | Biweekly 35 | 36 | Monthly 37 | 38 | Bimonthly 39 | 40 | Monthly 41 | 42 | Yearly 43 | ``` 44 | 45 | However, greater precision can be easily communicated: 46 | 47 | ```xml 48 | Every weekday 49 | 50 | Every Monday and Wednesday 51 | 52 | Every friday the 13th 53 | 54 | 55 | Every year on American Thanksgiving 56 | 57 | ``` 58 | 59 | Limited-run podcasts can indicate when they'll go on hiatus by setting an UNTIL date or a COUNT: 60 | 61 | ```xml 62 | 63 | Every other Monday for 10 episodes starting on Aug 28, 2023 64 | 65 | 66 | 67 | Every Monday until Dec 31, 2023 68 | 69 | ``` 70 | 71 | Podcasts currently on hiatus can indicate their intention to resume production by setting a DTSTART value in the future: 72 | 73 | ```xml 74 | 75 | Weekly, starting in 2025 76 | 77 | ``` 78 | 79 | Complete podcasts with no intention to release further episodes: 80 | 81 | ```xml 82 | That's all folks! 83 | ``` 84 | -------------------------------------------------------------------------------- /docs/tags/guid.md: -------------------------------------------------------------------------------- 1 | # Guid 2 | 3 | `` 4 | 5 | This element is used to declare a unique, global identifier for a podcast. The value is a UUIDv5, and is easily generated from the RSS feed url, with the **protocol scheme and trailing slashes stripped off**, combined with a unique "podcast" namespace which has a UUID of `ead4c236-bf58-58c6-a2c6-a6b28d128cb6`. Tools like [this one](https://www.uuidtools.com/v5) can help generate these values by hand. Or, language libraries like [this one](https://github.com/sporkmonger/uuidtools) in Ruby are widely available. Specifically for podcasts, [this tool from RSS Blue](https://tools.rssblue.com/podcast-guid) can help generate a GUID by hand. 6 | 7 | A podcast gets assigned a podcast:guid once in its lifetime using its current feed url (at the time of assignment) as the seed value. That GUID is then meant to follow the podcast from then on, for the duration of its life, even if the feed url changes. This means that when a podcast moves from one hosting platform to another, its podcast:guid should be discovered by the new host and imported into the new platform for inclusion into the feed. 8 | 9 | Using this pattern, podcasts can maintain a consistent identity across the open RSS ecosystem without a central authority. 10 | 11 | **Tips:** 12 | 13 | - All podcasts in the Podcast Index have already been assigned a GUID; but if one exists in the RSS feed, that value is canonical. 14 | - You can programmatically spot a GUID: it is 36 characters long, and contains four hyphen characters. 15 | - Be aware that Amazon Music also uses separate UUIDv5 identifiers within their podcast directory, which are calculated differently and unrelated to this specification. 16 | - The following regular expression (regex) will match a GUID: 17 | 18 | ```re 19 | [0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}` 20 | ``` 21 | 22 | ### Parent 23 | 24 | `` 25 | 26 | ### Count 27 | 28 | Single 29 | 30 | ### Node Value 31 | 32 | The node value is a UUIDv5 string. 33 | 34 | ### Examples 35 | 36 | Example GUID for feed url `mp3s.nashownotes.com/pc20rss.xml`: 37 | 38 | ```xml 39 | 917393e3-1b1e-5cef-ace4-edaa54e1f810 40 | ``` 41 | 42 | Example GUID for feed url `podnews.net/rss`: 43 | 44 | ```xml 45 | 9b024349-ccf0-5f69-a609-6b82873eab3c 46 | ``` 47 | 48 | ### Guid-enabled fast-follow share links 49 | 50 | The `podcast:guid` value above enables podcasters to produce a link that can share a podcast on a variety of different platforms. 51 | 52 | The format of the link is `https://(a podcast website link)#fastfollow-(type):(a podcast guid)` 53 | 54 | `type` is currently `podcast`, but may be extended in future. 55 | 56 | A working example is https://podnews.net/podcast/i8xe9/listen#fastfollow-podcast:9b024349-ccf0-5f69-a609-6b82873eab3c or the QR code given below. 57 | 58 | ![podnews-qr](https://user-images.githubusercontent.com/231941/127796108-d819de43-6c0e-4c7b-9579-ed1f19989443.png) 59 | 60 | When scanned on a mobile phone's camera app, this link will go to the specified podcast website. Behavior of this website is up to the creator: some may use a default homepage, others may sniff the useragent and open a default podcast app on a device. In the working example, above, an iPhone user may be taken to Apple Podcasts; an Android user may be taken to Google Podcasts; and another device will be given a page with a player. 61 | 62 | When scanned on a QR code reader inside a podcast app, like [CurioCaster](https://curiocaster.com/), the app can parse the `` value from the URL, allowing the podcast to be opened within the application. 63 | -------------------------------------------------------------------------------- /proposal-docs/opensubscribe/opensubscribe.md: -------------------------------------------------------------------------------- 1 | # The "podcast:subscribe" Specification 2 | 3 | Version 1.0 by [Dave Jones](https://github.com/daveajones)
4 | January 6th, 2022 5 | 6 |
7 | 8 | ## Purpose 9 | 10 | Podcasting requires a publicly available RSS feed to function in it's traditionally decentralized capacity. This has led to various schemes of 11 | "private" feeds that require either a basic authentication login to be prepended to the url, or a tokenized url that is unique for each subscriber. 12 | Neither of these are ideal. We envision an open way of subscribing to a single feed url. It doesn't matter if the feed itself is tokenized. All 13 | that really matters is that the members-only feed's enclosures are kept private only to subscribers. We outline a method here for achieving this 14 | type of tokenized enclosure delivery by way of a single, publicly available RSS feed.tokenized 15 | 16 |

17 | 18 | ## Process 19 | 20 | The process of subscribing to a feed consists of making the purchase, storing a shared seed value and storing a shared subscriber id. The purchase 21 | can be made over standard payment processors, cryptocurrency or any other method of payment the podcast creator chooses to use. 22 | 23 |
24 | 25 | ### Initiating the purchase 26 | 27 | A members-only feed will contain a `` element that points to a website the user will use to complete the subscription signup 28 | process. That process can be any method of paying and the app would probably just open a web view to the site and let the signup process happen 29 | right in the app. 30 | 31 | ### Generating the shared values 32 | 33 | Once the signup and payment has occurred, the server that processed the signup will generate a seed value to be used in a TOTP (Time-based One Time Password) 34 | calculation. The seed value will be stored by the server in order to calculate the TOTP value in the future. It will also be handed back to the app which 35 | will store the seed in it's internal database associated with this particular RSS feed. A user identifier will also be generated by the server and handed 36 | back to the app so that an association can be kept between the TOTP seed and the user it belongs to. 37 | 38 | ### Playing the Content 39 | 40 | When the app does a GET request for an enclosure within the subscription feed, it will first calculate the current TOTP value based on it's stored copy 41 | of the seed and then attach that value to the GET request as a url parameter, like this: 42 | 43 | ```http 44 | GET https://example.com/cdn/podcast/episode23.mp3?_subscriberid=019280835669288573153765328753&_privtoken=247163 45 | ``` 46 | 47 | The server validates the transmitted TOTP code by generating it server side based on the subscriber id given in the request.subscriber 48 | If the subscriber's subscription ever lapses, the server simply forgets the TOTP seed and no future requests for content will validate. 49 | 50 | ### Moving subscriptions between apps 51 | 52 | Because subscriptions are maintained by a simple TOTP random seed value, the values can be exported along with an opml file and imported into other apps. 53 | 54 |

55 | 56 | ### Subscribe Element 57 | 58 | The `` tag designates the server that will handle the subscription processing for the feed. 59 | 60 | This element must exist at the `` level. 61 | 62 | There can be only one copy of this element in a feed. 63 | 64 |
65 | 66 | #### Structure: 67 | ```xml 68 | 71 | ``` 72 |
73 | 74 | #### Attributes: 75 | - `url` (required) This is the service slug of the cryptocurrency or protocol layer. 76 | 77 |
78 | 79 | -------------------------------------------------------------------------------- /existing-namespaces.txt: -------------------------------------------------------------------------------- 1 | xmlns:a10="http://www.w3.org/2005/Atom" 2 | xmlns:acast="https://schema.acast.com/1.0/" 3 | xmlns:addthis="https://www.addthis.com/help/api-spec" 4 | xmlns:admin="http://webns.net/mvcb/" 5 | xmlns:anchor="https://anchor.fm/xmlns" 6 | xmlns:atom10="http://www.w3.org/2005/Atom" 7 | xmlns:atom="http://w3.org/2005/Atom" 8 | xmlns:atom="http://www.w3.org/2005/Atom" 9 | xmlns:b="http://www.google.com/2005/gml/b" 10 | xmlns:bitlove="http://bitlove.org" 11 | xmlns:blogChannel="http://backend.userland.com/blogChannelModule" 12 | xmlns:castbox="http://castbox.fm/dtds/podcast-1.0.dtd" 13 | xmlns:cba="https://cba.fro.at/help#feeds" 14 | xmlns:cc="http://backend.userland.com/creativeCommonsRssModule" 15 | xmlns:cc="http://creativecommons.org/ns#" 16 | xmlns:cc="http://web.resource.org/cc/" 17 | xmlns:content="http://purl.org/rss/1.0/modules/content/" 18 | xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" 19 | xmlns:data="http://www.google.com/2005/gml/data" 20 | xmlns:dc="http://purl.org/dc/elements/1.1/" 21 | xmlns:dcterms="http://purl.org/dc/terms/" 22 | xmlns:expr="http://www.google.com/2005/gml/expr"> 23 | xmlns:fb="http://www.facebook.com/2008/fbml" 24 | xmlns:fb="https://www.facebook.com/2008/fbml" 25 | xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" 26 | xmlns:feedpress="https://feed.press/xmlns" 27 | xmlns:fh="http://purl.org/syndication/history/1.0" 28 | xmlns:fireside="http://fireside.fm/modules/rss/fireside" 29 | xmlns:forbrowser="http://counterfolk.com/ken/extrav/audio/newitemcontent.css" 30 | xmlns:fyyd="https://fyyd.de/fyyd-ns/" 31 | xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" 32 | xmlns:georss="http://www.georss.org/georss" 33 | xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0" 34 | xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0/play-podcasts.xsd" 35 | xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 36 | xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" 37 | xmlns:itunes="http://www.itunes.com/DTDs/Podcast-1.0.dtd" 38 | xmlns:itunes="http://www.itunes.com/dtds/Podcast-1.0.dtd" 39 | xmlns:itunes="https://www.itunes.com/dtds/podcast-1.0.dtd" 40 | xmlns:itunesu="http://www.itunesu.com/feed" 41 | xmlns:iweb="http://www.apple.com/iweb" 42 | xmlns:media="http://search.yahoo.com/mrss/" 43 | xmlns:media="http://www.rssboard.org/media-rss" 44 | xmlns:npr="https://www.npr.org/rss/" 45 | xmlns:nprml="https://api.npr.org/nprml" 46 | xmlns:og="http://opengraphprotocol.org/schema/" 47 | xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" 48 | xmlns:pinecast="https://pinecast.com/rss-dtd/1.0/" 49 | xmlns:pingback="https://podping.info/specification/1" 50 | xmlns:podaccess="https://access.acast.com/schema/1.0/" 51 | xmlns:podaccess="https://schema-access.acast.com/1.0/" 52 | xmlns:podfm="http://podfm.ru/RSS/extension" 53 | xmlns:psc="http://podlove.org/simple-chapters" 54 | xmlns:rawvoice="http://www.rawvoice.com/rawvoiceRssModule/" 55 | xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 56 | xmlns:rp="https://w3id.org/rp/v1" 57 | xmlns:s="http://purl.org/steeple" 58 | xmlns:serif="http://www.serif.com/" 59 | xmlns:slash="http://purl.org/rss/1.0/modules/slash/" 60 | xmlns:sms="http://sms.csx.cam.ac.uk/rss" 61 | xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 62 | xmlns:soundon="http://soundon.fm/spec/podcast-1.0" 63 | xmlns:spotify="http://www.spotify.com/ns/rss" 64 | xmlns:spotify="https://www.spotify.com/ns/rss" 65 | xmlns:svg="http://www.w3.org/2000/svg" 66 | xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" 67 | xmlns:thr="http://purl.org/syndication/thread/1.0" 68 | xmlns:wfw="http://wellformedweb.org/CommentAPI/" 69 | xmlns:xlink="http://www.w3.org/1999/xlink" 70 | xmlns:xlink="http://www.w3.org/1999/xlink" 71 | xmlns:xlink="https://www.w3.org/1999/xlink" -------------------------------------------------------------------------------- /proposal-docs/value-webmonetization/value-webmonetization.md: -------------------------------------------------------------------------------- 1 | # Web Monetization using `` 2 | 3 | To enable and promote Web Monetization (WM) in podcasting, necessary information for WM could be provided for a podcast by adding a `` tag to the RSS feed. 4 | https://github.com/Podcastindex-org/podcast-namespace/blob/main/value/value.md 5 | 6 | This `value` tag would have the following values for use with Web Monetization: 7 | ```xml 8 | 12 | ``` 13 | 14 | The `podcast:value.type` defines the cryptocurrency or protocol layer, which in this case is used to define Web Monetization payment information, using the value of `webmonetization`. 15 | 16 | The `method` of `ILP` specifies the use of [Interledger Protocol (ILP)](https://interledger.org/rfcs/0027-interledger-protocol-4/) which is the protocol for payment providers in WM. 17 | 18 | Within the `podcast:value` tag we also need to designate recipients. In Web Monetization, payment info is discovered using the [Simple Payment Setup Protocol](https://interledger.org/rfcs/0009-simple-payment-setup-protocol) with which the [Open Payments](https://docs.openpayments.dev/web-monetization) protocol is designed to be [backwards compatible](https://docs.openpayments.dev/web-monetization#backwards-compatibility-with-spsp). 19 | 20 | Both SPSP and Open Payments use a recipient address in the form of a [Payment Pointer](https://github.com/interledger/rfcs/blob/master/0026-payment-pointers/0026-payment-pointers.md) which will be provided in the `address` attribute, with the `type` of `paymentpointer`. 21 | 22 | ```xml 23 | 27 | 33 | 34 | ``` 35 | 36 | While payments in WM are streamed to a single payment pointer at a time, the WM authors suggest splits can be implemented using [Probabilistic Revenue Sharing](https://webmonetization.org/docs/probabilistic-rev-sharing) or perhaps it should be [implemented at the payment pointer](https://github.com/Podcastindex-org/podcast-namespace/issues/132#issuecomment-780145285) rather than expecting the client to be responsible. In either case, the `podcast:value` and `podcast:valueRecipient` tags can provide sufficient information for a web player or page to setup Web Monetization for the podcast. 37 | 38 | ------ 39 | 40 | ### Current 41 | https://github.com/Podcastindex-org/podcast-namespace/blob/main/value/value.md 42 | https://github.com/Podcastindex-org/podcast-namespace/blob/main/value/valueslugs.txt 43 | 44 | ### Web Monetization and Podcasting Discussion 45 | https://github.com/Podcastindex-org/podcast-namespace/issues/132 46 | https://github.com/WICG/webmonetization/issues/70 47 | 48 | ### Background WM (i.e. for podcast audio playing on a background tab) 49 | https://github.com/coilhq/web-monetization-projects/issues/387 50 | https://github.com/WICG/webmonetization/issues/17 51 | 52 | ### PRX Player Implementation (in production) 53 | Player repository: https://github.com/PRX/Play-Next.js 54 | Component to implement monetization: https://github.com/PRX/Play-Next.js/tree/main/components/Player/WebMonetized 55 | Parsing `webmonetization` from the RSS feed: https://github.com/PRX/Play-Next.js/blob/main/lib/parse/data/parseEmbedData.ts#L33-L40 56 | 57 | ### Castopod Implementation 58 | https://podlibre.social/@Castopod/105278541687633547 59 | https://blog.castopod.org/castopod-supports-web-monetization/ 60 | https://github.com/ad-aures/castopod/blob/v1.0.0-beta.14/app/Helpers/rss_helper.php#L85-L95 61 | 62 | ### PodStation Planning by [Guilherme Dellagustin](https://github.com/dellagustin) 63 | https://github.com/podStation/podStation/issues/185 64 | -------------------------------------------------------------------------------- /docs/other-recommendations.md: -------------------------------------------------------------------------------- 1 | # Other Recommendations from the Creators of the RSS Namespace Extension for Podcasting 2 | 3 | While the wholistic RSS namespace for podcasting is meant to synthesize the fragmented world of podcast namespaces, there are some existing standards and defacto-standards we want do endorse: 4 | 5 | ## Episode GUID 6 | 7 | For all new episodes, we recommended to use 8 | 9 | - either a permanent URI, e.g. `https://example.com/ep0003` 10 | - or a [Universally unique identifier (UUID)](https://en.wikipedia.org/wiki/Universally_unique_identifier) e.g. `7c029615-a810-5214-9342-eee73f58435d` 11 | 12 | The GUID of an episode should never change, even if a new version of the episode is being published, otherwise this episode will be duplicated downstream. 13 | 14 | Consumers of podcast feeds should fall back to the enclosure URL or the namespaced UUIDv5 (SHA1 Hash with ns:URL) of the enclosure URL, if the value is not set – see https://github.com/Podcastindex-org/podcast-namespace/issues/186#issuecomment-932742468 for more details. 15 | 16 | #### Examples 17 | 18 | Only one entry per `` is valid: 19 | 20 | ```xml 21 | https://example.com/ep0003 22 | 7c029615-a810-5214-9342-eee73f58435d 23 | ``` 24 | 25 | (`isPermaLink` is optional, its default value is true –) 26 | 27 | ## Episode Description and Summary 28 | 29 | If you use ``, it should be an actual summary of the episode, in one or two sentences, and not a copy of the description. Be aware that Apple dropped `` from [their spec](https://help.apple.com/itc/podcasts_connect/#/itcb54353390) but many other clients still support it. 30 | 31 | The [original RSS specification](https://cyber.harvard.edu/rss/rss.html#hrelementsOfLtitemgt) defined `description` as follows: 32 | 33 | > A channel may contain any number of ``s. An item may represent a "story" -- much like a story in a newspaper or magazine; if so its description is a synopsis of the story, and the link points to the full story. An item may also be complete in itself, if so, the description contains the text (entity-encoded HTML is allowed; see examples) … 34 | 35 | There also exists `` for dedicated HTML episode notes [[rssboard.org]](https://www.rssboard.org/rss-profile#namespace-elements-content-encoded), but more and more publishers switch to only having ``. 36 | 37 | When your description contains HTML, we recommend to wrap it into ``. See https://podnews.net/article/html-episode-notes-in-podcast-rss and https://podnews.net/article/how-podcast-show-notes-display for more information about supported HTML tags in different clients. Typical are `

`, `
`, `
`, `

    ` and `
  • `. 38 | 39 | ## Feed Paging and Archiving (RFC5005) 40 | 41 | To be able to put more metadata into RSS feeds, while keeping the full archive of all old episodes becomes a challange for some podcasters and podcast clients. A typical workaround in the industry is to only render the full metadata of the newest episodes, where there is already a proper solution since 2007: [RFC5005](https://tools.ietf.org/html/rfc5005) 42 | 43 | There are already a few players implementing RFC5005 for a while, but . Adoption from clients is sporadic. A new/different standard wouldn't help though because I'd say RFC5005 does all that's required. We need to be louder about the existence of the standard and ask for it's implementation from all sides. 44 | 45 | #### Examples 46 | 47 | Excerpt from https://feeds.metaebene.me/freakshow/mp3 feed page 2, 48 | parent ``: 49 | 50 | ```xml 51 |