OK, I updated the script to version 1.1.
The old one would just crash and not work (my bad, I’m not the best at this), so I fixed that.
Also I rewrote it so instead of trying to match labels on the music video page (Not something all music videos have) it just picks the earliest album release. The script still tries to go for albums first, then other kinds like singles. (theirs also a clause to ignore anything not official and if that fails, it just chooses the first album in the list)
Their are some errors.
Like how the script saves the label to “Studio” (it also saves the label to label) it does this since it was written for Ersatz TV, and I’m not sure which should be the proper term. Either way I can’t change the Ersatz TV program (though I can ask, the creator is very nice and accommodating) but I’d rather not unless I know for sure what people would use.
Also some music videos will just cause a crash with no error. like this one does for me.
But aside from that, it seems to be working pretty well. Here’s the script:
PLUGIN_NAME = "Music Video Plugin"
PLUGIN_AUTHOR = "Ben"
PLUGIN_DESCRIPTION = """
This is a plugin made to get Music video Metadata from the Music Brainz site.
I wrote a check so that it will only attempt to alter entries with "video = true" but I also don't know what I'm doing so it might be safter to turn it off when not editing music videos.
It's designed to look for the information you would have in Music Video Credits: Band name, song title, album name, record label, director. (It's based on this image https://s.studiobinder.com/wp-content/uploads/2018/02/The-Essential-Music-Video-Credits-Format-Guide-MTV-Chyron-Look-StudioBinder-Production-Management-Software.jpg).
The labeling style used is based on the Ersatz TV program. To be frank, this plugin is made to get Music Video Data from the Music Brainz site so that it can be used for Ersatz TV.
For people with different use cases or who want to create a standardized Music video labeling parlance, this plugin will probably fall short But, it can be customized. I encourage people to build on and improve this plugin if they want.
The way it works is that the plugin gets the Director, Song name, and band from the Music video page. It will also get Label there too, but if one isn't available it will look for one on the album page The plugin then tries to get the album through some logical deductions. First, it goes to the page of the song the music video was made for. Then it goes through all the albums the song was featured on one by one, removing any albums that aren't the ''Album Type'' (So no Singles or Compilations), it also filter so only [status] "Official" albums are used It then checks the dates of accepted entries to see which was the first to release (assuming the music video was made for the first release of the song it was made for). If that fails it goes through the albums again, this time without filtering out Singles or Compilations but, still filtering for "Official" albums. It looks for the earliest one. I that fails it uses the first Album on the list.
"""
PLUGIN_VERSION = '1.1'
PLUGIN_API_VERSIONS = ['2.2']
PLUGIN_LICENSE = "GPL-2.0-or-later"
PLUGIN_LICENSE_URL = "https://www.gnu.org/licenses/gpl-2.0.html"
import json
from picard.metadata import register_track_metadata_processor
from functools import partial
from picard.webservice.api_helpers import MBAPIHelper
api_helper = None
hasLabel = 0
def startSearch(album, metadata, track, release):
video = track.get('video')
if video and video == True:
global api_helper
global hasLabel
hasLabel = 0
api_helper = MBAPIHelper(album.tagger.webservice)
labelhandler = partial(checklabel, metadata)
songhandler = partial(checksong, metadata)
api_helper.get_track_by_id(track['id'], labelhandler, inc = ['label-rels'])
r = track['relations']
vID = None
for x in range(len(r)):
if r[x]['target-type'] == 'recording' and r[x]['direction'] == 'backward' and r[x]['type'] == 'music video':
vID = r[x]['recording']['id']
break
if vID != None:
api_helper.get_track_by_id(vID, songhandler, inc = ['releases', 'release-groups'])
def checklabel(metadata, release, http, error):
global hasLabel
for y in range(len(release['relations'])):
if release['relations'][y]['target-type'] == 'label':
metadata["label"] = release['relations'][y]['label']['name']
metadata["studio"] = release['relations'][y]['label']['name']
hasLabel = 1
break
def checksong(metadata, recording, http, error):
albumhandler = partial(checkalbum, metadata)
noAlbum = 0
recordingFound = 0
recordingValue = -1
for x in range(len(recording['releases'])):
albumOK = 1
if recording['releases'][x]['release-group']['primary-type'] == 'Album' and recording['releases'][x]['status'] == 'Official':
for y in range(len(recording['releases'][x]['release-group']['secondary-types'])):
if recording['releases'][x]['release-group']['secondary-types'][y] == 'Compilation':
albumOK = 0
break
if albumOK == 1 and recordingFound == 0:
recordingFound = 1
recordingValue = x
if albumOK == 1 and recordingFound == 1:
dateA = recording['releases'][recordingValue]['date']
dateB = recording['releases'][x]['date']
dates = [dateA, dateB]
dates.sort
if dateA != dates[0]:
recordingValue = x
if x == len(recording['releases']) -1 and recordingFound == 1:
aID = recording['releases'][recordingValue]['id']
api_helper.get_release_by_id(aID, albumhandler, inc = ['labels'])
break
if x == len(recording['releases']) - 1 and recording['releases'][x]['release-group']['primary-type'] == 'Album':
if recording['releases'][x]['release-group']['secondary-types'][y] == 'Compilation':
noAlbum = 1
break
if x == len(recording['releases']) - 1 and recording['releases'][x]['release-group']['primary-type'] != 'Album':
noAlbum = 1
if noAlbum == 1:
for x2 in range(len(recording['releases'])):
if recordingFound == 0 and recording['releases'][x]['status'] == 'Official':
recordingFound = 1
recordingValue = x2
if recordingFound == 1 and recording['releases'][x]['status'] == 'Official':
dateA = recording['releases'][recordingValue]['date']
dateB = recording['releases'][x2]['date']
dates = [dateA, dateB]
dates.sort
if dateA != dates[0]:
recordingValue = x2
if x == len(recording['releases']) - 1 and recordingFound == 1:
aID = recording['releases'][recordingValue]['id']
api_helper.get_release_by_id(aID, albumhandler, inc = ['labels'])
if x == len(recording['releases']) - 1 and recordingFound == 0:
aID = recording['releases'][0]['id']
api_helper.get_release_by_id(aID, albumhandler, inc = ['labels'])
def checkalbum(metadata, release, http, error):
global hasLabel
for x in range(len(release['label-info'])):
if hasLabel == 0 and release['label-info'][0]['label']['name'] != None:
metadata["label"] = release['label-info'][0]['label']['name']
metadata["studio"] = release['label-info'][0]['label']['name']
metadata['album'] = release['title']
register_track_metadata_processor(startSearch)