Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: Python script for transferring ratings from audio metadata to foo_playcount (Read 621 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Python script for transferring ratings from audio metadata to foo_playcount

After updating to Foobar2000 v2.0 I noticed that foo_playcount is now basically the "default" for storing ratings, so I thought it would be a good time to transfer the ratings from the metadata of all the audio files to a foo_playcount-compatible XML file that can be imported into Foobar.

Usage is really easy: just export your library as XML first (through Library --> Playback Statistics, make sure to check all fields so that it exports all the file paths). Run this script and re-import the resulting XML. Note: I give no guarantees, use at your own risk!

This script was written partly by ChatGPT, partly by me  ;)

Code: [Select]
import os
import xml.etree.ElementTree as ET
from mutagen import File
import numpy as np

def extract_rating(file_path):
    """
    Extracts the rating from the metadata
    """
    audio = File(file_path)
    if 'rating' in audio:
        R = int(float(audio['rating'][0]))
        assert(0 <= R <= 5)
        return R
    return None

def calc_rating(rating):
    """
    foo_playcount stores the 0-5 rating as 'RatingFriendly' and a different
    integer as 'Rating', according to the equation below.
    Source: https://hydrogenaud.io/index.php/topic,85309.msg733606.html#msg733606
    """
    return int(np.round((63.75 + 42.5*(rating-1))))

  
def update_ratings(infile, outfile, folder_path):
    """
    Scans a folder recursively for audio files, extracts ratings and updates
    the XML data.
    """
    tree = ET.parse(infile)
    root = tree.getroot()
    for entry in root.findall('./Entry'):
        item = entry.find('Item')
        file_path = item.get('Path')
        if file_path:
            file_path = os.path.normpath(file_path)
            if any(file_path.lower().endswith(ext) for ext in ('.mp3', '.wav', '.flac', '.aac', '.mp4')):
                print('Scanning {}...'.format(file_path))
                rating = extract_rating(file_path)
                if rating is not None:
                    entry.set('Rating', str(calc_rating(rating)))
                    entry.set('RatingFriendly', str(rating))
    tree.write(outfile, encoding='utf-8', xml_declaration=False)

inxml = 'Library.xml'
outxml = 'Library_ratings.xml'
folder_to_scan = 'H:/MUSIC'

update_ratings(inxml, outxml, folder_to_scan)


 

Re: Python script for transferring ratings from audio metadata to foo_playcount

Reply #2
Why not using Playlist viewer context menu | Playback Statistics | Import statistics from file tags? Or did I miss something?
Ha, I guess that would have worked too :)

I googled for a bit but could not find this solution so I came up with my own.