Yetangitu / Spodcast

Spodcast is a caching Spotify podcast to RSS proxy. Using Spodcast you can follow Spotify-hosted netcasts/podcasts using any player which supports RSS, thus enabling the use of older hardware which is not compatible with the Spotify (web) app.
GNU General Public License v3.0
359 stars 14 forks source link

Set audio format (.ogg vs. .mp3) #4

Closed ahuse closed 2 years ago

ahuse commented 2 years ago

Some podcasts are downloaded as .mp3 and some as .ogg. I looked at your code and it seems to me, that you are preferring .ogg over .mp3.

In which format are the files stored on Spotify's servers? Either .mp3 or .ogg? Or both formats for some podcasts? Would it be possible to download the .mp3 for the episodes which are currently downloaded as .ogg?

Yetangitu commented 2 years ago

These are the formats Spotify offers for Spotify-hosted shows: mp4, aac and ogg:

Spotify-hosted (streaming download):

      "audio": {
        "items": [
          {
            "url": "https://anon-podcast.scdn.co/d5fe1647e3fb98c7f074cf87c0a6fe6fbd3848b1",
            "format": "AAC_24",
            "fileId": "d5fe1647e3fb98c7f074cf87c0a6fe6fbd3848b1",
            "externallyHosted": false
          },
          {
            "url": "https://anon-podcast.scdn.co/47e7f56afca4719d33094c81dc826a63668a23a6",
            "format": "MP4_128",
            "fileId": "47e7f56afca4719d33094c81dc826a63668a23a6",
            "externallyHosted": false
          },
          {
            "url": "https://anon-podcast.scdn.co/ec2cd6625026c45273e8776c3779b80afc28ca36",
            "format": "MP4_128_DUAL",
            "fileId": "ec2cd6625026c45273e8776c3779b80afc28ca36",
            "externallyHosted": false
          },
          {
            "url": "https://anon-podcast.scdn.co/226e1bd59da25e023cbdb450485e43b6b1b9878b",
            "format": "OGG_VORBIS_96",
            "fileId": "226e1bd59da25e023cbdb450485e43b6b1b9878b",
            "externallyHosted": false
          }
        ]
      }

Externally hosted shows can be download directly as mp3 - see the last group in the array, the one hosted by podtrac.

Externally hosted (direct download):

  "audio": {
    "items": [
      {
        "url": "https://anon-podcast.scdn.co/b16d6ecd88942a0fac5dea4e560fc553e7ba90fb",
        "format": "AAC_24",
        "fileId": "b16d6ecd88942a0fac5dea4e560fc553e7ba90fb",
        "externallyHosted": false
      },
      {
        "url": "https://anon-podcast.scdn.co/63437b0b71f6d332555b041441d760641e00dba8",
        "format": "MP4_128_DUAL",
        "fileId": "63437b0b71f6d332555b041441d760641e00dba8",
        "externallyHosted": false
      },
      {
        "url": "https://anon-podcast.scdn.co/30f1f2170606c5bc6ccd367ea163b9a1039336af",
        "format": "MP4_128",
        "fileId": "30f1f2170606c5bc6ccd367ea163b9a1039336af",
        "externallyHosted": false
      },
      {
        "url": "https://anon-podcast.scdn.co/ce101e45379048a8d41d21e352dfc076aa1cdbf1",
        "format": "OGG_VORBIS_96",
        "fileId": "ce101e45379048a8d41d21e352dfc076aa1cdbf1",
        "externallyHosted": false
      },
      {
        "url": "https://www.podtrac.com/pts/redirect.mp3/pdst.fm/e/pdst.fm/e/traffic.megaphone.fm/BENT9388265894.mp3?updated=1645154429",
        "format": "UNKNOWN",
        "fileId": null,
        "externallyHosted": true
      }
    ]
  }

Spodcast simply takes the last array item, checks whether it can be downloaded directly and does so if possible, otherwise it downloads the VORBIS stream at high speed or in real time if --download-real-time is enabled. The former produces mp3 files - theoretically it could also produce other formats depending on the external podcast links but thus far I've only seen mp3 - while the latter produces ogg. It could produce aac as well or possibly mp4 (have not tried) but not mp3 since these are not available.

ahuse commented 2 years ago

Ok. Got it. Thanks for the explanation.

Would be interesting to implement an option to choose the filetype, as not all my players can play ogg.

Yetangitu commented 2 years ago

The librespot-python library on wich Spodcast rests currently only supports VorbisOnlyAudioQuality(), I'll see how it reacts to adding a similar method for aac and mp4 - not mp3 since this format is not offered by Spotify - and see what it produces.

[edit]

I just did the experiment and found out the AAC stream is not recognised as such (possibly due to encryption), at least when using the version of librespot-python on PyPi as is used by the version of Spodcast on PyPi, the one you get when you pip install spodcast. I'll experiment a bit more with the development version (which is quite different) at a later stage but for now it is ogg and mp3 you'll get from Spodcast, at least from the version on PyPi.

heywoodlh commented 2 years ago

For the record, ogg format does not work on iOS.

I work around this issue by running a (not very elegant) script to convert the ogg files to mp3 and update the metadata in the .info file:

#!/usr/bin/env bash

root_dir=/data

files=$(find ${root_dir} -name "*.ogg")

for file in ${files}
do 
    base_ogg=${file%.ogg}
    base_name=$(echo "$(basename ${file})" | sed 's/.ogg//g')
    ogg_info="${file}.info"
    outfile="${base_ogg}.mp3"

    echo "converting ${file} to ${outfile}" \
        && ffmpeg -n -loglevel quiet -i ${file} ${outfile} -speed 8
    sed -i 's/audio\/ogg/audio\/mp3/g' ${ogg_info}
    sed -i "s/${base_name}.ogg/${base_name}.mp3/g" ${ogg_info}
    cp ${base_ogg}.mp3 ${file}
    mv ${ogg_info} ${base_ogg}.mp3.info
done

@Yetangitu would it be reasonable to add a feature to the project that if you specify --mp3 or --ogg that you invoke a Python library to convert the file if the format if it is not the desired audio file type?

Yetangitu commented 2 years ago

Aren't there any tools to breach the Apple boycott of open formats? That would be the better solution IMnsHO. Working around Apple-related problems reminds me too much of working around Microsoft-related problems.VLC seems to be available, it can play Vorbis.

Anyway, I'll give it some thought, more in a few days - busy now.

Yetangitu commented 2 years ago

The latest release (0.4.1) introduces a --transcode yes/no option, give it a try.

Yetangitu commented 2 years ago

There's a typo in 0.4.1, wait for 0.4.2...

Yetangitu commented 2 years ago

Fixed now, 0.4.2 is up on Github and PyPi

heywoodlh commented 2 years ago

Worked great for me! Thanks for adding this feature.

ahuse commented 2 years ago

Works for me too.

One minor issue is that the embedded image is not copied to the mp3-file while transcoding.

Yetangitu commented 2 years ago

@ahuse is this an issue worth tackling? Is anyone using those images? What is the effect of not having them? For sure, it is possible to copy embedded images but if nobody uses them (I for one do not) it isn't worth spending any (processing) time on.

ahuse commented 2 years ago

@Yetangitu For me, yes. My Podcast app always uses the cover of the last episode as the shows cover. Should be just a setting in ffmpeg to copy the cover to the new file. I will do some research.

Yetangitu commented 2 years ago

I checked a random downloaded Ogg file and did not find any embedded image in it, am I missing something? Could you give me an example of such a file - or a pointer to a Spotify-hosted (s)podcast which hosts such files - which does contain an embedded image?