Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: <podcast:alternateEnclosure> update #174

Closed
agates opened this issue Feb 1, 2021 · 40 comments
Closed

Proposal: <podcast:alternateEnclosure> update #174

agates opened this issue Feb 1, 2021 · 40 comments
Labels
proposal An idea for a new tag

Comments

@agates
Copy link
Contributor

agates commented Feb 1, 2021

This tag is a named collection of different transports available to acquire a single type of media. There can be multiple as needed, to provide media encoded in different ways or provided by different means of transport.

This is designed to provide sufficient information to the podcast player to be able to determine what type of media it supports along with the transports available to acquire it. At the same time, sufficient information should be provided to be able to allow sane defaults or preferences presented to the user.

For example, one podcast player might only support audio, but can play it in various different codecs such as OPUS, AAC, MP3, etc. Another may support video, but only video in h264 format.

If desired, media related to the enclosure -- but which does not have the same content -- can be provided. Perhaps a "bloopers" take, or the same episode in a different language.

Lastly, I propose optional information to verify integrity of downloaded media via hashes or maybe even PGP signatures. Obviously, PGP verification would require the podcast application to separately import trusted public keys to be useful. Adhering to the Subresource Integrity standard will help here for hashes.

EDIT: I also didn't include this on the Channel primarily because I like the idea proposed in #77 to allow an item to be included at the channel level. But I'm not against having this at the Channel level, either.

  • <podcast:alternateEnclosure type="[mime type]" length="[(int)]" bitrate="[(float)]" height="[(int)]" lang="[(string)]" rel="[(string)]" codecs="[(string)]" default="[(boolean)]"> ... </podcast:alternateEnclosure>
    Item (optional | multiple)

    This element defines a media file. One or more <podcast:source> tags must be contained within this element to list available methods to obtain the file. This is meant to provide different versions of a media file -- such as low or high bitrate, alternate formats (different codecs or video), alternate URI schemes (IPFS or live streaming), or alternate download types not indicated by the URI and type (like torrents).

    The "rel" attribute is meant to allow presentation of media different from the main content given in the enclosure. For example, "director's cut" or "behind the scenes". If you are only offering one media content (say, a podcast in MP3, AAC, Opus, over HTTPS and IPFS), you can likely ignore the "rel" attribute.

    The media element always refers to an available media version. The standard RSS enclosure element is always the default media to be played.

    An <enclosure> tag must be present along with this tag within the item.

    • type (required) Mime type of the media asset.
    • length (required) Length of the file in bytes.
    • bitrate (optional) Encoding bitrate of media asset.
    • height (optional) Height of the media asset for video formats
    • lang (optional) An IETF language tag (BCP 47) code identifying the language of this media.
    • rel (optional) Provides a method of offering and/or grouping together different media elements. If not set, or set to "default", the media will be grouped with the enclosure and assumed to be an alternative to the enclosure's encoding/transport. This attribute can and should be the same for items with the same content encoded by different means. Should be limited to 32 characters for UX.
    • codecs (optional) A RFC 6381 string specifying the codecs available in this media.
    • default (optional) Boolean specifying whether or not the given media is the same as the file from the enclosure element and should be the preferred media element. The primary reason to set this is to offer alternative transports for the enclosure. If not set, this should be assumed to be false.
  • <podcast:source uri="[uri of media asset]" contentType="[mime type]" />

    podcast:alternateEnclosure (required | multiple)

    This element defines available transport methods to obtain media, such as HTTP, HTTPS, IPFS, Tor, magnet, etc, via alternate URI schemes and content types if the <podcast:alternateEnclosure> content type does not suffice, such as torrent or stream files.

    There should be one or more source elements in a media tag.

    • uri (required) This a an IANA-registered URI for the media asset.
    • contentType (optional) Mime type of the data retrieved from the URI, if different from the media's "type"
  • <podcast:integrity type="[integrity type]" value="[integrity value]" />

    podcast:alternateEnclosure (optional | multiple)

    This element defines a method of verifying integrity the media given either an SRI-compliant integrity string or a base64 encoded PGP signature.

    There may be one or more integrity elements in a media tag.

    • type (required) Type of integrity, either "sri" or "pgp-signature".
    • value (required) Value of the sri string or base64 encoded pgp signature.

Example of content served via audio in mp3, high-bitrate Opus, "hi-fi" AAC, low-bitrate Opus -- over both HTTPS and IPFS:

<enclosure url="https://best-podcast.com/file-0.mp3" length="43200000" type="audio/mpeg" /> 

<podcast:alternateEnclosure type="audio/mpeg" length="43200000" bitrate="128000" default="true">
    <podcast:source uri="https://best-podcast.com/file-0.mp3" />
    <podcast:source uri="ipfs://someRandomMpegFile" />
</podcast:alternateEnclosure>

<podcast:alternateEnclosure type="audio/opus" length="32400000" bitrate="96000">
    <podcast:source uri="https://best-podcast.com/file-high.opus" />
    <podcast:source uri="ipfs://someRandomHighBitrateOpusFile" />
</podcast:alternateEnclosure>

<podcast:alternateEnclosure type="audio/aac" length="54000000" bitrate="160000">
    <podcast:source uri="https://best-podcast.com/file-proprietary.aac" />
    <podcast:source uri="ipfs://someRandomProprietaryAACFile" />
</podcast:alternateEnclosure>

<podcast:alternateEnclosure type="audio/opus" length="5400000" bitrate="16000">
    <podcast:source uri="https://best-podcast.com/file-low.opus" />
    <podcast:source uri="ipfs://someRandomLowBitrateOpusFile" />
</podcast:alternateEnclosure>

Example of content served via audio (mp3) and video in different resolutions (mp4) with dynamic streaming options:

<podcast:alternateEnclosure type="audio/mpeg" length="2490970" bitrate="160707.74">
    <podcast:source uri="https://best-podcast.com/file-0.mp3" />
    <podcast:source uri="ipfs://QmdwGqd3d2gFPGeJNLLCshdiPert45fMu84552Y4XHTy4y" />
    <podcast:source uri="https://best-podcast.com/file-0.torrent" contentType="application/x-bittorrent" />
    <podcast:source uri="http://somerandom.onion/file-0.mp3" />
</podcast:alternateEnclosure>

<podcast:alternateEnclosure type="video/mp4" length="10562995" bitrate="681483.55" height="1080">
    <podcast:source uri="https://best-podcast.com/file-1080.mp4" />
    <podcast:source uri="ipfs://QmfQKJcp2xdByEt8mzWr1AJUhwvb9rdWPoacvdq2roDhgh" />
    <podcast:source uri="https://best-podcast.com/file-1080.torrent" contentType="application/x-bittorrent" />
    <podcast:source uri="http://somrandom.onion/file-1080.mp4" />
</podcast:alternateEnclosure>

<podcast:alternateEnclosure type="video/mp4" length="7924786" bitrate="511276.52" height="720">
    <podcast:source uri="https://best-podcast.com/file-720.mp4" />
    <podcast:source uri="ipfs://QmX33FYehk6ckGQ6g1D9D3FqZPix5JpKstKQKbaS8quUFb" />
    <podcast:source uri="https://best-podcast.com/file-720.torrent" contentType="application/x-bittorrent" />
    <podcast:source uri="http://somrandom.onion/file-720.mp4" />
</podcast:alternateEnclosure>

<podcast:alternateEnclosure type="video/mp4" length="6081197" bitrate="392335.29" height="480">
    <podcast:source uri="https://best-podcast.com/file-480.mp4" />
    <podcast:source uri="ipfs://QmQHNcr88kHp2ieNQYcBRczM7XpMtjRSQcLek6CaJwd81m" />
    <podcast:source uri="https://best-podcast.com/file-480.torrent" contentType="application/x-bittorrent" />
    <podcast:source uri="http://somrandom.onion/file-480.mp4" />
</podcast:alternateEnclosure>

<podcast:alternateEnclosure type="video/mp4" length="4086007" bitrate="327833.03" height="360">
    <podcast:source uri="https://best-podcast.com/file-360.mp4" />
    <podcast:source uri="ipfs://QmeK3EQMuV6cR766kuyG2QUUEJqUVfkJKGPNRceXzXC3ED" />
    <podcast:source uri="https://best-podcast.com/file-360.torrent" contentType="application/x-bittorrent" />
    <podcast:source uri="http://somrandom.onion/file-360.mp4" />
</podcast:alternateEnclosure>

<podcast:alternateEnclosure type="video/mp4" length="2490970" bitrate="263613.35" height="240">
    <podcast:source uri="https://best-podcast.com/file-240.mp4" />
    <podcast:source uri="ipfs://QmdjB94TUMSQu1P8QvPnGnPjNLiWycjtraSaCsiVi4xUNi" />
    <podcast:source uri="https://best-podcast.com/file-240.torrent" contentType="application/x-bittorrent" />
    <podcast:source uri="http://somrandom.onion/file-240.mp4" />
</podcast:alternateEnclosure>
<podcast:alternateEnclosure type="application/x-mpegURL" length="10562995">
    <podcast:source uri="https://best-podcast.com/master.m3u8" />
    <podcast:source uri="ipfs://exampleLinkThatDoesntWorkHLS" />
    <podcast:source uri="http://somerandom.onion/master.m3u8" />
</podcast:alternateEnclosure>

<podcast:alternateEnclosure type="application/dash+xml" length="10562995">
    <podcast:source uri="https://example.com/master.mpd" />
    <podcast:source uri="ipfs://exampleLinkThatDoesntWorkDASH" />
    <podcast:source uri="http://somerandom.onion/master.mpd" />
</podcast:alternateEnclosure>

Example use of the "rel" attribute offering "Behind the Scenes" content:

<podcast:alternateEnclosure type="audio/mp4" length="2490970" bitrate="160707.74" rel="Behind the Scenes">
    <podcast:source uri="https://example.com/file.mp4" />
    <podcast:source uri="ipfs://exampleLinkThatDoesntWork" />
</podcast:alternateEnclosure>

<podcast:alternateEnclosure type="video/mp4" length="10562995" bitrate="681483.55" height="1080" rel="Behind the Scenes">
    <podcast:source uri="https://example.com/video.mp4" />
    <podcast:source uri="ipfs://exampleLinkThatDoesntWorkVideo" />
</podcast:alternateEnclosure>

<podcast:alternateEnclosure type="application/x-mpegURL" length="10562995" rel="Behind the Scenes">
    <podcast:source uri="https://example.com/master.m3u8" />
    <podcast:source uri="ipfs://exampleLinkThatDoesntWorkHLS" />
</podcast:alternateEnclosure>
@daveajones
Copy link
Contributor

This is an excellent write up Alecks. I’ll translate it into a formal proposal that takes the place of alternateEnclosure and put into the readme as I do the phase 2 finalization work this week.

@agates
Copy link
Contributor Author

agates commented Feb 1, 2021

Dave, do you think it would be useful to recommend or provide a place to put one or more public keys on the Channel?

The flow would look like:

  1. User subscribes to podcast
  2. Podcast channel contains a public key
  3. User's podcast app is configured to check PGP signatures where possible
  4. Podcast app sees the public key on subscribe and asks the user to import and trust the key
  5. Media with a PGP signature will be verified with the key

@jamescridland
Copy link
Contributor

I do like this proposal. Thoughts:

"An tag must be present along with this tag within the item."

  • but do we also list the same audio file that we've listed in the tag? And how does the client know which is the one that's also in the enclosure tag?

The title tag needs to be explicit that it's humanly-readable, and we need a maximum length for it, which I'd like to suggest is 16 or 32 characters for UX purposes. Similar for the rel tag.

I still don't quite understand why we're changing the name from alternateEnclosure. It is an alternate enclosure, surely?

@saerdnaer
Copy link
Contributor

saerdnaer commented Feb 2, 2021

I think this proposal should reuse existing vocabulary from the HTML5 audio/video tag (e.g. podcast:source instead of podcast:mediaTransport),
and provide a more realistic (audio) example, e.g. only MP3, MP4, HLS, DASH, IPFS

@jamescridland
Copy link
Contributor

I've also asked Thomas Barrasso to take a look at this. He runs PodLP, the most popular podcast app on KaiOS, a mobile phone OS that's in use in many developing countries. PodLP has more than 4 million installs, and I suspect a low-bitrate version would be a great plan for those listeners.

@daveajones
Copy link
Contributor

That’s a great idea James.

As far as naming goes, this is a namespaced element. Why don't we just call it <podcast:enclosure>. We don’t have to worry about name collisions.

@agates
Copy link
Contributor Author

agates commented Feb 2, 2021

I just called it something that made the most semantic sense to me -- to my non-podcast brain that's what I came up with (really I kept thinking wtf is an enclosure?)

But it doesn't matter to me much one way or another.

@agates
Copy link
Contributor Author

agates commented Feb 2, 2021

I think this proposal should reuse existing vocabulary from the HTML5 audio/video tag (e.g. podcast:source instead of podcast:mediaTransport),

I like this.

provide a more realistic (audio) example, e.g. only MP3, MP4, HLS, DASH, IPFS

The point of keeping this generic enough was there is not just one realistic use case, but alas I only pulled from something I had to work with -- wanted to take something that's not podcast RSS and see what it would take to add it.

As long as Dave can wrangle around the different possibilities, maybe a few examples for some theoretical scenarios can be produced

@agates
Copy link
Contributor Author

agates commented Feb 2, 2021

I do like this proposal. Thoughts:

"An tag must be present along with this tag within the item."

  • but do we also list the same audio file that we've listed in the tag? And how does the client know which is the one that's also in the enclosure tag?

As far as I'm concerned (again I have no dog in this fight, don't crucify me), the enclosure tag is there for backwards compatibility. Maybe an optional default attribute could be added to tell the client "this is the same as the enclosure."

The title tag needs to be explicit that it's humanly-readable, and we need a maximum length for it, which I'd like to suggest is 16 or 32 characters for UX purposes. Similar for the rel tag.

Agreed

@Tombarr
Copy link

Tombarr commented Feb 2, 2021

I've also asked Thomas Barrasso to take a look at this. He runs PodLP, the most popular podcast app on KaiOS, a mobile phone OS that's in use in many developing countries. PodLP has more than 4 million installs, and I suspect a low-bitrate version would be a great plan for those listeners.

I think this proposal definitely has value. As far as PodLP is concerned, dynamically selecting an appropriate bitrate based on network speeds is a great idea and is something already supported by file formats like M3U. Some hosts like iono.fm already offer this both manually (by adjusting a URL query parameter) and automatically based on User-Agent detection.

As far as naming conventions, I'd recommend not using podcast:enclosure. Many poorly written XML parsers for podcast feeds disregard namespaces altogether.

rel is a bit confusing, why not have it be an enum like the HTML rel attribute? It's probably difficult to enumerate all possibilities, but otherwise won't it feels like a duplicate of title?

For mediaVerification, why not go for consistency with the integrity attribute that is part of the Subresource Integrity (SRI) specification? It doesn't add much value to web-based streaming services since calculating a hash client-side would require downloading the entire audio file, and I suspect podcast hosts with DAI wouldn't bother with this.

@agates
Copy link
Contributor Author

agates commented Feb 2, 2021

I think this proposal definitely has value. As far as PodLP is concerned, dynamically selecting an appropriate bitrate based on network speeds is a great idea and is something already supported by file formats like M3U. Some hosts like iono.fm already offer this both manually (by adjusting a URL query parameter) and automatically based on User-Agent detection.

Yes, this will allow any kind of streaming option, be it M3U, HLS, DASH, or some future protocol. Just needs a supported MIME type and source file.

As far as naming conventions, I'd recommend not using podcast:enclosure. Many poorly written XML parsers for podcast feeds disregard namespaces altogether.

Does podcast:media make sense to you? The podcast:alternateEnclosure makes sense until this has the possibility of being used outside of an element that has an enclosure tag, and I was trying to account for that.

rel is a bit confusing, why not have it be an enum like the HTML rel attribute? It's probably difficult to enumerate all possibilities, but otherwise won't it feels like a duplicate of title?

The purpose of rel is to group together the same content... so if you had the same episode but in Spanish, all of the different files in the Spanish version would look like this:

title="Audio" rel="Spanish"
title="Audio (low bandwidth)" rel="Spanish"
title="Stream (auto bandwidth)" rel="Spanish"

Definitely open to changing the name of this, I just used what was previously in podcast:alternateEnclosure. It could be separated out into it's own tag also, like most things XML, but I felt it didn't warrant that.

For mediaVerification, why not go for consistency with the integrity attribute that is part of the Subresource Integrity (SRI) specification? It doesn't add much value to web-based streaming services since calculating a hash client-side would require downloading the entire audio file, and I suspect podcast hosts with DAI wouldn't bother with this.

I like this a lot, and integrity could still be useful for validating the download of .m3u, m3u8, or .mpd stream files for example. My only concern is SRI doesn't appear to support PGP, which I think could be a useful feature for some podcasts (admittedly a low percentage).

@daveajones daveajones added the proposal An idea for a new tag label Feb 2, 2021
@jamescridland
Copy link
Contributor

The purpose of rel is to group together the same content... so if you had the same episode but in Spanish, all of the different files in the Spanish version would look like this:

However we do this, I'd like to ensure that things are programmatically readable - so that a podcast app being used on a Spanish-language phone, as one example, can know to choose the correct audio. So if one proposal is to offer different language versions here, please let's use the ISO 639-1 standard language codes - so some form of rel="alternate" lang="es-mx" thing, so we can signal to the app that this is NOT the same audio (rel="alternate") and that it's in Mexican Spanish (lang="es-mx").

@agates
Copy link
Contributor Author

agates commented Feb 3, 2021

The purpose of rel is to group together the same content... so if you had the same episode but in Spanish, all of the different files in the Spanish version would look like this:

However we do this, I'd like to ensure that things are programmatically readable - so that a podcast app being used on a Spanish-language phone, as one example, can know to choose the correct audio. So if one proposal is to offer different language versions here, please let's use the ISO 639-1 standard language codes - so some form of rel="alternate" lang="es-mx" thing, so we can signal to the app that this is NOT the same audio (rel="alternate") and that it's in Mexican Spanish (lang="es-mx").

Hmm, maybe language is a bad example for rel, I was thinking lang should have its own attribute anyway.

@agates
Copy link
Contributor Author

agates commented Feb 4, 2021

Updated the original post, added some suggestions, cleared up the examples a bit.

@douglaskastle
Copy link
Contributor

Is it possible to add bittorrent magnets or just the CID for IPFS? I know they are not actually http links (which the RSS standard i think is only supposed to accept)

Also I assumed that a there would also be space for a youtube link. I release a video version of my podcast on youtube, it is the same podcast from an audio perspective, i don't see why in this case it wouldn't be a valid alternate enclosure (which this is recommended to replace)

Finally a lot of people are mentioning the power of this tag for multiple versions of the same audio file, but at lower bitrates. There was talk of bitrate peeling being introduced into the Vorbis specification (used in ogg files):

https://en.wikipedia.org/wiki/Bitrate_peeling

I was disappointed to find out it was never fully implemented, maybe an appropriate use case to push it through never really materialised.

@agates
Copy link
Contributor Author

agates commented Mar 1, 2021

Is it possible to add bittorrent magnets or just the CID for IPFS? I know they are not actually http links (which the RSS standard i think is only supposed to accept)

As of RSS 2.0, any IANA-registered URI scheme is allowed. I will rename "URL" to "URI" to make it clear it can support any kind of URI and link to the IANA register.

This will allow support of both magnet links and IPFS/IPNS, as well as anything else in the register.

Also I assumed that a there would also be space for a youtube link. I release a video version of my podcast on youtube, it is the same podcast from an audio perspective, i don't see why in this case it wouldn't be a valid alternate enclosure (which this is recommended to replace)

My only concern with this is the client is expected to be able to download the media directly from the URI and play it with no other information. To support youtube under this tag, a client would need to bundle something like youtube-dl.

I'm not against having alternative sources but I feel it goes beyond media files and may belong to its own tag on the item. Something like...
<podcast:alternativeSource>https://youtube.com/example</podcast:alternativeSource>

Finally a lot of people are mentioning the power of this tag for multiple versions of the same audio file, but at lower bitrates. There was talk of bitrate peeling being introduced into the Vorbis specification (used in ogg files):

https://en.wikipedia.org/wiki/Bitrate_peeling

I was disappointed to find out it was never fully implemented, maybe an appropriate use case to push it through never really materialised.

Both HLS (.m3u8 files) and DASH (.mpd files) support similar functionality and are included in the examples already :).

@douglaskastle
Copy link
Contributor

My only concern with this is the client is expected to be able to download the media

Well this is potentially the problem with replacing words alternate enclosure with media, at least conceptually. I would assume that alternate enclosure is a valid type for youtube, but maybe not for media. Ultimately we are moving into a streaming world and in that case I think it is a valid media type. But you are right, youtube is not downloadable natively.

I suppose it depends on how dogmatic we want to be on media, I know @daveajones has mentioned the problem for certain words being picked, but their eventual usage may not track exactly with where they end up being used. If media is a word that is too baised, maybe it isn't appropriate.

Maybe there is only one media file per episode and everything else is an alternate source?

@saerdnaer
Copy link
Contributor

Just a short comment:
I personally find length always a little confusing if it is the duration or filesize – can we change it to size for the new tags?

@jamescridland
Copy link
Contributor

Maybe there is only one media file per episode and everything else is an alternate source?

@douglaskastle I'd suggest that this is likely to be the case in reality. The main media file is the <enclosure>, since non-podcast-namespace apps will always choose this one. The alternate sources are only available to apps that support the podcast namespace.

the client is expected to be able to download the media

@agates I don't think that's a requirement here. Podcasts don't need to be downloaded; they can quite successfully be streamed (and arguably the 'download' model for podcasting is partially a function of age - it was the only possible way to get hold of media in the era of slow download speeds).

I think these are pointers to alternate sources of the same content - different bitrates/codecs, or with video, or something else. But if there's a way to identify a stream, or even a pseudo-mime-type like a 'video/youtube', or something else, I don't see that as being an issue. If the client can ignore the ones it can't deal with, that's cool.

I'm still quite keen that "this podcast but in Spanish" is dealt with in a different way. This is a different proposal, I think - and it seems to me that you could do so using a LINK REL in the standard way at the top of the file, in a similar way to HTML, which works like...

<link rel="alternate" hreflang="lang_code" href="url_of_page" />

After all, if the podcast is in Spanish, so will the artwork, description, etc etc, be. You'll want to point someone off to a different RSS feed in that language, I would suspect.

@agates
Copy link
Contributor Author

agates commented Mar 2, 2021

For clarification, when I say download, I mean it only in the sense of using a network connection to receive data -- not whether or not the app does it ahead of time, saves it to the disk, etc. (Not saying one use of the word is right or wrong, but I see how that can be confusing)

I can see the value in having a sort of YouTube metatype, but on the other hand I can see value in presenting it as an alternative platform for the user to navigate to and not just an alternative source of media -- the idea being YouTube offers a lot more and the user might want to actually open it open in their browser, for example. I've done this to view comments before.

That is the distinction I see between files to play and wholly alternative hosts with their own ecosystem -- the app could still see this as YouTube and offer to download/stream it, no argument there.

That said, now I'm thinking maybe this should just be alternateEnclosure to avoid confusion.

As for the language and size, I'm going to defer that to @daveajones :)

@PofMagicfingers
Copy link
Contributor

I can see the value in having a sort of YouTube metatype

Why not using the podcast:id tag at item level for this. We could link to the episode in a specific platform/website.

@daveajones
Copy link
Contributor

daveajones commented Mar 2, 2021

I don’t want to get too bogged down in what we call it. Ultimately, what it is called is really just marketing. HTML has the tag <a> which is a link. Nobody today knows that it is an “anchor” tag. They just know that is how you define links.

I still think it makes sense to call it simply <podcast:enclosure>, which carries the same clear meaning as the base-level tag. But that’s just me.

I think we need to pick a couple of main use cases for this tag to address initially (the ones causing the biggest pain points today) and one side case. That will be enough to spur adoption. We can always then extend the spec later to add a new attribute to it if we see that it needs to capture a new use case it can’t handle.

On that note, I think these are the pain points that come up the most:

  • alternate low (or high) bit rate versions of <enclosure>
  • alternate video version of an audio and vice versa
  • Live video/audio
  • alternate transport protocols like bit torrent, ipfs, etc.
  • Companion audio/video track for <enclosure> meant to be played simultaneously, like a directors commentary or a Flop House/Riff Traxx style thing

I put that list into the order of biggest to smallest need based on just my own anecdotal observations. It might be wrong.

If we can solve all of those needs in one tag or structure that would be ideal since attempts at putting “live” into its own element in the past has had the result of zero adoption of that element.

@daveajones
Copy link
Contributor

daveajones commented Mar 2, 2021

I suppose it depends on how dogmatic we want to be on media, I know @daveajones has mentioned the problem for certain words being picked, but their eventual usage may not track exactly with where they end up being used. If media is a word that is too baised, maybe it isn't appropriate.

Media does feel a bit generic doesn’t it. I think something with “enclosure” in it will carry more weight in the community. It’s really just a marketing thing, but marketing is a reality so it’s something to keep in mind. Telling someone about the new “alternateEnclosure” tag is pretty easy since it carries its full intent directly in the name. (I’m being a little loose with “full” here. 😊)

@PofMagicfingers
Copy link
Contributor

PofMagicfingers commented Mar 2, 2021 via email

@agates
Copy link
Contributor Author

agates commented Mar 2, 2021

I do like the simplicity of <podcast:enclosure>, I just get a feeling it's going to cause issues for improperly written parsers and potentially hosts that set the podcast namespace as a default namespace. But people have been pretty quick to adapt before, no reason that couldn't be worked out.

@agates
Copy link
Contributor Author

agates commented Mar 3, 2021

For those interested, there's also been a tiny bit of discussion on live media representation for an item at Chocobozzz/PeerTube#3786, but I'll continue it here.

One thing I'm not clear on, and this is where me not being a podcaster shows most: What is the general consensus around updating an <item>? My initial research is that if you want to update the item, the <guid> should change to essentially identify it as a new item?

@daveajones
Copy link
Contributor

I just get a feeling it's going to cause issues for improperly written parsers and potentially hosts that set the podcast namespace as a default namespace.

We should avoid anything that even has the potential for problems. The name is the least important thing.

@agates agates changed the title Proposal: <podcast:media> Proposal: <podcast:alternateEnclosure> update Mar 3, 2021
@agates
Copy link
Contributor Author

agates commented Mar 3, 2021

Trying to think outside the box, threw this together as a quick idea -- what if the recommendation for a live stream is an <item> without an <enclosure> but with <podcast:alternateEnclosure ... live="true">, with the specified live time given an ISO 8601 time interval? Then when the actual episode is released, it would be under a new item released with an <enclosure>.

<podcast:timeInterval> could then technically be used for content expiration, but when used in combination with a live="true" attribute can allow indication of a live stream. The length/size attribute would become optional due to being unknown.

(I understand this doesn't take into account youtube/twitch/troll-room -- I've intentionally excluded them for now to focus on live audio/video content streams)

Live version of upcoming show at 11am CST on March 4, 2021, 3 hours long:

<title>Episode 1326 LIVE!!!</title>
<guid>some-random-live-guid</guid>
<podcast:alternateEnclosure type="audio/mpeg" bitrate="128000" title="Live Audio" live="true">
    <podcast:source uri="https://best-podcast.com/live-stream-mpeg" />
    <podcast:timeInterval>2021-03-04T11:00:00-06:00/PT3H<podcast:timeInterval>
</podcast:alternateEnclosure>

<podcast:alternateEnclosure type="audio/aac" bitrate="160000" title="Live Audio - High Quality" live="true">
    <podcast:source uri="https://best-podcast.com/live-stream-aac" />
    <podcast:timeInterval>2021-03-04T11:00:00-06:00/PT3H<podcast:timeInterval>
</podcast:alternateEnclosure>

<podcast:alternateEnclosure type="application/x-mpegURL" title="Live Dynamic Audio/Video Stream" live="true">
    <podcast:source uri="https://best-podcast.com/master.m3u8" />
    <podcast:source uri="ipfs://exampleLinkThatDoesntWorkHLS" />
    <podcast:timeInterval>2021-03-04T11:00:00-06:00/PT3H<podcast:timeInterval>
</podcast:alternateEnclosure>

Actual episode release, guid is different:

<title>Episode 1326: Clever Title</title>
<enclosure url="https://best-podcast.com/file-0.mp3" length="43200000" type="audio/mpeg" /> 
<guid>different-guid-for-same-episode-with-enclosure</guid>
<podcast:alternateEnclosure type="audio/mpeg" length="43200000" bitrate="128000" title="Audio" default="true">
    <podcast:source uri="https://best-podcast.com/file-0.mp3" />
</podcast:alternateEnclosure>

<podcast:alternateEnclosure type="audio/aac" length="54000000" bitrate="160000" title="Audio - Proprietary AAC">
    <podcast:source uri="https://best-podcast.com/file-proprietary.aac" />
</podcast:alternateEnclosure>

EDIT: No idea how live streams would work with non-http sources
EDIT2: Actually nevermind, I think HLS/DASH can support live streams by definition, they are just files and can be loaded from IPFS -- included in first example.

@daveajones
Copy link
Contributor

One thing I'm not clear on, and this is where me not being a podcaster shows most: What is the general consensus around updating an <item>? My initial research is that if you want to update the item, the <guid> should change to essentially identify it as a new item?

Everyone does it a bit differently. Even I’ve done it differently in two different aggregators. But generally the only sure-fire way to make sure it changes everywhere is to change the GUID like you said, which will be a new item.

@jamescridland
Copy link
Contributor

It seems to me that podcast:enclosure is a viper's nest of confusion and unpleasantness.

How about podcast:enclosures - with the proviso that

  • this must include the original enclosure as well if used
  • this is only really useful if there is more than one enclosure anyway (and if you don't have more than one, just use enclosure)

@daveajones
Copy link
Contributor

  • this must include the original enclosure as well if used

What's the thinking on this if you don't mind expounding a bit?

@jamescridland
Copy link
Contributor

I think I'm just trying to keep things simple.

We have an enclosure tag. That will, realistically, never go away. Any podcast RSS needs the standard enclosure tag.

An "alternateEnclosure" tag is one that includes alternates to the main enclosure. That main enclosure is in the enclosure tag. The additional ones listed under "alternate" are alternative enclosures.

An "podcast:enclosures" tag lists all available enclosures. This new tag may have more detail than is currently available in the old enclosure tag. So it's absolutely valid to include all of them, with all the information. We should probably highlight which is the default.

It all depends what the use-case is here.

@daveajones
Copy link
Contributor

Thanks. Makes sense. I say we just keep the naming as “alternateEnclosure” then. Avoids duplication and preserves the intent of the tag.

@saerdnaer
Copy link
Contributor

saerdnaer commented Mar 29, 2021

On other comment – it looks like peertube is already including torrent links in it's rss feeds (using mediarss):

https://video.codefor.de/feeds/videos.xml?videoChannelId=3

<item>
<title><![CDATA[ The Open Show 1.2: Was ist Linked Open Data? ]]></title>
<link>https://video.codefor.de/videos/watch/791d6351-2fbe-4335-bc98-5e99d6dc10fb</link>
<guid>https://video.codefor.de/videos/watch/791d6351-2fbe-4335-bc98-5e99d6dc10fb</guid>
<pubDate>Tue, 19 Jan 2021 17:11:26 GMT</pubDate>
<description>
  <![CDATA[ Was ist Linked Open Data und wie können uns verknüpfte, offene Daten im Alltag helfen? ]]>
</description>
<content:encoded>
  <![CDATA[ Was ist Linked Open Data und wie können uns verknüpfte, offene Daten im Alltag helfen? ]]>
</content:encoded>
<dc:creator>julia</dc:creator>

<media:title type="plain">The Open Show 1.2: Was ist Linked Open Data?</media:title>
<media:description type="plain">Was ist Linked Open Data und wie können uns verknüpfte, offene Daten im Alltag helfen?</media:description>
<media:thumbnail url="https://video.codefor.de/static/thumbnails/791d6351-2fbe-4335-bc98-5e99d6dc10fb.jpg" height="122" width="223"> </media:thumbnail>
<media:rating>nonadult</media:rating>
<media:category scheme="http://search.yahoo.com/mrss/category_schema" label="Education">13</media:category>
<media:community>
  <media:statistics views="22"> </media:statistics>
</media:community>
<media:embed url="/videos/embed/791d6351-2fbe-4335-bc98-5e99d6dc10fb"> </media:embed>
<media:player url="/videos/watch/791d6351-2fbe-4335-bc98-5e99d6dc10fb"> </media:player>
<enclosure type="application/x-bittorrent" url="https://video.codefor.de/static/torrents/791d6351-2fbe-4335-bc98-5e99d6dc10fb-720.torrent" length="88238199"> </enclosure>
<media:group>
  <media:peerLink type="application/x-bittorrent" href="https://video.codefor.de/static/torrents/791d6351-2fbe-4335-bc98-5e99d6dc10fb-720.torrent" isDefault="true"> </media:peerLink>
  <media:peerLink type="application/x-bittorrent" href="https://video.codefor.de/static/torrents/791d6351-2fbe-4335-bc98-5e99d6dc10fb-720.torrent"> </media:peerLink>
  <media:peerLink type="application/x-bittorrent" href="https://video.codefor.de/static/torrents/791d6351-2fbe-4335-bc98-5e99d6dc10fb-360.torrent"> </media:peerLink>
  <media:peerLink type="application/x-bittorrent" href="https://video.codefor.de/static/torrents/791d6351-2fbe-4335-bc98-5e99d6dc10fb-360.torrent"> </media:peerLink>
  <media:peerLink type="application/x-bittorrent" href="https://video.codefor.de/static/torrents/791d6351-2fbe-4335-bc98-5e99d6dc10fb-240.torrent"> </media:peerLink>
  <media:peerLink type="application/x-bittorrent" href="https://video.codefor.de/static/torrents/791d6351-2fbe-4335-bc98-5e99d6dc10fb-240.torrent"> </media:peerLink>
  <media:peerLink type="application/x-bittorrent" href="https://video.codefor.de/static/torrents/791d6351-2fbe-4335-bc98-5e99d6dc10fb-0.torrent"> </media:peerLink>
  <media:peerLink type="application/x-bittorrent" href="https://video.codefor.de/static/torrents/791d6351-2fbe-4335-bc98-5e99d6dc10fb-0.torrent"> </media:peerLink>

  <media:content url="https://video.codefor.de/static/webseed/791d6351-2fbe-4335-bc98-5e99d6dc10fb-720.mp4" fileSize="88238199" type="video/mp4" medium="video" framerate="30" duration="276" height="720" lang="de"> </media:content>
  <media:content url="https://video.codefor.de/static/webseed/791d6351-2fbe-4335-bc98-5e99d6dc10fb-720.mp4" fileSize="88135041" type="video/mp4" medium="video" framerate="30" duration="276" height="720" lang="de"> </media:content>
  <media:content url="https://video.codefor.de/static/webseed/791d6351-2fbe-4335-bc98-5e99d6dc10fb-360.mp4" fileSize="7863651" type="video/mp4" medium="video" framerate="30" duration="276" height="360" lang="de"> </media:content>
  <media:content url="https://video.codefor.de/static/webseed/791d6351-2fbe-4335-bc98-5e99d6dc10fb-360.mp4" fileSize="7774273" type="video/mp4" medium="video" framerate="30" duration="276" height="360" lang="de"> </media:content>
  <media:content url="https://video.codefor.de/static/webseed/791d6351-2fbe-4335-bc98-5e99d6dc10fb-240.mp4" fileSize="6599939" type="video/mp4" medium="video" framerate="30" duration="276" height="240" lang="de"> </media:content>
  <media:content url="https://video.codefor.de/static/webseed/791d6351-2fbe-4335-bc98-5e99d6dc10fb-240.mp4" fileSize="6511257" type="video/mp4" medium="video" framerate="30" duration="276" height="240" lang="de"> </media:content>
  <media:content url="https://video.codefor.de/static/webseed/791d6351-2fbe-4335-bc98-5e99d6dc10fb-0.mp4" fileSize="6649144" type="video/mp4" medium="video" framerate="0" duration="276" height="0" lang="de"> </media:content>
  <media:content url="https://video.codefor.de/static/webseed/791d6351-2fbe-4335-bc98-5e99d6dc10fb-0.mp4" fileSize="6660174" type="video/mp4" medium="video" framerate="0" duration="276" height="0" lang="de"> </media:content>
</media:group>

</item>

@agates
Copy link
Contributor Author

agates commented Mar 29, 2021

They do yes, I am very familiar with this code and currently have a fork that adds the podcast namespace.

@agates
Copy link
Contributor Author

agates commented Apr 10, 2021

Updated the proposal:

  1. Removed the "title" attribute as it wasn't useful in practice and was more or less redundant from the information already available. Should leave it up to the application to generate these labels if desired.
  2. Added an optional "height" attribute for cases where the media format is a video.

I'm not settled on how to include optional attributes like "height" as it feels like these optional attributes may only grow over time. But adding another child tag to include the information is also clunky, though I think it could work.

@daveajones
Copy link
Contributor

Thanks for this. Should I write it up into the main phase 3 of the readme or does it need its own proposal document?

@agates
Copy link
Contributor Author

agates commented Apr 11, 2021

Thanks for this. Should I write it up into the main phase 3 of the readme or does it need its own proposal document?

I can't think of a reason to keep it separate at the moment

@daveajones
Copy link
Contributor

I've written in up in the README and a separate doc. Just felt right since it's a big tag:

Spec Doc

@agates
Copy link
Contributor Author

agates commented Mar 5, 2022

FYI this was formally adopted in Phase 3.

@agates agates closed this as completed Mar 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal An idea for a new tag
Projects
None yet
Development

No branches or pull requests

7 participants