Closed tomrossi7 closed 1 year ago
You beat me to this Tom. This is absolutely a good idea.
Isn't this what the recommendation tag is supposed to support?
A channel is not a recommendation, but a collection of related podcasts. A podcast could belong at most to only one channel. The should be grouped together under a name as well.
a thought on naming …
channel
is a name for a dedicated XML element in the feed already. so that naming is not helpful.
a bunch of channels would e. g. be an aggregation
. this would also clarify the difference to recommendations
.
any better wording or thoughts on that maybe?
a thought on naming …
channel
is a name for a dedicated XML element in the feed already. so that naming is not helpful.a bunch of channels would e. g. be an
aggregation
. this would also clarify the difference torecommendations
.any better wording or thoughts on that maybe?
What about <podcast:related>
since that was part of Tom’s initial wording?
@tomrossi7 Do you want to write up what a tag structure would look like that you can see implementing? If you don’t have time I can take a crack at it and submit here for comments.
"bundle" could be another word to use.
But I'm still having trouble understanding what's different about this compared to recommendations/related.
But I'm still having trouble understanding what's different about this compared to recommendations/related.
I’m thinking the difference between these are our shows, ie the same network or producer vs these are things we recommend, which could be anyone’s shows? This is not to say that we can’t have it under one tag and have a field to identify things that are ‘Internal’ vs ‘external’ if that matters.
From an app perspective, I think the difference becomes how it might be shown. It’d be nice to have the option to showcase our Network shows together (similar to the channel idea or a brand page), and our recommendations to be more of a blog roll type list maybe.
@theDanielJLewis recommendations
refer to specific episodes, whereas related
refers to other shows/podcasts
I am struggling with this too. Is this meant to be a RSS way of showing podcasts that are all part of a podcast network? Or would you use it as an episode level where one might be doing a cross promo? Are there any good existing examples of where this might be used? Is it per podcast or per episode? or both?
I’m thinking the difference between these are our shows, ie the same network or producer vs these are things we recommend, which could be anyone’s shows? This is not to say that we can’t have it under one tag and have a field to identify things that are ‘Internal’ vs ‘external’ if that matters.
I like this idea. Whether is a recommended
or related
tag, let it have some kind of grouping and order. On the channel level, this could replace both "more by this artist" and also provide a more personalized "other shows you might like" list.
Having some control over the labeling and order can help differentiate these things, too. There could be standard tags, like recommended
for the related recommended shows, and withhost
or something like that for grouping other podcasts hosted or cohosted by the hosts, even if not their own.
For example, my own show would obviously list my other shows (unless I didn't want a show connected in this context), but I could also list Podcasters' Roundtable, of which I'm an official cohost but it's not my own show.
Then on the item level, the recommendations/related could be to other relevant episodes or entire shows as well. For example, if I do an episode about writing, I could link to a couple other "writing for podcasters" kinds of episodes, as well as entire shows all about writing.
EDIT: Updated with a newer proposal below.
cc: @tomrossi7 @KieranMcKeefery @eteubert @cio-blubrry @PofMagicfingers @dan
In a perfect world each podcast would have a guid. Then we could use this guid as reference instead of a URL, which may change. But the feed URL seems like a close second choice because the podcaster has a high interest in keeping that stable or at least redirecting to the current URL.
I do like the draft. Simple enough and provides enough data for the usual display of such lists.
Agreed on the UUID thing. We’re brainstorming possible solutions to that here. It’s a tough one. ☹️
Would having a thumbnail url attribute included next to the feed url attribute in podcast:relatedFeed be wise? To give apps what they need for a nice UI presentation?
cc: @MartinMouritzen @dellagustin @mitchdowney
At this part of the user journey, I would most likely just look up the podcasts through the API, so at least for my purposes a thumbnail url is not necessary here.
Its not that big of a deal, but I do like <podcast:channel>
better or possibly <podcast:network>
. If an XML parser can't properly parse namespace tags, they are bound to run into collisions even now. Related
sounds more loose a definition e.g. I mentioned Joe Rogan in one of my episodes so now I'm going to say I'm related
to his RSS feed.
I like the idea of a podcast having the option of belonging to one and only one channel or network. I don't know how we could enforce integrity, but we can at least make it part of the spec and allow aggregators the ability to invalidate feeds.
Just my 2 cents!
As far as I understood then "Channels" in the new Apple Podcasts is curated content. This would more be a way for podcasters themselves to say "I want to be associated with these other podcasts" right? (and possibly have those podcasts do the same thing)
If that's the case, then I do like
I'm really good either way on the naming. If it comes down to it, "channel" is probably a better word than "network", since large podcast networks may want to sub-categorize their shows into channels.
We could do this instead:
<podcast:channel
title="[title of this channel(string)]"
description="[a short description of the channel(string)]"
>
[one or more <podcast:channelMember> elements]
</podcast:channel>
Parent: \<rss>\<channel> (optional | single)
title
(required) - This is the title of the channel.description
(optional) - This is a short (600 characters or less) description of what this channel contains.<podcast:channelMember
url="[feed url of a related podcast(string)]"
image="[url of a thumbnail image for this podcast(string)]"
private="[true|false]"
/>
[Title of Podcast(string)]
</podcast:channelMember>
Parent: \<podcast:channel> (required | multiple)
The node value of this element is the title of the podcast being referenced. It is required and cannot be blank.
url
(required) - This is the url of a podcast feed.image
(optional) - If this attribute is present, it should be the url of an image to use for this podcast to ease the burden of querying for show art urls when an app wants to display a full channel of shows to the listener.private
(optional) - If this attribute is present, and set to "true" it tells a podcast application that this feed requires some kind of membership in order to access. If this attribute is not present or is set to "false" the feed is public.<podcast:channel title="Daniel J. Lewis">
<podcast:channelMember url="https://theaudacitytopodcast.com/sitefeed/">The Audacity to Podcast</podcast:channelMember>
<podcast:channelMember url="https://podcastersroundtable.libsyn.com/rss">Podcaster's Roundtable</podcast:channelMember>
<podcast:channelMember url="https://anchor.fm/s/a42af4/podcast/rss">Inside the Podcasting Business</podcast:channelMember>
<podcast:channel>
<podcast:channel title="Nothing But Dan" description="All the Dan Benjamin you could ever want in one place.">
<podcast:channelMember url="https://feeds.5by5.tv/b2w" image="http://icebox.5by5.tv/images/broadcasts/19/cover.jpg">Back to Work</podcast:channelMember>
<podcast:channelMember url="http://feeds.5by5.tv/roadwork" image="http://icebox.5by5.tv/images/broadcasts/89/cover.jpg">Road Work</podcast:channelMember>
<podcast:channelMember url="https://feeds.fireside.fm/podcastmethod/rss" image="https://assets.fireside.fm/file/fireside-images/podcasts/images/6/63cb6a26-1daa-48af-98a7-285e89e0f62b/cover.jpg?v=2">Podcast Method</podcast:channelMember>
<podcast:channel>
cc: @staceygoers
@daveajones I wonder if we need to duplicate any of those attributes since they can be found within the RSS feed itself. It could be as simple as below. Maybe we could have an image for the channel since that wouldn't be in any of the feeds?
<podcast:channel title="Daniel J. Lewis" image="http://icebox.5by5.tv/images/broadcasts/19/cover.jpg">
<podcast:channelMember>https://theaudacitytopodcast.com/sitefeed/</podcast:channelMember>
<podcast:channelMember>https://podcastersroundtable.libsyn.com/rss</podcast:channelMember>
<podcast:channelMember>https://anchor.fm/s/a42af4/podcast/rss</podcast:channelMember>
<podcast:channel>
As far as I understood then "Channels" in the new Apple Podcasts is curated content. This would more be a way for podcasters themselves to say "I want to be associated with these other podcasts" right? (and possibly have those podcasts do the same thing)
Not quite. That was my initial misunderstanding, too. But now, it's more about how a creator can create their own channels with their own shows, but a show can be in only one channel at a time.
For example, ESPN could bundle all their soccer podcasts in a channel, all their baseball podcasts in another channel, etc.
I apologize that I'm starting to get a little lost with some of the details. But what I see "related" as being is a podcaster-curated "you might also like" list, similar to what's in Apple Podcasts now. But with enough flexibility in the tag, the groupings could be based on whatever I want: whether my own other podcasts, podcasts that are similar to mine, or shows I recommend often that fit the interests of my audience.
I'm not so sure channel
is a better tag. What about group
or collection
?
@daveajones I wonder if we need to duplicate any of those attributes since they can be found within the RSS feed itself. It could be as simple as below. Maybe we could have an image for the channel since that wouldn't be in any of the feeds?
If we make image
optional then it can be safely left out by the hosts. API's like us could then dynamically put it back in at run time to help the apps that don't have their own infrastructure, like PWA's.
Would that work?
I like the channel image. I'll add it.
Would having a thumbnail url attribute included next to the feed url attribute in podcast:relatedFeed be wise? To give apps what they need for a nice UI presentation?
I like the idea of having the thumbnail enclosed here, it would make it simpler from the app side if the app decide to show it.
In general I like the feeds to be as self contained as possible, without depending on external APIs (of course, observing that we don't want to have a gigantic feed...).
I like the idea of having the thumbnail enclosed here, it would make it simpler from the app side if the app decide to show it.
This is a dangerous path because we are duplicating content in anticipation of how it may be used. In other words, we think the aggregator will want the title and artwork of the channel member, so we fatten up the RSS feed with information. I would rather err on the side of anticipating less and letting the aggregator decide what they want to load. The ultimate source of truth should be the channel member's RSS feed.
Not a biggie since we can make it optional, but just my 2 cents on a general "what we should and should not include in the RSS feed?".
we are duplicating content
Yeah I agree with you. If we include titles, thumbnail url, and even members, we'll have many times either broken links or out-of-date informations.
Actually, maybe it's better to move the "channel" members into it's own "channel file", using something like OPML. The RSS feeds only reference this file, and the channel data would be inside this always up-to-date file.
The tag could be :
<podcast:channel href="http://ourpodcastnetwork.com/podcast_channel.opml" />
And the clients and aggregator would check the URL to get the up-to-date podcasts links and channel infos.
Actually, maybe it's better to move the "channel" members into it's own "channel file", using something like OPML. The RSS feeds only reference this file, and the channel data would be inside this always up-to-date file.
I love OPML and have written tons of software that uses it, but I'm not sure it's the right tool for this job. It can be much more "clumsy" than RSS. I would lean toward JSON since we've already established a standard with that on the chapters side. If we're going to introduce another external file I would keep it consistent.
I can see the wisdom in an external file. It makes sense. It is, however, yet another external file to track and keep in sync. For example, what if a feed references an external channel file, but that feed itself isn't listed in the external file as being a channel member? It does become more complicated.
I would rather err on the side of anticipating less and letting the aggregator decide what they want to load. The ultimate source of truth should be the channel member's RSS feed.
I agree. We can just let the aggregators/api's take care of assembling the meta-data. Let's leave it out.
So, I guess before we refine this more, we need to make a decision about external channel file vs internal to the RSS. There are trade-offs, as always. What do we think on this? I can see wisdom in either direction.
yet another external file to track and keep in sync Well yeah, but it's not meant to change very often.
For example, what if a feed references an external channel file, but that feed itself isn't listed in the external file as being a channel member? It does become more complicated.
Here are my thoughts on it :
Of course, linking should be done on both side to be confirmed : the RSS feed links to the channel file and it is considered part of this channel, only if the channel file include the canonical link of the feed.
Other advantage of this method is that updating and adding feeds to catalogs become almost organic :
In the end I also think an external file is better because it's an ultimate source of truth. If we include the whole network list on each feeds, what do we do when the list isn't the same on each feed ?
If the list isn't meant to be consistent between members of the channel, it's true it's more of a recommended feeds tags.
To me, an external file seems like overkill since all we are listing are the channel members RSS feeds. Even for a large channel, you aren't talking about adding too many lines. If the feed were an object, the other channel members would be an array attribute of RSS feeds. Its definitely not an easy black-and-white and I could go either way!
Well I agree the file is kind of ridiculous because it will only be a list of urls. But If we include in this file all channel metadata it could be more than a list : channel name, images, persons, podcast members etc.
The main argument for the external file is : reducing requests by having a single source of truth, it might seem overkill because it's another file, but it's solving a lot of problems
If we include channel members inside the RSS feed, if your app wants to list members of the channel, they will actually have to check all mentionned members to check whether they are or not really included in the channel. And with multiple feeds referencing themselves, what will we do if you have a missing or added feed ? What if a feed is not updated and link to an old rss feed url ?
What if a feed is not updated and link to an old rss feed url ?
I'm guessing this is really internal to the hosting platform. If the host assembles the channel data to include in the RSS feed, it will probably be doing it based on it's own internal podcast ID's, so it could ensure that the feed url in the channelMember is always fresh.
Well I agree the file is kind of ridiculous because it will only be a list of urls. But If we include in this file all channel metadata it could be more than a list : channel name, images, persons, podcast members etc.
Yeah, I just don't know if there will be a lot of metadata at the channel level? Even a channel image is possibly a stretch. Images? Persons? Those seem like they belong on the individual feeds themselves. Creating a separate file would definitely provide room to grow, I just don't know if we'll need it. 🤷♂️
If we include channel members inside the RSS feed, if your app wants to list members of the channel, they will actually have to check all mentionned members to check whether they are or not really included in the channel.
Maybe? But if you wanted to check that a feed really belonged to a channel, wouldn't you do that with the external file as well? Grab each RSS feed and see if it truly belongs to the channel?
what will we do if you have a missing or added feed ? What if a feed is not updated and link to an old rss feed url ?
You still have the same issue with an external file. What if the feed references a channel that doesn't actually include the feed? What if the channel file references an RSS feed that that is broken?
Again, I really could go either way. I just usually tend towards simplicity when one path isn't obviously better.
really internal to the hosting platform
Of course that's really easy to do for hosting platforms with some code. However it doesn't change the fact it's duplicated data. If one change, all caches for all feeds have to be pruned.
Also IMHO we're building a standard for hosting platforms, but also for nerdy people who will make XML files by hand, or people using Wordpress with plugins... Many of those people could potentially let a channel list become out of date.
Also it can be possible not every podcasts from a channel is from the same hosting platform. For example, if the channel list is included in the feeds of 3 wordpress blogs, it's 3 places to update for each change.
@snookfin is convincing me the external file is better. His position is that we would want to include lots of possible meta data about the channel itself.
You still have the same issue with an external file
Yeah, you're right. After thinking more about it, and reading your thoughts on it, I agree either included or via an external file you have the same kind of issues... :slightly_frowning_face:
Well it's seems the real advantages to an external file are :
EDIT:
So, would we say that the tag itself would look something like this then?
<podcast:channel
url="http://example.org/eip/channel.json"
image="http://example.org/eip/channelart.jpg"
>
Excellence in Podcasting Network
</podcast:channel>
@daveajones I think we should do like transcripts and chapters:
<podcast:channel url="https://example.com/my_channel.json" type="application/json+channel" />
Any aggregator that wants to make use of the channel data can pull down the channel file and that is where they could grab images, etc.
@snookfin had a good idea for how we could keep people from throwing Rogan in their channel: we could make it so any podcast listed in the channel has have a reciprocal link in their RSS feed. That could cut out the potential for abuse.
we could make it so any podcast listed in the channel has have a reciprocal link in their RSS feed. That could cut out the potential for abuse.
Yeah, exactly. As we were saying when agregators, apps, etc update the feed they have to check if the canonical feed url is inside the channel file to confirm. And they should fetch other feeds for channel to confirm they're really part of the network. That leads to many requests, but with caching, paralleling, and lazy queries it should be okay.
That leads to many requests
What I would do on the PI API is just resolve all of that stuff before hand and hand it back in the results. That would give apps all that they need in a single query. It'll be a lot of code, but it's the right way to do it.
So, I guess the question now is what the external file format should look like. Any ideas?
Lego Benny voice:
😎
I’ll start working on a format.
I like the way this is progressing. Let me throw out some ideas for consideration.
First I think we should consider creating a <podcast:guid>
that would be a simple Base64 encoding of the podcast's original feed URL. When a new podcast is created, a new <podcast:guid>
should be created along with it (it would live at the channel level in the RSS feed). If a podcast is just changing its feed URL, moving from one host to another, the <podcast:guid>
would not change. Hosting companies already respect the episode guid at the item level, so I don't anticipate any pushback here.
This will be really helpful down the road (think subscriptions), but I think we should intro it now to make show associations easier for app and index developers.
The next concept I would offer is using two separate tags for channels (define and declare).
The first tag defines a channel:
<podcast:channel url="http://example.org/eip/channel.json" type="application/json+channel">Name of Channel</podcast:channel>
The second declares your membership in a channel:
<podcast:channelMember id="aHR0cDovL2V4YW1wbGUub3JnL2VpcC9jaGFubmVsLmpzb24=" />
The proper syntax to define a channel must include both tags (this expresses our opinion that you should not define channels that you are not a member of, each channel has one defining authority, and podcasts cannot be members of multiple channels). If a podcast declares membership in multiple channels, we treat this like any other conflicting tag; the last declaration wins. Both tags have to match for a valid channel to be recognized. Only the <podcast:channelMember>
tag is needed to declare membership.
I think we should follow Apple's guidance on artwork and add a few things to make channel management easy for app devs.
Channel
Shows
<podcast:guid>
for the member show)Within the Channel JSON, I would avoid any member or "show" attributes that could be derived from parsing the RSS feed. So I would only have one field for each show: the RSS feed. The consumer of the content could pull the RSS feed to get the title, the id, or anything else they may want to know about the channel member. Otherwise it becomes a slippery slope of putting more information in the Channel JSON in anticipation of how consumers of the content may use it. For example, why not include a count of the number of episodes? Or the last published episode date? These could be derived by pulling down the RSS feed, so lets leave them out of the Channel file. My 2 cents!
@daveajones you want me to use @snookfin's proposal and propose the tags?
Within the Channel JSON, I would avoid any member or "show" attributes that could be derived from parsing the RSS feed. So I would only have one field for each show: the RSS feed.
I get the slippery slope, but that doesn't mean there aren't legitimate use cases we can accommodate. If you need to remove a show from your channel and there are 10 feeds listed, how do you know which one to remove without loading up RSS feeds until you find the right one? What if you want to rearrange the order because some apps display them in the order you specify in your JSON?
The ID may be less helpful, but I was thinking as an app developer it would be nice to check my system for that ID first before having to hit the feed URL. Also, feed URLs change, but the IDs do not. Again, I was thinking this could make things easier for app/index devs but If not we can drop it.
Again, I was thinking this could make things easier for app/index devs but If not we can drop it.
I think we can hit a happy medium where we include a tiny bit of data (like maybe title) to accomodate some ease of use without going crazy and loading it up. Title is something that so rarely changes. (CNN Sanjay Gupta show being a rare example).
First I think we should consider creating a
<podcast:guid>
that would be a simple Base64 encoding of the podcast's original feed URL. When a new podcast is created, a new<podcast:guid>
should be created along with it (it would live at the channel level in the RSS feed). If a podcast is just changing its feed URL, moving from one host to another, the<podcast:guid>
would not change. Hosting companies already respect the episode guid at the item level, so I don't anticipate any pushback here.
I keep coming back to a fixed value here to make DB storage more predictable. In the podping repo, @agates suggested using a UUIDv5, which seems fine to me. Either that, or a sha-1 hash of the original feed url would give fixed length output instead of a base64-url which is variable in size. If the feed url ever changes, then you lose the reverse conversion anyway.
Thoughts?
The feed url change bit can be accommodated in other ways right? A tag that shows this feed used to be “ “ and can be a series if someone really changes hosts that often. What purpose does it serve? Little from a podcast player, but it keeps a log for the creator or perhaps someone who wants to report on it (podnews or I can see a tiny case within our reporting).
The base GUID as has been suggested never changes and moves along when you a) import into a new provider but b) can also be tested against the index if a provider allows creators to map manually to an existing show (which is when the “used to be at” tag would be added for example.
The proper syntax to define a channel must include both tags (this expresses our opinion that you should not define channels that you are not a member of, each channel has one defining authority, and podcasts cannot be members of multiple channels).
I get why this is the default (and why Apple has gone this way too) but I can see a use case where podcasts can want to belong to multiple channels. A network may want to bundle something by type, say a tech channel and a business channel but have a show that fits under both. I’m thinking more of a discovery use case over just a subscription one; where a creator might want to have multiple bundles by interest and have overlap. I think the market will eventually deter creators from trying to ‘double bill’ someone for the same shows, even if there is a small subset who try to misuse this.
Alternative use case can be me having a network-bundle but also a personal one where I want to share a show I host under a Network (with each channel still having one defining authority). So the idea of a podcast living in more than one channel is an expansion I think we should consider, even if it’s not implemented in the first version of this tag.
Just for the sake of completeness :-)
I love OPML and have written tons of software that uses it, but I'm not sure it's the right tool for this job. It can be much more "clumsy" than RSS. I would lean toward JSON […]
There is also an JSON variant of OPML... :-)
The base GUID as has been suggested never changes and moves along when you a) import into a new provider but b) can also be tested against the index if a provider allows creators to map manually to an existing show (which is when the “used to be at” tag would be added for example.
So it sounds like we’re settling on something like this at the channel level:
<podcast:guid>85768a82-3f41-50cb-a95e-52a7ff392de8</podcast:guid>
Where this guid value would be a v5 uuid derived from the “url” namespace and the feed url itself as a utf8 string.
This is something that the hosting provider would embed in the feed at creation time. If it’s an imported/moved feed, the hosting provider would just record the existing one instead of generating a new one.
Do we think that would work? If so I’ll create a new proposal for it and we can move forward with the actual channel spec.
A few thoughts after having seen a lot of feeds...
Some podcast hosts like Libsyn (or Podnews!) give different services different RSS feeds.
https://thefeed.libsyn.com/spotify
is the feed for, um, The Feed, for Spotify.https://thefeed.libsyn.com/rss
is their normal feed.They are the same show, but different URLs (and the feeds can look rather different, since they can use specific namespaces, as in this example).
Clearly both these produce different GUIDs. How would that work?
Libsyn is a good use-case here, actually, since a few years ago they were still using http:// feeds (and offering both, as different URLs). If following this spec, I'd hope that they would have initially set their GUIDs based on the http:// versions, and not changed them when they force-forwarded people to https://.
Second, and I know this is a little out of scope here, but... Renegades: Born In The USA on Spotify. That doesn't have an RSS feed. Is that NOT A PODCAST BURN THE HERETIC WE DON'T CARE or is there another option here?
https://podnews.net/podcast/i95pi is a link to that show; the 95pi
bit is the internal ID in my own database (using base 36 to keep the length down). I did consider using an ID based on the RSS feed, as Google Podcasts does, but ended up not doing so precisely because I wanted to also be able to link to shows like this one.
Third, what happens with private RSS feed URLs here - are they also BURN THE HERETIC or is there a consideration for these types of shows?
Some podcast hosts like Libsyn (or Podnews!) give different services different RSS feeds.
https://thefeed.libsyn.com/spotify
is the feed for, um, The Feed, for Spotify.https://thefeed.libsyn.com/rss
is their normal feed.They are the same show, but different URLs (and the feeds can look rather different, since they can use specific namespaces, as in this example).
Clearly both these produce different GUIDs. How would that work?
My 2cts on this : those 2 feeds are the same feed, one is canonical, one is a specific usage. Maybe the spotify feed should include the guid of the canonical feed ? It could prevent duplicates.
But it raises questions : How do we know which feed is canonical ?
And this question is relevant even in the specific use case of the proposal : imagine you're thinking about changing hosting provider, you go and try importing your feed on two other services, but you don't really have time, and postpone the move. Or you move to one of them, but forget to delete the test feed from the other one.
How does a podcast directory knows which RSS feed is the one ? It's really hard to create a unique identifier in a decentralized technology. You always wonder which source to trust
One of Apple's features is the grouping of podcasts into a channel. I kind-of like this idea and wonder if we could incorporate a way to do this within the RSS feed. Perhaps, we provide a
podcastChannel
tag that uniquely identifies the channel? Or arelatedPodcasts
tag that points to a JSON of all the related RSS feeds?