Merge pull request #3 from theDanielJLewis/reorganize-examples

reorganize-examples
pull/707/head
Daniel J. Lewis 2025-06-13 17:08:30 -04:00 zatwierdzone przez GitHub
commit 8260e9464d
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
30 zmienionych plików z 378 dodań i 461 usunięć

Wyświetl plik

@ -1,210 +0,0 @@
## JSON Chapters Format
<small>Version 1.2 - Updated on 2021.04.15</small>
<br><br>
This is the initial spec for a json chapters format that can be referenced in an RSS feed using the `<podcast:chapters>` tag of
the "podcast" namespace. This file can reside on any publicly accessible url. See the podcast namespace documentation for
details on the format of the tag.
This type of file should be served with a Content-type of 'application/json+chapters'. Chapter order is assumed to be
in ascending order based on the `startTime`.
<br>
## "Chapters" Object
The chapters object is a simple JSON object with only 2 required properties:
- `version` (required - string) The version number of the format being used
- `chapters` (required - array) An array of chapter objects defined below
#### Optional Attributes:
- `author` (optional - string) The name of the author of this podcast episode.
- `title` (optional - string) The title of this podcast episode.
- `podcastName` (optional - string) The name of the podcast this episode belongs to.
- `description` (optional - string) A description of this episode.
- `fileName` (optional - string) The name of the audio file these chapters apply to.
- `waypoints` (optional - boolean) If this property is present, the locations in a chapter object should be displayed with a route between locations.
<br>
## The "Chapter" Object
The "chapter" object takes this basic form:
```json
{
"startTime": 94,
"title": "Donation Segment"
}
```
There is only one required attribute:
- `startTime` (required - float) The starting time of the chapter, expressed in seconds with float precision for fractions of a second.
<br>
#### Optional Attributes:
- `title` (optional - string) The title of this chapter.
- `img` (optional - string) The url of an image to use as chapter art.
- `url` (optional - string) The url of a web page or supporting document that's related to the topic of this chapter.
- `toc` (optional - boolean) If this property is present and set to false, this chapter should not display visibly to the user in either the table of contents or as a jump-to point in the user interface. It should be considered a "silent" chapter marker for the purpose of meta-data only. If this property is set to `true` or not present at all, this should be considered a normal chapter for display to the user. The name "toc" is short for "table of contents".
- `endTime` (optional - float) The end time of the chapter, expressed in seconds with float precision for fractions of a second.
- `location` (optional - object) This object defines an optional location that is tied to this chapter. It follows the structure of the [location](https://github.com/Podcastindex-org/podcast-namespace/blob/main/location/location.md) tag in the XML namespace.
<br>
## The Location Object:
The "location" object takes this basic form:
```json
{
"name": "Eiffel Tower, Paris",
"geo": "geo:48.858093,2.294694"
}
```
It is intended to provide for rich location-based experiences tied to a point of time within a podcast episode, or other feed based media. For example, a "walking tour" may include latitude and longitude waypoints along side the image within chapters markers as someone listens to the tour podcast. This
would allow apps to show a map with markers within the UI as the tour progresses. Or, perhaps a "History of the Middle East" podcast might expose a map to highlight where certain landmarks are when being discussed.
There are two required attributes:
- `name` (required - string) A human readable place name.
- `geo` (required - string) A simple latitude,longitude given in geoURI format, conformant to [RFC 5870](https://tools.ietf.org/html/rfc5870).
#### Optional Attributes:
- `osm` (optional - string) An OpenStreetMaps query string. Please see the [location](https://github.com/Podcastindex-org/podcast-namespace/blob/main/location/location.md) XML tag specification for full details.
<br>
## Basic example
Here is what a very basic chapters file may look like:
```json
{
"version": "1.2.0",
"chapters":
[
{
"startTime": 0,
"title": "Intro"
},
{
"startTime": 168,
"title": "Hearing Aids",
"img": "https://example.com/images/hearing_aids.jpg"
},
{
"startTime": 260,
"title": "Progress Report"
},
{
"startTime": 410,
"title": "Namespace",
"img": "https://example.com/images/namepsace_example.jpg",
"url": "https://github.com/Podcastindex-org/podcast-namespace"
},
{
"startTime": 3990,
"title": "Just Break Up",
"img": "https://example.com/images/justbreakuppod.png"
},
{
"startTime": 5510,
"title": "The Big Players"
},
{
"startTime": 5854,
"title": "Spread the Word"
},
{
"startTime": 6089,
"title": "Outro"
}
]
}
```
In this simple form, the chapter objects are treated as sequential just based on their index as a function of being
ordered in ascending fashion based on their `startTime`. In a very simple example such as this nothing is present except the `startTime`,
`title`, and a few bits of optional meta-data.
<br><br>
## More complex example
In this more robust example, we can bring in more meta-data about the podcast episode, and provide a way for this file to exist more easily in a web
context for something like an embedded HTML5 player on a website. Also there is an example of a "silent" chapter that has no presence in the visible
chapter list, but allows for different artwork to be shown:
```json
{
"version": "1.2.0",
"author": "John Doe",
"title": "Episode 7 - Making Progress",
"podcastName": "John's Awesome Podcast",
"chapters":
[
{
"startTime": 0,
"title": "Intro"
},
{
"startTime": 168,
"title": "Hearing Aids"
},
{
"startTime": 260,
"title": "Progress Report"
},
{
"startTime": 410,
"title": "Namespace",
"img": "https://example.com/images/namepsace_example.jpg",
"url": "https://github.com/Podcastindex-org/podcast-namespace"
},
{
"startTime": 3990,
"title": "Just Break Up",
"img": "https://example.com/images/justbreakuppod.png",
"url": "https://twitter.com/justbreakuppod"
},
{
"startTime": 4826,
"img": "https://example.com/images/parisfrance.jpg",
"toc": false,
"location": {
"name": "Eiffel Tower, Paris",
"geo": "geo:42.3417649,-70.9661596"
}
},
{
"startTime": 5510,
"title": "The Big Players"
},
{
"startTime": 5854,
"title": "Spread the Word"
},
{
"startTime": 6089,
"title": "Outro"
}
]
}
```
<br><br>
## Note about privacy
Clearly, when pulling in web based data there is the chance that this functionality could be used for tracking. As a safeguard against that, apps
using chapters are encouraged to prompt the user to acknowledge whether they trust the podcast in question before displaying the content. Trusted
podcasts can then be remembered for the future.

Wyświetl plik

@ -0,0 +1,193 @@
## JSON Chapters Format
<small>Version 1.2 - Updated on 2021.04.15</small>
This is the initial spec for a json chapters format that can be referenced in an RSS feed using the `<podcast:chapters>` tag of
the "podcast" namespace. This file can reside on any publicly accessible url. See the podcast namespace documentation for
details on the format of the tag.
This type of file should be served with a Content-type of 'application/json+chapters'. Chapter order is assumed to be
in ascending order based on the `startTime`.
## "Chapters" Object
The chapters object is a simple JSON object with only 2 required properties:
- `version` (required - string) The version number of the format being used
- `chapters` (required - array) An array of chapter objects defined below
#### Optional Attributes:
- `author` (optional - string) The name of the author of this podcast episode.
- `title` (optional - string) The title of this podcast episode.
- `podcastName` (optional - string) The name of the podcast this episode belongs to.
- `description` (optional - string) A description of this episode.
- `fileName` (optional - string) The name of the audio file these chapters apply to.
- `waypoints` (optional - boolean) If this property is present, the locations in a chapter object should be displayed with a route between locations.
## The "Chapter" Object
The "chapter" object takes this basic form:
```json
{
"startTime": 94,
"title": "Donation Segment"
}
```
There is only one required attribute:
- `startTime` (required - float) The starting time of the chapter, expressed in seconds with float precision for fractions of a second.
#### Optional Attributes:
- `title` (optional - string) The title of this chapter.
- `img` (optional - string) The url of an image to use as chapter art.
- `url` (optional - string) The url of a web page or supporting document that's related to the topic of this chapter.
- `toc` (optional - boolean) If this property is present and set to false, this chapter should not display visibly to the user in either the table of contents or as a jump-to point in the user interface. It should be considered a "silent" chapter marker for the purpose of meta-data only. If this property is set to `true` or not present at all, this should be considered a normal chapter for display to the user. The name "toc" is short for "table of contents".
- `endTime` (optional - float) The end time of the chapter, expressed in seconds with float precision for fractions of a second.
- `location` (optional - object) This object defines an optional location that is tied to this chapter. It follows the structure of the [location](https://github.com/Podcastindex-org/podcast-namespace/blob/main/location/location.md) tag in the XML namespace.
## The Location Object:
The "location" object takes this basic form:
```json
{
"name": "Eiffel Tower, Paris",
"geo": "geo:48.858093,2.294694"
}
```
It is intended to provide for rich location-based experiences tied to a point of time within a podcast episode, or other feed based media. For example, a "walking tour" may include latitude and longitude waypoints along side the image within chapters markers as someone listens to the tour podcast. This
would allow apps to show a map with markers within the UI as the tour progresses. Or, perhaps a "History of the Middle East" podcast might expose a map to highlight where certain landmarks are when being discussed.
There are two required attributes:
- `name` (required - string) A human readable place name.
- `geo` (required - string) A simple latitude,longitude given in geoURI format, conformant to [RFC 5870](https://tools.ietf.org/html/rfc5870).
#### Optional Attributes:
- `osm` (optional - string) An OpenStreetMaps query string. Please see the [location](../../tags/location.md) XML tag specification for full details.
## Basic example
Here is what a very basic chapters file may look like:
```json
{
"version": "1.2.0",
"chapters": [
{
"startTime": 0,
"title": "Intro"
},
{
"startTime": 168,
"title": "Hearing Aids",
"img": "https://example.com/images/hearing_aids.jpg"
},
{
"startTime": 260,
"title": "Progress Report"
},
{
"startTime": 410,
"title": "Namespace",
"img": "https://example.com/images/namepsace_example.jpg",
"url": "https://github.com/Podcastindex-org/podcast-namespace"
},
{
"startTime": 3990,
"title": "Just Break Up",
"img": "https://example.com/images/justbreakuppod.png"
},
{
"startTime": 5510,
"title": "The Big Players"
},
{
"startTime": 5854,
"title": "Spread the Word"
},
{
"startTime": 6089,
"title": "Outro"
}
]
}
```
In this simple form, the chapter objects are treated as sequential just based on their index as a function of being
ordered in ascending fashion based on their `startTime`. In a very simple example such as this nothing is present except the `startTime`,
`title`, and a few bits of optional meta-data.
## More complex example
In this more robust example, we can bring in more meta-data about the podcast episode, and provide a way for this file to exist more easily in a web
context for something like an embedded HTML5 player on a website. Also there is an example of a "silent" chapter that has no presence in the visible
chapter list, but allows for different artwork to be shown:
```json
{
"version": "1.2.0",
"author": "John Doe",
"title": "Episode 7 - Making Progress",
"podcastName": "John's Awesome Podcast",
"chapters": [
{
"startTime": 0,
"title": "Intro"
},
{
"startTime": 168,
"title": "Hearing Aids"
},
{
"startTime": 260,
"title": "Progress Report"
},
{
"startTime": 410,
"title": "Namespace",
"img": "https://example.com/images/namepsace_example.jpg",
"url": "https://github.com/Podcastindex-org/podcast-namespace"
},
{
"startTime": 3990,
"title": "Just Break Up",
"img": "https://example.com/images/justbreakuppod.png",
"url": "https://twitter.com/justbreakuppod"
},
{
"startTime": 4826,
"img": "https://example.com/images/parisfrance.jpg",
"toc": false,
"location": {
"name": "Eiffel Tower, Paris",
"geo": "geo:42.3417649,-70.9661596"
}
},
{
"startTime": 5510,
"title": "The Big Players"
},
{
"startTime": 5854,
"title": "Spread the Word"
},
{
"startTime": 6089,
"title": "Outro"
}
]
}
```
## Note about privacy
Clearly, when pulling in web based data there is the chance that this functionality could be used for tracking. As a safeguard against that, apps
using chapters are encouraged to prompt the user to acknowledge whether they trust the podcast in question before displaying the content. Trusted
podcasts can then be remembered for the future.

Wyświetl plik

@ -31,7 +31,7 @@ This matter is very complex so this specification only intends to scratch its su
## Specification ## Specification
- **\<podcast:license url="[url to license]" />[License Slug from [License List](/license/licenseslugs.txt) or Custom Liense name]</podcast:license>** - **\<podcast:license url="[url to license]" />[License Slug from [License List](licenseslugs.txt) or Custom Liense name]</podcast:license>**
Channel (optional | single) Channel (optional | single)
@ -42,11 +42,12 @@ This matter is very complex so this specification only intends to scratch its su
- `url` (required): This is the url to the license file. - `url` (required): This is the url to the license file.
Examples: Examples:
- `<podcast:license url="http://creativecommons.org/licenses/by-nd/4.0/">(CC BY-ND 4.0)</podcast:license>` - `<podcast:license url="http://creativecommons.org/licenses/by-nd/4.0/">(CC BY-ND 4.0)</podcast:license>`
- `<podcast:license url="http://creativecommons.org/licenses/by-nc-nd/4.0/">(CC BY-NC-ND 4.0)</podcast:license>` - `<podcast:license url="http://creativecommons.org/licenses/by-nc-nd/4.0/">(CC BY-NC-ND 4.0)</podcast:license>`
- `<podcast:license url="http://domain.tld/license.txt">© My Company 2021 - All Rights Reserved</podcast:license>` - `<podcast:license url="http://domain.tld/license.txt">© My Company 2021 - All Rights Reserved</podcast:license>`
Discussion here: Discussion here:
- (https://github.com/Podcastindex-org/podcast-namespace/issues/177) - (https://github.com/Podcastindex-org/podcast-namespace/issues/177)
- (https://podcastindex.social/web/statuses/105839486748529374) - (https://podcastindex.social/web/statuses/105839486748529374)

Wyświetl plik

@ -1,9 +1,10 @@
# The Publisher Medium # The Publisher Medium
v1.0 - April 5, 2024 v1.0 - April 5, 2024
<br> <br>
Below, you will find implementation details about using the `publisher` value in the [`<podcast:medium>`](https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md#medium) tag to Below, you will find implementation details about using the `publisher` value in the [`<podcast:medium>`](../../tags/medium.md) tag to
create "publisher feeds". create "publisher feeds".
<br> <br>
@ -33,14 +34,14 @@ discarded.
A publisher feed must have the following parts in it's `<channel>`: A publisher feed must have the following parts in it's `<channel>`:
1. A [`<podcast:medium>`](https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md#medium) tag with a value of `publisher`. 1. A [`<podcast:medium>`](../../tags/medium.md) tag with a value of `publisher`.
2. A valid [`<podcast:guid>`](https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md#guid). 2. A valid [`<podcast:guid>`](../../tags/guid.md).
3. One or more [`<podcast:remoteItem>`](https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md#remoteItem) tags that link to podcast feeds. 3. One or more [`<podcast:remoteItem>`](../../tags/remote-item.md) tags that link to podcast feeds.
### Example ### Example
The following example shows a publisher feed that links to all of the feeds published by the "AgileSet Media" entity. The following example shows a publisher feed that links to all of the feeds published by the "AgileSet Media" entity.
This feed also makes use of the [`<podcast:person>`](https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md#person) tag to define a responsible person at the This feed also makes use of the [`<podcast:person>`](../../tags/person.md) tag to define a responsible person at the
publishing entity. publishing entity.
```xml ```xml

Wyświetl plik

@ -6,7 +6,7 @@ Some transcript implementations are done in-browser. [CORS headers](https://deve
are required to make these files available from other websites. [A CORS tester is available here](https://cors-test.codehappy.dev/), are required to make these files available from other websites. [A CORS tester is available here](https://cors-test.codehappy.dev/),
to ensure that transcripts are available within browser-based players. to ensure that transcripts are available within browser-based players.
* **Want to support only one format?** WebVTT is used by Apple Podcasts for ingest, and also natively supported by web browsers. Because the WebVTT format is the most flexible, it's an ideal choice if you can only support one format. - **Want to support only one format?** WebVTT is used by Apple Podcasts for ingest, and also natively supported by web browsers. Because the WebVTT format is the most flexible, it's an ideal choice if you can only support one format.
The examples given below are just for convenience. In production you should ensure you are conforming to the actual spec for each format as defined in its own documentation. The examples given below are just for convenience. In production you should ensure you are conforming to the actual spec for each format as defined in its own documentation.
@ -21,7 +21,8 @@ While there is no defined maximum line-length, to ensure that displaying WebVTT
The full specification includes formatting features; these are typically not used in podcasting applications. The full specification includes formatting features; these are typically not used in podcasting applications.
#### Snippet: #### Snippet:
```
```vtt
WEBVTT WEBVTT
00:00:00.000 --> 00:00:05.000 00:00:00.000 --> 00:00:05.000
@ -52,7 +53,7 @@ Example file: [example.vtt](example.vtt)
This example code will add an audio player on a web page, and display the accompanying WebVTT file as the audio plays. (Note that this basic code will not show speaker names). This example code will add an audio player on a web page, and display the accompanying WebVTT file as the audio plays. (Note that this basic code will not show speaker names).
``` ```html
<div style="height:111px;text-align:center;"> <div style="height:111px;text-align:center;">
<audio id="vttplayer" controls preroll="none" src="https://podnews.net/audio/podnews240125.mp3?_from=P20spec"> <audio id="vttplayer" controls preroll="none" src="https://podnews.net/audio/podnews240125.mp3?_from=P20spec">
<track default src="https://podnews.net/audio/podnews240125.mp3.vtt"> <track default src="https://podnews.net/audio/podnews240125.mp3.vtt">
@ -70,8 +71,6 @@ document.getElementById('vttplayer').textTracks[0].addEventListener('cuechange',
</script> </script>
``` ```
<br><br>
## SRT ## SRT
The SRT format was designed for video captions but provides a suitable solution for podcast transcripts. The SRT format contains medium-fidelity timestamps and are a The SRT format was designed for video captions but provides a suitable solution for podcast transcripts. The SRT format contains medium-fidelity timestamps and are a
@ -80,12 +79,14 @@ popular export option from transcription services. An SRT file can be generated
SRT transcripts used for podcasts should adhere to the following specifications: SRT transcripts used for podcasts should adhere to the following specifications:
#### Properties: #### Properties:
- Max number of lines: 2 - Max number of lines: 2
- Max characters per line: 32 - Max characters per line: 32
- Speaker names (optional): Start a new card when the speaker changes. Include the speaker's name, followed by a colon. - Speaker names (optional): Start a new card when the speaker changes. Include the speaker's name, followed by a colon.
#### Snippet: #### Snippet:
```
```srt
1 1
00:00:00,000 --> 00:00:02,760 00:00:00,000 --> 00:00:02,760
Sarah: In today's episode, Sarah: In today's episode,
@ -124,12 +125,12 @@ do we need a podcast trailer?
Example file: [example.srt](example.srt) Example file: [example.srt](example.srt)
## JSON ## JSON
The JSON representation is a flexible format that accomodates various degrees of fidelity in a concise way. At the most precise, it enables word-by-word highlighting. This format for podcast transcripts should adhere to the following specifications. The JSON representation is a flexible format that accomodates various degrees of fidelity in a concise way. At the most precise, it enables word-by-word highlighting. This format for podcast transcripts should adhere to the following specifications.
#### Elements included in this representation: #### Elements included in this representation:
- `<version>`: The version of JSON transcript specification - `<version>`: The version of JSON transcript specification
- `<segments>`: An array of dialogue elements (segments) - `<segments>`: An array of dialogue elements (segments)
- `<speaker>`: Speaker - `<speaker>`: Speaker
@ -138,6 +139,7 @@ The JSON representation is a flexible format that accomodates various degrees of
- `<body>`: Dialogue content - `<body>`: Dialogue content
#### Snippet: #### Snippet:
```json ```json
{ {
"version": "1.0.0", "version": "1.0.0",
@ -163,7 +165,7 @@ The JSON representation is a flexible format that accomodates various degrees of
{ {
"speaker": "Darth Vader", "speaker": "Darth Vader",
"startTime": 2.25, "startTime": 2.25,
"endTime": 2.50, "endTime": 2.5,
"body": "father.\n" "body": "father.\n"
}, },
{ {
@ -178,27 +180,28 @@ The JSON representation is a flexible format that accomodates various degrees of
Example file: [example.json](example.json) Example file: [example.json](example.json)
<br><br>
## HTML ## HTML
The HTML transcript format provides a solution when a transcript is available but no or limited timecode data is available. HTML transcript files are considered low-fidelity and are designed to serve as an accessibility aid and provide searchable episode content. The HTML format used for podcast transcripts should adhere to the following specifications. The HTML transcript format provides a solution when a transcript is available but no or limited timecode data is available. HTML transcript files are considered low-fidelity and are designed to serve as an accessibility aid and provide searchable episode content. The HTML format used for podcast transcripts should adhere to the following specifications.
#### HTML tags used: #### HTML tags used:
- `<cite>`: Name of the speaker (if available) - `<cite>`: Name of the speaker (if available)
- `<time>`: Start time of monologue (if available) - `<time>`: Start time of monologue (if available)
- `<p>`: Content of monologue - `<p>`: Content of monologue
#### Snippet: #### Snippet:
```html ```html
<cite>Kevin:</cite> <cite>Kevin:</cite>
<time>0:00</time> <time>0:00</time>
<p>We have an update planned where we would like to give the ability to upload an artwork file for these videos</p> <p>
We have an update planned where we would like to give the ability to upload an
artwork file for these videos
</p>
<cite>Alban :</cite> <cite>Alban :</cite>
<time>0:09</time> <time>0:09</time>
<p>You're triggering Tom right now with a hey, here's a cool feature.</p> <p>You're triggering Tom right now with a hey, here's a cool feature.</p>
``` ```
Example file: [example.html](example.html) Example file: [example.html](example.html)
<br><br>

Wyświetl plik

@ -6,8 +6,6 @@ Created: 2022-01-24
License: CC0 License: CC0
``` ```
<br>
## Purpose ## Purpose
Using Value 4 Value apps, listeners can send sats to the podcasts they listen to. A per-minute payment is Using Value 4 Value apps, listeners can send sats to the podcasts they listen to. A per-minute payment is
@ -30,15 +28,11 @@ Simple Example:
} }
``` ```
<br>
## Specification ## Specification
The sender of a bLIP-10 payment (i.e. - the podcast app) needs to include some metadata so the podcast host can The sender of a bLIP-10 payment (i.e. - the podcast app) needs to include some metadata so the podcast host can
identify for whom the payment is for. Most fields are optional. identify for whom the payment is for. Most fields are optional.
<br>
### Formatting and encoding ### Formatting and encoding
A flat, key-value json structure is used where the keys listed below can be set. The json string is then encoded A flat, key-value json structure is used where the keys listed below can be set. The json string is then encoded
@ -76,51 +70,41 @@ Treated as `utf-8`, the hex value of the above json record would be:
3a203537342c20226e616d65223a2022506f64636173746572222c202273656e6465725f6e616d65223a20225065746572227d0a 3a203537342c20226e616d65223a2022506f64636173746572222c202273656e6465725f6e616d65223a20225065746572227d0a
``` ```
<br>
### Types ### Types
If a field is indicated to be a `str` in the fields-list, that means it is a JSON string (within quotes). An `int` is If a field is indicated to be a `str` in the fields-list, that means it is a JSON string (within quotes). An `int` is
a plain number. a plain number.
<br>
### Fields ### Fields
Identifying the podcast **required**: use one or more of `podcast`, `guid`, `feedID` and/or `url`. **guid preferred** Identifying the podcast **required**: use one or more of `podcast`, `guid`, `feedID` and/or `url`. **guid preferred**
* `guid` ( - `guid` (
str) [The `<podcast:guid>` tag](https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md#guid). str) [The `<podcast:guid>` tag](../../tags/guid.md).
* `podcast` (str) Title of the podcast - `podcast` (str) Title of the podcast
* `feedID` (int) ID of podcast in PodcastIndex.org directory - `feedID` (int) ID of podcast in PodcastIndex.org directory
* `url` (str) RSS feed URL of podcast - `url` (str) RSS feed URL of podcast
<br>
Identifying the episode **recommended**: use any of `episode`, `itemID` and/or `episode_guid`. **episode_guid Identifying the episode **recommended**: use any of `episode`, `itemID` and/or `episode_guid`. **episode_guid
preferred** preferred**
* `episode` (str) Title of the podcast episode - `episode` (str) Title of the podcast episode
* `itemID` (int) ID of episode in PodcastIndex.org directory - `itemID` (int) ID of episode in PodcastIndex.org directory
* `episode_guid` (str) The GUID of the episode - `episode_guid` (str) The GUID of the episode
<br>
Information about time within the episode **recommended**: use one of `ts` or `time`. **ts preferred** Information about time within the episode **recommended**: use one of `ts` or `time`. **ts preferred**
* `ts` (int) Timestamp of when the payment was sent, in seconds, as an offset from zero (i.e. - playback position) - `ts` (int) Timestamp of when the payment was sent, in seconds, as an offset from zero (i.e. - playback position)
* `time` (str) Timestamp of when the payment was sent, in HH:MM:SS notation, as an offset from 00:00:00 - `time` (str) Timestamp of when the payment was sent, in HH:MM:SS notation, as an offset from 00:00:00
(i.e. - playback position) (i.e. - playback position)
<br>
Other fields that are strongly recommended: Other fields that are strongly recommended:
* `action` **recommended**: (str) "boost", "stream" or "auto". See Appending B of the - `action` **recommended**: (str) "boost", "stream" or "auto". See Appending B of the
[value](/value.md#appendix-b---payment-actions) spec for details. [value](/value.md#appendix-b---payment-actions) spec for details.
* `app_name`: **recommended** (str) Name of sending app - `app_name`: **recommended** (str) Name of sending app
* `sender_name` **recommended** (str) Name of the sender (free text, not validated in any way) - `sender_name` **recommended** (str) Name of the sender (free text, not validated in any way)
* `value_msat_total`: **recommended** (int) TOTAL Number of millisats for the payment before any fees are subtracted. - `value_msat_total`: **recommended** (int) TOTAL Number of millisats for the payment before any fees are subtracted.
This should be the number the listener entered into the app. Preserving This should be the number the listener entered into the app. Preserving
this value is important for numerology reasons. Certain numeric values can this value is important for numerology reasons. Certain numeric values can
have significance to the sender and/or receiver, so giving a way to show have significance to the sender and/or receiver, so giving a way to show
@ -130,39 +114,39 @@ Other fields that are strongly recommended:
Other optional fields: Other optional fields:
* `message` (str) Text message to add to the payment. When this field is present, the payment is known as a - `message` (str) Text message to add to the payment. When this field is present, the payment is known as a
"boostagram". "boostagram".
* `app_version`: (str) Version of sending app - `app_version`: (str) Version of sending app
* `boost_link`: (str) App specific URL containing route to podcast, episode, and/or timestamp at time of the action. - `boost_link`: (str) App specific URL containing route to podcast, episode, and/or timestamp at time of the action.
The use case for this is sending a link along with the payment that will take the recipient to The use case for this is sending a link along with the payment that will take the recipient to
the exact playback position within the episode where the payment was sent. the exact playback position within the episode where the payment was sent.
* `name` (str) Name for this split in value tag - `name` (str) Name for this split in value tag
* `sender_id` (str) Static random identifier for users, not displayed by apps to prevent abuse. Apps can set this - `sender_id` (str) Static random identifier for users, not displayed by apps to prevent abuse. Apps can set this
per-feed or app-wide. A GUID-like random identifier or a hash works well. Max 32 bytes (64 ascii per-feed or app-wide. A GUID-like random identifier or a hash works well. Max 32 bytes (64 ascii
characters). This can be a Nostr hex encoded pubkey (not NIP-19) for purposes of sender attribution. characters). This can be a Nostr hex encoded pubkey (not NIP-19) for purposes of sender attribution.
* `signature` (str) Optionally, this field can contain a signature for the payment, to be able to verify that the - `signature` (str) Optionally, this field can contain a signature for the payment, to be able to verify that the
user who sent it is actually who they claim in the `sender_id` field. If the `sender_id` contains user who sent it is actually who they claim in the `sender_id` field. If the `sender_id` contains
a Nostr public key, this field should contain a Nostr `sig` value as a 64-byte encoded hex string. a Nostr public key, this field should contain a Nostr `sig` value as a 64-byte encoded hex string.
For the purpose of generating the Nostr signature, the following data should be serialized: For the purpose of generating the Nostr signature, the following data should be serialized:
[0,`sender_id`,`ts`,1,[],`message`] to conform to the [0,`sender_id`,`ts`,1,[],`message`] to conform to the
[NIP-01](https://github.com/nostr-protocol/nips/blob/master/01.md) specification. The resulting [NIP-01](https://github.com/nostr-protocol/nips/blob/master/01.md) specification. The resulting
serialized string should be hashed with `sha256` to obtain the value. serialized string should be hashed with `sha256` to obtain the value.
* `speed` (str) Speed in which the podcast was playing, in decimal notation at the time the payment was sent. So 0.5 - `speed` (str) Speed in which the podcast was playing, in decimal notation at the time the payment was sent. So 0.5
is half speed and 2 is double speed. is half speed and 2 is double speed.
* `boost_uuid` (str) UUID for the boost/stream/auto payment. If there are several recipients, the same identifier should be sent to all of them. - `boost_uuid` (str) UUID for the boost/stream/auto payment. If there are several recipients, the same identifier should be sent to all of them.
* `uuid` (str) UUID of a payment sent out to a single recipient. - `uuid` (str) UUID of a payment sent out to a single recipient.
* `reply_address` (str) The pubkey of the lightning node that can receive payments for the sender. The node given - `reply_address` (str) The pubkey of the lightning node that can receive payments for the sender. The node given
must be capable of receiving keysend payments. If this field contains an "@" symbol, it should must be capable of receiving keysend payments. If this field contains an "@" symbol, it should
be interpreted as a be interpreted as a
"[lightning address](https://github.com/andrerfneves/lightning-address/blob/master/README.md#tldr)". "[lightning address](https://github.com/andrerfneves/lightning-address/blob/master/README.md#tldr)".
* `reply_custom_key` (int) The custom key for routing a reply payment to the sender. This field should not be present - `reply_custom_key` (int) The custom key for routing a reply payment to the sender. This field should not be present
if it is not required for payment routing. if it is not required for payment routing.
* `reply_custom_value` (str) The custom value for routing a reply payment to the sender. This field should not be - `reply_custom_value` (str) The custom value for routing a reply payment to the sender. This field should not be
present if it is not required for payment routing. present if it is not required for payment routing.
* `remote_feed_guid` (str) Sometimes a payment will be sent to a feed's value block by way of a `<podcast:valueTimeSplit>` - `remote_feed_guid` (str) Sometimes a payment will be sent to a feed's value block by way of a `<podcast:valueTimeSplit>`
tag containing a single `<podcast:remoteItem>` tag. When that happens, this field will contain the `feedGuid` attribute from tag containing a single `<podcast:remoteItem>` tag. When that happens, this field will contain the `feedGuid` attribute from
the `<podcast:remoteItem>` tag. the `<podcast:remoteItem>` tag.
* `remote_feed_guid` (str) Sometimes a payment will be sent to a feed's value block by way of a `<podcast:valueTimeSplit>` - `remote_feed_guid` (str) Sometimes a payment will be sent to a feed's value block by way of a `<podcast:valueTimeSplit>`
tag containing a single `<podcast:remoteItem>` tag having an `itemGuid` attribute. When that happens, this field will contain tag containing a single `<podcast:remoteItem>` tag having an `itemGuid` attribute. When that happens, this field will contain
the `itemGuid` attribute from the `<podcast:remoteItem>` tag. the `itemGuid` attribute from the `<podcast:remoteItem>` tag.
@ -170,17 +154,17 @@ Other optional fields:
## Reference Implementations ## Reference Implementations
* -
Breez: <https://github.com/breez/breezmobile/blob/4cf057c066d03c155964f0c4db43476cd70a57ab/lib/bloc/podcast_payments/podcast_payments_bloc.dart> Breez: <https://github.com/breez/breezmobile/blob/4cf057c066d03c155964f0c4db43476cd70a57ab/lib/bloc/podcast_payments/podcast_payments_bloc.dart>
* -
Podverse: <https://github.com/podverse/podverse-shared/blob/fff84c0143dea4fa01241109b8666d4c0b9a6ffc/src/satoshiStream.ts> Podverse: <https://github.com/podverse/podverse-shared/blob/fff84c0143dea4fa01241109b8666d4c0b9a6ffc/src/satoshiStream.ts>
* PodStation: <https://github.com/podStation/podStation/pull/249> - PodStation: <https://github.com/podStation/podStation/pull/249>
* Helipad: <https://github.com/Podcastindex-org/helipad/blob/203e72dafb65e4f9e89540fbe4fc07a456a9907a/src/main.rs> - Helipad: <https://github.com/Podcastindex-org/helipad/blob/203e72dafb65e4f9e89540fbe4fc07a456a9907a/src/main.rs>
* Rust-V4V: <https://github.com/Conshax/Rust-V4V/blob/master/src/boostagram.rs> - Rust-V4V: <https://github.com/Conshax/Rust-V4V/blob/master/src/boostagram.rs>
## Examples & App Specifics ## Examples & App Specifics
@ -340,7 +324,6 @@ received value of a split being less than it should calculated from the total.
"sender_name": "Jade Monkey", "sender_name": "Jade Monkey",
"message": "test" "message": "test"
} }
``` ```
#### Stream #### Stream

Wyświetl plik

@ -4,8 +4,6 @@
, [Evan Feenstra](https://github.com/evanfeenstra) & [Paul Itoi](https://github.com/pitoi)</small><br> , [Evan Feenstra](https://github.com/evanfeenstra) & [Paul Itoi](https://github.com/pitoi)</small><br>
<small>September 1st, 2021</small> <small>September 1st, 2021</small>
<br>
## Purpose ## Purpose
Here we describe an additional "block" of XML that gives podcasters (and other media creators) a way to receive direct Here we describe an additional "block" of XML that gives podcasters (and other media creators) a way to receive direct
@ -20,8 +18,6 @@ describes (within the feed) where and how they would like payments to be sent ba
of that media. The format is designed to be flexible enough to handle many scenarios of direct payment streaming. Even of that media. The format is designed to be flexible enough to handle many scenarios of direct payment streaming. Even
the use of fiat currency, if there is an API that is capable of interfacing as a receiver within this format. the use of fiat currency, if there is an API that is capable of interfacing as a receiver within this format.
<br>
## Play to Pay ## Play to Pay
This system can be thought of as Play-to-pay, rather than the traditional Pay-to-play paywall approach. When a This system can be thought of as Play-to-pay, rather than the traditional Pay-to-play paywall approach. When a
@ -30,8 +26,6 @@ block, a compatible app will be expected to begin streaming micro-payments to th
interval that makes sense for the app. The amount of each payment can be any amount the listener chooses, including interval that makes sense for the app. The amount of each payment can be any amount the listener chooses, including
zero. If the listener chooses not to pay to listen to this media, then the app can ignore the value block of that feed. zero. If the listener chooses not to pay to listen to this media, then the app can ignore the value block of that feed.
<br>
## Payment Intervals ## Payment Intervals
The "time interval" for calculating payments is **always 1 minute**. However, the actual interval between when payments The "time interval" for calculating payments is **always 1 minute**. However, the actual interval between when payments
@ -48,18 +42,12 @@ like this also helps to minimize the impact of transaction fees on the underlyin
Note that playback speed is not a factor in this calculation. The "one minute payment interval" refers to the minutes Note that playback speed is not a factor in this calculation. The "one minute payment interval" refers to the minutes
that make up the total runtime of the content, thus all payment calculations are independent of playback speed. that make up the total runtime of the content, thus all payment calculations are independent of playback speed.
<div class="page"/>
<br><br>
## Elements ## Elements
There are two elements that make up what we refer to as the "value block". They are a parent element that specifies the There are two elements that make up what we refer to as the "value block". They are a parent element that specifies the
currency to use, and one or more child elements that specify who to pay using the currency and protocol described by the currency to use, and one or more child elements that specify who to pay using the currency and protocol described by the
parent. parent.
<br>
### Value Element ### Value Element
The `<podcast:value>` tag designates the cryptocurrency or payment layer that will be used, the transport method for The `<podcast:value>` tag designates the cryptocurrency or payment layer that will be used, the transport method for
@ -68,8 +56,6 @@ the payments, and a suggested amount denominated in the given cryptocurrency.
This element can exist at either the `<channel>` or `<item>` level. This element can exist at either the `<channel>` or `<item>` level.
<br>
#### Structure: #### Structure:
```xml ```xml
@ -83,16 +69,12 @@ This element can exist at either the `<channel>` or `<item>` level.
</podcast:value> </podcast:value>
``` ```
<br>
#### Attributes: #### Attributes:
- `type` (required) This is the service slug of the cryptocurrency or protocol layer. - `type` (required) This is the service slug of the cryptocurrency or protocol layer.
- `method` (required) This is the transport mechanism that will be used. - `method` (required) This is the transport mechanism that will be used.
- `suggested` (optional) This is an optional suggestion on how much cryptocurrency to send with each payment. - `suggested` (optional) This is an optional suggestion on how much cryptocurrency to send with each payment.
<br>
#### Explanation: #### Explanation:
Using Lightning as an example, the `type` would be "lightning". Various possible `type` values will be kept Using Lightning as an example, the `type` would be "lightning". Various possible `type` values will be kept
@ -131,10 +113,6 @@ the Lightning Network is a millisat, which is a thousandth of a sat.
></podcast:value> ></podcast:value>
``` ```
<br><br>
<div class="page"/>
### Value Recipient Element ### Value Recipient Element
The `valueRecipient` tag designates various destinations for payments to be sent to during consumption of the enclosed The `valueRecipient` tag designates various destinations for payments to be sent to during consumption of the enclosed
@ -145,8 +123,6 @@ This element may only exist within a parent `<podcast:value>` element.
There is no limit on how many `valueRecipient` elements can be present in a given `<podcast:value>` element. There is no limit on how many `valueRecipient` elements can be present in a given `<podcast:value>` element.
<br>
#### Structure: #### Structure:
```xml ```xml
@ -162,8 +138,6 @@ There is no limit on how many `valueRecipient` elements can be present in a give
/> />
``` ```
<br>
#### Attributes: #### Attributes:
- `name` (recommended) A free-form string that designates who or what this recipient is. - `name` (recommended) A free-form string that designates who or what this recipient is.
@ -175,8 +149,6 @@ There is no limit on how many `valueRecipient` elements can be present in a give
- `split` (required) The number of shares of the payment this recipient will receive. - `split` (required) The number of shares of the payment this recipient will receive.
- `fee` (optional) If this attribute is not specified, it is assumed to be false. - `fee` (optional) If this attribute is not specified, it is assumed to be false.
<br>
#### Explanation: #### Explanation:
The `name` is just a human readable description of who or what this payment destination is. This could be something The `name` is just a human readable description of who or what this payment destination is. This could be something
@ -225,10 +197,6 @@ documented [in the list maintained by Satoshis Stream](https://github.com/satosh
If your specific application would benefit from your own `customKey:customValue` pair which will be passed along from If your specific application would benefit from your own `customKey:customValue` pair which will be passed along from
the player to your app, and for which nothing already exists, add your own. the player to your app, and for which nothing already exists, add your own.
<br><br>
<div class="page"/>
### Payment calculation ### Payment calculation
The interval payment calculation is: The interval payment calculation is:
@ -279,21 +247,21 @@ On a 190/152/38 split, each minute the payment calculation would be:
- Share total: 380 - Share total: 380
- Recipient #1 gets a payment of: 50 sats (190 / 380 * 100) - Recipient #1 gets a payment of: 50 sats (190 / 380 \* 100)
- Recipient #2 gets a payment of: 40 sats (152 / 380 * 100) - Recipient #2 gets a payment of: 40 sats (152 / 380 \* 100)
- Recipient #3 gets a payment of: 10 sats (38 / 380 * 100) - Recipient #3 gets a payment of: 10 sats (38 / 380 \* 100)
If an app chooses to only make a payout once every 30 minutes of listening/watching, the calculation would be the same If an app chooses to only make a payout once every 30 minutes of listening/watching, the calculation would be the same
after multiplying after multiplying
the per-minute payment by 30: the per-minute payment by 30:
- Interval payout: 3000 sats (100 * 30) - Interval payout: 3000 sats (100 \* 30)
- Shares total: 380 - Shares total: 380
- Recipient #1 gets a payment of: 1500 sats (190 / 380 * 3000) - Recipient #1 gets a payment of: 1500 sats (190 / 380 \* 3000)
- Recipient #2 gets a payment of: 1200 sats (152 / 380 * 3000) - Recipient #2 gets a payment of: 1200 sats (152 / 380 \* 3000)
- Recipient #3 gets a payment of: 300 sats (38 / 380 * 3000) - Recipient #3 gets a payment of: 300 sats (38 / 380 \* 3000)
As shown above, the once per minute calculation does not have to actually be sent every minute. A longer payout period As shown above, the once per minute calculation does not have to actually be sent every minute. A longer payout period
can be chosen. But, can be chosen. But,
@ -301,10 +269,6 @@ the once-per-minute nature of the payout still remains in order for listeners an
measure and calculate how much measure and calculate how much
they will spend and charge. they will spend and charge.
<br><br>
<div class="page"/>
### Supported Currencies and Protocols ### Supported Currencies and Protocols
The value block is designed to be flexible enough to handle most any cryptocurrency, and even fiat currencies with a The value block is designed to be flexible enough to handle most any cryptocurrency, and even fiat currencies with a
@ -321,8 +285,6 @@ widely implemented as of now.
[AMP]: https://bitcoinops.org/en/topics/multipath-payments/ [AMP]: https://bitcoinops.org/en/topics/multipath-payments/
<br>
#### Lightning #### Lightning
For the `<podcast:value>` tag, the following attributes MUST be used: For the `<podcast:value>` tag, the following attributes MUST be used:
@ -359,8 +321,6 @@ When sending a payment containing application specific data, the client must use
this specification, the inclusion of the TLV record with type `7629169`, as this specification, the inclusion of the TLV record with type `7629169`, as
defined [here](blip-0010.md), in order to correctly route the payment to the corresponding receiver defined [here](blip-0010.md), in order to correctly route the payment to the corresponding receiver
<br>
##### Example ##### Example
This is a live, working example of a Lightning keysend value block in production. It designates four recipients for This is a live, working example of a Lightning keysend value block in production. It designates four recipients for
@ -485,8 +445,6 @@ and guest.
</channel> </channel>
``` ```
<br>
### TLV Records and Extensions ### TLV Records and Extensions
Lightning payments are performed using lightning messages as specified Lightning payments are performed using lightning messages as specified
@ -500,31 +458,27 @@ found at the document [TLV record registry](https://github.com/satoshisstream/sa
. In special, the section _Fields used in customKey / customValue Pairs_ documents the known use cases for . In special, the section _Fields used in customKey / customValue Pairs_ documents the known use cases for
the `customKey` and `customValue` attributes. the `customKey` and `customValue` attributes.
<br>
### Payment Actions ### Payment Actions
There are currently 3 payment "actions" that are defined in the BLIP-10 TLV extension that is embedded in the payment There are currently 3 payment "actions" that are defined in the BLIP-10 TLV extension that is embedded in the payment
payload: "stream", "boost" and "auto". payload: "stream", "boost" and "auto".
* `stream` - This means the payment is a timed interval payment (i.e. - every minute) that is sent or queued while the - `stream` - This means the payment is a timed interval payment (i.e. - every minute) that is sent or queued while the
user is engaged in active listening/viewing of the content. user is engaged in active listening/viewing of the content.
* `boost` - This means the payment is a user generated one-time payment that happens in response to a user initiated - `boost` - This means the payment is a user generated one-time payment that happens in response to a user initiated
action like a "Boost" button push, or some other clearly labeled payment initiation function. These action like a "Boost" button push, or some other clearly labeled payment initiation function. These
types of payments can contain textual messages (i.e. - a boostagram). types of payments can contain textual messages (i.e. - a boostagram).
* `auto` - This means the payment was an app initiated payment that recurs at a specific long-form interval such as - `auto` - This means the payment was an app initiated payment that recurs at a specific long-form interval such as
weekly, monthly, yearly, etc. The user configures an interval and payment amount in the app and the app weekly, monthly, yearly, etc. The user configures an interval and payment amount in the app and the app
then sends that amount at the specified time when each interval passes. then sends that amount at the specified time when each interval passes.
<br>
### Value Recipient Address Types ### Value Recipient Address Types
There are a few different available recipient address types: There are a few different available recipient address types:
* `node` - The public address of a node. For instance, in the `lightning` value type this would represent a node's - `node` - The public address of a node. For instance, in the `lightning` value type this would represent a node's
public address. public address.
* `lnaddress` - A so-called "lightning address", which takes the form of an email address that gets resolved into an - `lnaddress` - A so-called "lightning address", which takes the form of an email address that gets resolved into an
options file which holds the underlying destinations for payment. See the full document options file which holds the underlying destinations for payment. See the full document
[here](lnaddress.md) for explanation. [here](lnaddress.md) for explanation.

Wyświetl plik

@ -2,7 +2,7 @@
`<podcast:chapters>` `<podcast:chapters>`
Links to an external file (see example file) containing chapter data for the episode. See the [jsonChapters.md](https://github.com/Podcastindex-org/podcast-namespace/blob/main/chapters/jsonChapters.md) file for a description of the chapter file syntax. And, see the [example.json](https://github.com/Podcastindex-org/podcast-namespace/blob/main/chapters/example.json) example file for a real world example. 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.
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. 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.

Wyświetl plik

@ -19,7 +19,7 @@ Single
### Attributes ### Attributes
- `server` (required) The fqdn of a chat server that serves as the "bootstrap" server to connect to. - `server` (required) The fqdn of a chat server that serves as the "bootstrap" server to connect to.
- `protocol` (required) The [protocol](../../chatprotocols.txt) in use on the server. - `protocol` (required) The [protocol](../chatprotocols.txt) in use on the server.
- `accountId` (recommended) The account id of the podcaster on the server or platform being connected to. - `accountId` (recommended) The account id of the podcaster on the server or platform being connected to.
- `space` (optional) Some chat systems have a notion of a chat "space" or "room" or "topic". This attribute will serve that purpose. - `space` (optional) Some chat systems have a notion of a chat "space" or "room" or "topic". This attribute will serve that purpose.

Wyświetl plik

@ -2,7 +2,7 @@
`<podcast:license>` `<podcast:license>`
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](../../license/license.md) for a more complete picture of what this tag is intended to accomplish. 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.
### Parent ### Parent
@ -14,7 +14,7 @@ Single
### Node Value ### Node Value
The node value must be a lower-cased reference to a license "identifier" defined in the companion [license list](../../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. 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.
### Attributes ### Attributes

Wyświetl plik

@ -8,8 +8,8 @@ The tag has many use cases and is one of the more complex ones.
> [!IMPORTANT] > [!IMPORTANT]
> You are **highly encouraged** to read the > You are **highly encouraged** to read the
full [implementation document](https://github.com/Podcastindex-org/podcast-namespace/blob/main/location/location.md) > full [implementation document](../examples/location/location.md)
before starting to code for it. This document includes rationale and example code. > before starting to code for it. This document includes rationale and example code.
### Parent ### Parent
@ -37,11 +37,12 @@ define the actual location parameters.
- **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) - **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)
> [!NOTE] > [!NOTE]
> While all elements are "recommended", **the location tag works best when all elements are populated.** The [implementation document](https://github.com/Podcastindex-org/podcast-namespace/blob/main/location/location.md) goes into more detail. An example location generator (entirely in JavaScript) is [over here](https://jamescridland.github.io/podcast-location-generator/). > 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/).
### Examples ### Examples
- A podcast *made in* [Austin TX](https://www.openstreetmap.org/relation/113314) in the US: - A podcast _made in_ [Austin TX](https://www.openstreetmap.org/relation/113314) in the US:
```xml ```xml
<podcast:location <podcast:location
rel="subject" rel="subject"
@ -52,6 +53,7 @@ define the actual location parameters.
``` ```
- A podcast about the [Birmingham Civil Rights Museum](https://www.openstreetmap.org/relation/6930627) in Birmingham, AL: - A podcast about the [Birmingham Civil Rights Museum](https://www.openstreetmap.org/relation/6930627) in Birmingham, AL:
```xml ```xml
<podcast:location <podcast:location
rel="subject" rel="subject"
@ -61,7 +63,8 @@ define the actual location parameters.
>Birmingham Civil Rights Museum</podcast:location> >Birmingham Civil Rights Museum</podcast:location>
``` ```
- A podcast *made in* [Marlow, England](https://www.openstreetmap.org/relation/3727240) - *about* [Dreamworld](https://www.openstreetmap.org/relation/16317988), a themepark in Australia: - A podcast _made in_ [Marlow, England](https://www.openstreetmap.org/relation/3727240) - _about_ [Dreamworld](https://www.openstreetmap.org/relation/16317988), a themepark in Australia:
```xml ```xml
<podcast:location <podcast:location
rel="creator" rel="creator"

Wyświetl plik

@ -25,7 +25,7 @@ The node value is a string denoting one of the following possible values:
- `audiobook` - Specific types of audio with one item per feed, or where items represent chapters within the book. - `audiobook` - Specific types of audio with one item per feed, or where items represent chapters within the book.
- `newsletter` - Describes a feed of curated written articles. Newsletter articles now sometimes have an spoken version audio enclosure attached. - `newsletter` - Describes a feed of curated written articles. Newsletter articles now sometimes have an spoken version audio enclosure attached.
- `blog` - Describes a feed of informally written articles. Similar to `newsletter` but more informal as in a traditional blog platform style. - `blog` - Describes a feed of informally written articles. Similar to `newsletter` but more informal as in a traditional blog platform style.
- `publisher` - Describes a feed that links to other feeds a publisher owns using the [`<podcast:remoteItem>`](remote-item.md) element. To understand the structure of how "publisher" feeds work, please see the dedicated document [here](../../publishers/publishers.md) and the [`<podcast:publisher>`](publisher.md) tag [here](./publisher.md). - `publisher` - Describes a feed that links to other feeds a publisher owns using the [`<podcast:remoteItem>`](remote-item.md) element. To understand the structure of how "publisher" feeds work, please [see the dedicated document](../examples/publishers/publishers.md) and the [`<podcast:publisher>` tag](publisher.md).
- `course` - A feed of training material (audio or video courses) with each item being a session or chapter of the course or conference track. - `course` - A feed of training material (audio or video courses) with each item being a session or chapter of the course or conference track.
### List Mediums ### List Mediums

Wyświetl plik

@ -4,7 +4,7 @@
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 `<podcast:remoteItem medium="publisher">` element pointing to the publisher feed. For widest compatibility, it is highly recommended to use the `feedUrl` attribute of the [`<podcast:remoteItem>`](remote-item.md) element in this capacity. 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 `<podcast:remoteItem medium="publisher">` element pointing to the publisher feed. For widest compatibility, it is highly recommended to use the `feedUrl` attribute of the [`<podcast:remoteItem>`](remote-item.md) element in this capacity.
For complete implementation details regarding publisher feeds and how to create them, please see the full publisher feed [documentation](../../publishers/publishers.md) and the `publisher` medium [here](./medium.md#medium). 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).
### Parent ### Parent

Wyświetl plik

@ -18,7 +18,7 @@ Multiple
### Attributes ### Attributes
- **protocol** (required) The [protocol](../../socialprotocols.txt) in use for interacting with the comment root post. - **protocol** (required) The [protocol](https://github.com/Podcastindex-org/podcast-namespace/blob/main/socialprotocols.txt) in use for interacting with the comment root post.
- **uri** (required) The uri/url of root post comment. - **uri** (required) The uri/url of root post comment.
- **accountId** (recommended) The account id (on the commenting platform) of the account that created this root post. - **accountId** (recommended) The account id (on the commenting platform) of the account that created this root post.
- **accountUrl** (optional) The public url (on the commenting platform) of the account that created this root post. - **accountUrl** (optional) The public url (on the commenting platform) of the account that created this root post.

Wyświetl plik

@ -4,7 +4,7 @@
This tag is used to link to a transcript or closed captions file. Multiple tags can be present for multiple transcript formats. This tag is used to link to a transcript or closed captions file. Multiple tags can be present for multiple transcript formats.
Detailed file format information and example files are [here](../../transcripts/transcripts.md). Detailed file format information and example files are [here](../examples/transcripts/transcripts.md).
### Parent ### Parent

Wyświetl plik

@ -8,7 +8,7 @@ This element may only exist within a parent [`<podcast:value>`](value.md) elemen
There is no limit on how many `valueRecipient` elements can be present in a given [`<podcast:value>`](value.md) element. There is no limit on how many `valueRecipient` elements can be present in a given [`<podcast:value>`](value.md) element.
This is a complex tag, so implementors are HIGHLY encouraged to read the companion [document](https://github.com/Podcastindex-org/podcast-namespace/blob/main/value/value.md) for a complete understanding of how this tag works and what it is capable of. 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.
### Parent ### Parent

Wyświetl plik

@ -6,7 +6,7 @@ This element designates the cryptocurrency or payment layer that will be used, t
This element can exist at either the `<channel>` or `<item>` level. When it exists at the `<item>` level, it should be treated as an "override" of whatever is defined at the `<channel>` level. This element can exist at either the `<channel>` or `<item>` level. When it exists at the `<item>` level, it should be treated as an "override" of whatever is defined at the `<channel>` level.
This is a complex tag, so implementors are HIGHLY encouraged to read the companion [document](https://github.com/Podcastindex-org/podcast-namespace/blob/main/value/value.md) for a complete understanding of how this tag works and what it is capable of. 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.
### Parent ### Parent

Wyświetl plik

@ -1,6 +1,5 @@
# Podcasting 2.0 # Podcasting 2.0
Podcasting 2.0 is a set of forward looking ideas combined with the technology to realize them. It's a vision for what the podcast listener experience can and should Podcasting 2.0 is a set of forward looking ideas combined with the technology to realize them. It's a vision for what the podcast listener experience can and should
be. That experience has stagnated for over a decade, with almost all of the improvements coming in isolated sections of the ecosystem. There hasn't been a single, be. That experience has stagnated for over a decade, with almost all of the improvements coming in isolated sections of the ecosystem. There hasn't been a single,
unified vision from the podcasting community acting together with one voice. So, we've ended up with fragments of innovation across the podcasting landscape with no unified vision from the podcasting community acting together with one voice. So, we've ended up with fragments of innovation across the podcasting landscape with no
@ -13,9 +12,6 @@ Stated eloquently, the aim of Podcasting 2.0 is this:
> >
> --Tom Rossi [Tom Rossi](https://podcastindex.social/@tomrossi7/105839063781381384) > --Tom Rossi [Tom Rossi](https://podcastindex.social/@tomrossi7/105839063781381384)
<br>
Closed ecosystems can not innovate any better or faster than open systems. We should know this by now. The open world of RSS based podcasting can not only Closed ecosystems can not innovate any better or faster than open systems. We should know this by now. The open world of RSS based podcasting can not only
keep pace with closed systems, it can exceed them easily. Podcasting 2.0 is simply the technological expression of this idea. We can make a better podcasting keep pace with closed systems, it can exceed them easily. Podcasting 2.0 is simply the technological expression of this idea. We can make a better podcasting
experience for listeners than they can get behind any walled garden - no matter how high or expensive those walls are. experience for listeners than they can get behind any walled garden - no matter how high or expensive those walls are.
@ -26,13 +22,11 @@ There are three parts to Podcasting 2.0:
2. Web app friendliness 2. Web app friendliness
3. Value for Value 3. Value for Value
<br><br>
## Step 1. Adopt the "podcast" Namespace ## Step 1. Adopt the "podcast" Namespace
To be a Podcasting 2.0 compliant podcast you need to first declare the "podcast" To be a Podcasting 2.0 compliant podcast you need to first declare the "podcast"
[namespace](https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md) in your feed if you self-host your podcast. If you [namespace](/docs/1.0.md) in your feed if you self-host your podcast. If you
use a hosting company for your podcast, check [here](https://podcastindex.org/apps) for a list of hosts that now support the new namespace. use a hosting company for your podcast, check [PodcastIndex.org/apps](https://podcastindex.org/apps) or [Podcasting2.org/apps](https://podcasting2.org/apps) for a list of hosts that now support the new namespace.
The namespace gives you (and your listeners) access to many new features: The namespace gives you (and your listeners) access to many new features:
@ -56,9 +50,6 @@ The namespace gives you (and your listeners) access to many new features:
maybe a low (or high) bandwidth version of the main audio/video file. Or, perhaps you want to deliver a version of your content over another maybe a low (or high) bandwidth version of the main audio/video file. Or, perhaps you want to deliver a version of your content over another
method like IPFS or WebTorrent. method like IPFS or WebTorrent.
<br><br>
## Step 2. Be Web App Friendly ## Step 2. Be Web App Friendly
Next, you need to confirm that your feed does not have "mixed content", and that it supports CORS where necessary. Again, if you use a hosting company for your podcast Next, you need to confirm that your feed does not have "mixed content", and that it supports CORS where necessary. Again, if you use a hosting company for your podcast
@ -81,8 +72,6 @@ requires cross-origin access, please be sure to enable the correct CORS policies
Web-based podcast apps, PWA's (Progressive Web Apps) and Browser Extension based apps are critical to Podcasting 2.0, so the above changes are very important. Web-based podcast apps, PWA's (Progressive Web Apps) and Browser Extension based apps are critical to Podcasting 2.0, so the above changes are very important.
<br><br>
## Step 3. Value for Value ## Step 3. Value for Value
The final step is monetizing your content with cryptocurrency so your listeners can support you directly with no middle-men. This allows your content to be truly free from the pressures of advertising. Advertising serves a necessary role in any free market, but it does come with a cost. That cost is censorship - whether it's direct censorship by the advertisers themselves or self-censorship as you restrict your speech as to not offend the advertisers. The final step is monetizing your content with cryptocurrency so your listeners can support you directly with no middle-men. This allows your content to be truly free from the pressures of advertising. Advertising serves a necessary role in any free market, but it does come with a cost. That cost is censorship - whether it's direct censorship by the advertisers themselves or self-censorship as you restrict your speech as to not offend the advertisers.
@ -100,4 +89,4 @@ Because of these issues, we've created a way to receive cryptocurrency payments
If you can't add the `<podcast:value>` tag to your feed manually, we also have created [a site](https://podcasterwallet.com) that can help you put a value tag directly into the Podcast Index database for your feed. Any apps that use the Podcast Index will see your value tag and be able to stream micropayments to you. If you can't add the `<podcast:value>` tag to your feed manually, we also have created [a site](https://podcasterwallet.com) that can help you put a value tag directly into the Podcast Index database for your feed. Any apps that use the Podcast Index will see your value tag and be able to stream micropayments to you.
The `<podcast:value>` tag is still early and experimental. But, it does work today. There are more details about it in this [blog post](https://blog.podcastindex.org/html/AnotherWay-lJmNWj9T490hdmPmz5M4GV1Tlw6rDF.html), and in the official [whitepaper](value/value.md). The Podcasting 2.0 community is also always willing to lend you a hand and some advice on the [podcastindex.social](https://podcastindex.social) discussion server. The `<podcast:value>` tag is still early and experimental. But, it does work today. There are more details about it in this [blog post](https://blog.podcastindex.org/html/AnotherWay-lJmNWj9T490hdmPmz5M4GV1Tlw6rDF.html), and in the official [whitepaper](docs/examples/value/value.md). The Podcasting 2.0 community is also always willing to lend you a hand and some advice on the [podcastindex.social](https://podcastindex.social) discussion server.