Python script to update metadata information for items in plex as well as automatically build collections and playlists. The Wiki Documentation is linked below.
Is your feature request related to a problem? Please elaborate.
I love that PMM now supports music libraries, but there is a lack of metadata sources for music information to build playlists. There are some obvious starting choices (spotify, apple music, last.fm, etc) but I would like to suggest tunefind.com
Describe the solution you'd like
TuneFind.com would be a great metadata source for PMM! It's a collaborative site where people identify and list songs they hear in movies or TV shows. This could conceivably allow a PMM user to make music playlists for TV series they have in their library. Binge watching a new TV show? When you're driving around, you can listen to the PMM generated soundtrack based on what already exists within your music collection.
General Info
As a fallback, it is possible to scrape pages. They store all the useful data in a HTML script tag called "__NEXT_DATA__" in a slightly different structure... but the easiest way is through the public API that I discovered by just watching the network activity tab in Firefox.
You can also add some parameters to narrow down the search, like...
facetFilters=[["type: show","type: movie"]] limits the results to the show and movie categories
hitsPerPage=40 returns 40 results per page rather than the default 20
The data that's returned is pretty simple to understand, but just a heads up that the cnt key lists the number of songs associated with the matching object... so for "stranger things" we can easily see that it's a show and the partial URL is /show/stranger-things and it has 384 songs.
> show Contains the show name and a link to artwork
> seasons Contains a collection of season objects, for example...
> seasons > 0 Contains the season name (keyed as group_name), start and end of the season schedule (keyed as air_date_start and air_date_end in unixtimestamp format). type_full in this example is show which validated that this is a TV show and not a movie. songs_count gives the number of songs that are known to have appeared across that season, and episodes_count is the number of episodes in that season.
> seasons > 0 > image is an object giving info about an image representing that season. Probably not useful
> seasons > 0 > music_supervisors is an object of objects giving info about the music supervisors responsible for that season. If the object for each music_supervisors item contains the key username that means that they have an account on tunefine. If it contains 'id' that means that the professional is in their DB but doesn't have an account with them. Depending on those differences, to get their real name, you'll want to look for either the realname or name field. Later we can use the username or name_stub data to get some really useful info about other projects that person is affiliated with. People without an account also have an images field that contains an artist image. For people with an account, that info is pulled from their user profile page.
> seasons > 0 > composers is basically the same setup and rules as music_supervisors
> seasons > 0 > theme_song contains information on the theme song associated with that season. Often they're the same as shows usually don't change their theme song that often. It contains stuff like the song name, the name of the album it's on, a link to a preview snippet of the song (just like plex can play a theme song when you go into a show), and a link to the album coverart. The coverart link points to a low res image, but you can replace the /88x88bb.jpg part of the url with /999999999x0w-999.jpg to get a very high resolution image.
> latest_episode Contains a summary of the latest episode, including the title, episode number, description, air date, if it's been aired already, and the number of songs identified in the episode.
> similars is neat. It's a collection of TV shows that tunefind recommends as having a similar music profile.
> theme_song is basically the same as the theme_song layout within each season, but it represents the themesong pick that represents the whole series as opposed to a specific season
> season contains information about the specified season, basically the same layout as the items in the seasons object in the TV show request
> theme_song contains information about the theme song for that specific season, basically the same layout as the theme_song object in the TV show request > seasons > 0 > theme_song
music_supervisors and composers are basically also the same as the entries in each season from the TV show request. It just gives info on those people on the season level
episodes is a collection of items representing each episode in that season. It contains values that include data like the episode_id (used to request data on each episode, so this is important), episode title, the air date, episode description, and the number of songs known to be in that episode.
> hot_songs is kinda cool, it's the top 5 songs by popularity that were used across that whole season
> episode contains a lot of fields already available from previous queries like the episode title, description, id, airing date, etc.
> episode > song_events contains the juicy stuff. It's a collection of moments in the TV show where there was music, and the song information if known
> episode > song_events > 0 contains a description field explaining the context of when the music plays in the episode, is_right can be true or false and shows if tunefind feels that the information is entirely correct.
> episode > song_events > 0 > song contains the information about the song. It has the song name and the album name it's on, as well as the artist name. It might also have the field album_id and album_song_no which represent the itunes album ID and the track number. The itunes album info can be queried at https://itunes.apple.com/lookup?id=1234567890&entity=album
> episode > song_events > 0 > song > url has a link to the coverart (see previous notes about URL modification to get higher quality cover art) and a link to a preview of the song. It also has a trackid... If you remove the prepended A:, the ID number can be used in a request to itunes like https://itunes.apple.com/lookup?id=1443757612&entity=album which returns two JSON objects with more information about the song track and the album itself. That's because if you request a track number in the album context, it returns the track info AND the album info.
> episode > song_events > 0 > song > artists is a collection of artists who are responsible for the track. Each artist item has keys, most useful is id, name, name_stub, image > src
> episode > next and previous are built the same. They contain the basic episode info of the next and previous episodes in the season, at the level of detail that's found in the season JSON api call
Artist Info with a list of where their songs appear
Returns useful fields about the musical artist like name, image, HTML formatted biography, links to their various official sites and pages, links to their artist pages on music DL/streaming services, and the number of songs they have that have been featured in TV shows or movies that tunefind knows about.
> appearances is a collection of data that includes all the TV shows and movies that the song has appeared in
> popularity is an sorted array. The values represent the song_id in the appearances. The first item in the array is the most popular, the last item the least popular.
The whole nag_login and nag_count makes me think that even the frontend public API may have some usage monitoring or rate limiting. I've never hit it, so I don't know what it looks like when that happens.
Additional Information
TuneFind does have an official API, but it looks like they're really trying to figure out how best to monetize it... The API endpoints I used above as examples are sourced from browsing the site itself. They might try to lock it down if it gets too popular. Also, tunefine is behind cloudflare so it would be important to make sure that CF isn't trying to do a CAPTCHA test during requests, and skipping the rest of the requests if it is.
Is your feature request related to a problem? Please elaborate.
I love that PMM now supports music libraries, but there is a lack of metadata sources for music information to build playlists. There are some obvious starting choices (spotify, apple music, last.fm, etc) but I would like to suggest tunefind.com
Describe the solution you'd like
TuneFind.com would be a great metadata source for PMM! It's a collaborative site where people identify and list songs they hear in movies or TV shows. This could conceivably allow a PMM user to make music playlists for TV series they have in their library. Binge watching a new TV show? When you're driving around, you can listen to the PMM generated soundtrack based on what already exists within your music collection.
General Info
As a fallback, it is possible to scrape pages. They store all the useful data in a HTML script tag called "__NEXT_DATA__" in a slightly different structure... but the easiest way is through the public API that I discovered by just watching the network activity tab in Firefox.
Useful API Endpoints for Discovery
Searching
One method is to use their Algolia instance. An example search that returns JSON is: https://owe3eigao9-dsn.algolia.net/1/indexes/tunefind-prod?x-algolia-application-id=OWE3EIGAO9&x-algolia-api-key=e73d0fd588e6c0e221c6f8d79b833671&query=testing
You can also add some parameters to narrow down the search, like...
facetFilters=[["type: show","type: movie"]]
limits the results to the show and movie categorieshitsPerPage=40
returns 40 results per page rather than the default 20One example is: https://owe3eigao9-dsn.algolia.net/1/indexes/tunefind-prod?x-algolia-application-id=OWE3EIGAO9&x-algolia-api-key=e73d0fd588e6c0e221c6f8d79b833671&query=stranger+things&facetFilters=[[%22type:%20show%22,%22type:%20movie%22]]&hitsPerPage=40
The data that's returned is pretty simple to understand, but just a heads up that the
cnt
key lists the number of songs associated with the matching object... so for "stranger things" we can easily see that it's a show and the partial URL is/show/stranger-things
and it has 384 songs.More documentation can be found at: https://www.algolia.com/doc/rest-api/search/
TV Show - Show summary with a list of seasons
Example: https://www.tunefind.com/api/frontend/show/for-all-mankind?fields=seasons,similars,theme-song&metatags=1
> show
Contains the show name and a link to artwork> seasons
Contains a collection of season objects, for example...> seasons > 0
Contains the season name (keyed asgroup_name
), start and end of the season schedule (keyed asair_date_start
andair_date_end
in unixtimestamp format).type_full
in this example isshow
which validated that this is a TV show and not a movie.songs_count
gives the number of songs that are known to have appeared across that season, andepisodes_count
is the number of episodes in that season.> seasons > 0 > image
is an object giving info about an image representing that season. Probably not useful> seasons > 0 > music_supervisors
is an object of objects giving info about the music supervisors responsible for that season. If the object for each music_supervisors item contains the keyusername
that means that they have an account on tunefine. If it contains 'id' that means that the professional is in their DB but doesn't have an account with them. Depending on those differences, to get their real name, you'll want to look for either therealname
orname
field. Later we can use theusername
orname_stub
data to get some really useful info about other projects that person is affiliated with. People without an account also have an images field that contains an artist image. For people with an account, that info is pulled from their user profile page.> seasons > 0 > composers
is basically the same setup and rules asmusic_supervisors
> seasons > 0 > theme_song
contains information on the theme song associated with that season. Often they're the same as shows usually don't change their theme song that often. It contains stuff like the song name, the name of the album it's on, a link to a preview snippet of the song (just like plex can play a theme song when you go into a show), and a link to the album coverart. The coverart link points to a low res image, but you can replace the/88x88bb.jpg
part of the url with/999999999x0w-999.jpg
to get a very high resolution image.> latest_episode
Contains a summary of the latest episode, including the title, episode number, description, air date, if it's been aired already, and the number of songs identified in the episode.> similars
is neat. It's a collection of TV shows that tunefind recommends as having a similar music profile.> theme_song
is basically the same as the theme_song layout within each season, but it represents the themesong pick that represents the whole series as opposed to a specific seasonTV Show - Season summary with a list of episodes
Example: https://www.tunefind.com/api/frontend/show/for-all-mankind/season/1?fields=episodes,theme-song,music-supervisors,hot-songs,composers,albums&metatags=1
> season
contains information about the specified season, basically the same layout as the items in theseasons
object in the TV show request> theme_song
contains information about the theme song for that specific season, basically the same layout as the theme_song object in the TV show request> seasons > 0 > theme_song
music_supervisors
andcomposers
are basically also the same as the entries in each season from the TV show request. It just gives info on those people on the season levelepisodes
is a collection of items representing each episode in that season. It contains values that include data like the episode_id (used to request data on each episode, so this is important), episode title, the air date, episode description, and the number of songs known to be in that episode.> hot_songs
is kinda cool, it's the top 5 songs by popularity that were used across that whole seasonTV Episode with a detailed list of songs
Example: https://www.tunefind.com/api/frontend/episode/92291?fields=song-events,nextPrev The episode ID in the URL is from the previous TV Season API call
> episode
contains a lot of fields already available from previous queries like the episode title, description, id, airing date, etc.> episode > song_events
contains the juicy stuff. It's a collection of moments in the TV show where there was music, and the song information if known> episode > song_events > 0
contains adescription
field explaining the context of when the music plays in the episode,is_right
can be true or false and shows if tunefind feels that the information is entirely correct.> episode > song_events > 0 > song
contains the information about the song. It has the song name and the album name it's on, as well as the artist name. It might also have the fieldalbum_id
andalbum_song_no
which represent the itunes album ID and the track number. The itunes album info can be queried at https://itunes.apple.com/lookup?id=1234567890&entity=album> episode > song_events > 0 > song > url
has a link to the coverart (see previous notes about URL modification to get higher quality cover art) and a link to a preview of the song. It also has atrackid
... If you remove the prependedA:
, the ID number can be used in a request to itunes likehttps://itunes.apple.com/lookup?id=1443757612&entity=album
which returns two JSON objects with more information about the song track and the album itself. That's because if you request a track number in the album context, it returns the track info AND the album info.> episode > song_events > 0 > song > artists
is a collection of artists who are responsible for the track. Each artist item has keys, most useful is id, name, name_stub, image > src> episode > next
andprevious
are built the same. They contain the basic episode info of the next and previous episodes in the season, at the level of detail that's found in the season JSON api callArtist Info with a list of where their songs appear
Example: https://www.tunefind.com/api/frontend/artist/squirrel-nut-zippers?fields=appearances,meta,songs_count
Returns useful fields about the musical artist like name, image, HTML formatted biography, links to their various official sites and pages, links to their artist pages on music DL/streaming services, and the number of songs they have that have been featured in TV shows or movies that tunefind knows about.
> appearances
is a collection of data that includes all the TV shows and movies that the song has appeared in> popularity
is an sorted array. The values represent the song_id in the appearances. The first item in the array is the most popular, the last item the least popular.Public User Profile
Example: https://www.tunefind.com/api/frontend/profile/MaggiePhillips
Some artists are a member of the site. The results are similar in concept to the previous Artist Info endpoint
Game Details
https://www.tunefind.com/api/frontend/game/halo-infinite-2021?fields=song-events,theme-song,hot-songs,music-supervisors,similars,composers
Movie Details
Good example of a score: https://www.tunefind.com/api/frontend/movie/lightyear-2022?fields=song-events,hot-songs,music-supervisors,similars,composers Good example of a soundtrack: https://www.tunefind.com/api/frontend/movie/trainspotting-1996?fields=song-events,hot-songs,music-supervisors,similars,composers
Interesting observations
https://www.tunefind.com/api/frontend/user/current is called on most HTML pages and includes a response like
The whole
nag_login
andnag_count
makes me think that even the frontend public API may have some usage monitoring or rate limiting. I've never hit it, so I don't know what it looks like when that happens.Additional Information
TuneFind does have an official API, but it looks like they're really trying to figure out how best to monetize it... The API endpoints I used above as examples are sourced from browsing the site itself. They might try to lock it down if it gets too popular. Also, tunefine is behind cloudflare so it would be important to make sure that CF isn't trying to do a CAPTCHA test during requests, and skipping the rest of the requests if it is.