Stand-alone quodlibet script

I love quodlibet and have a big collection of music in it. Some time ago I wanted to transcode some big lossless files into the more mobile-friendly ogg format and wanted to query quodlibet for the songs. This is an example of a script that can access the quodlibet database and doesn't need X. It only searches and loops over the results, nothing fancy.

#!/usr/bin/env python2

import argparse
import os
import sys
import subprocess

import quodlibet
from quodlibet import app
from quodlibet import config
from quodlibet.query import Query
import quodlibet.library


parser = argparse.ArgumentParser(description='Transcode quodlibet music to ogg')
parser.add_argument('query', type=str, help='the query, e.g. "~format=flac"')
parser.add_argument('--transcode', action='store_true', help="Perform the transcoding")
parser.add_argument('--debug', action='store_true', help="Be more verbose")
parser.add_argument('--album', action='store_true',
                    help="Transcode the entire album for every song found")
args = parser.parse_args()

TARGET = "/whatever/location/ogg/"

# Initialize quodlibet
quodlibet.init_cli()
config.init(os.path.join(quodlibet.get_user_dir(), "config"))
library_path = os.path.join(quodlibet.get_user_dir(), "songs")
library = quodlibet.library.init(library_path)
app.library = library


if not os.path.exists(TARGET):
    os.mkdir(TARGET)


def main_query(search, album_recurse=False):
    if args.debug:
        sys.stdout.write('Search for {}\n'.format(search))
    for song in Query(search).filter(app.library):
        filename = song.get('~filename', None)
        enc = song.get('~format', None)
        album = song.get('album', None)
        title = song.get('title', None)
        labelid = song.get('labelid', None)
        artist = song.get('artist', None)
        if args.debug:
            sys.stdout.write('Processing {} | {} | {}\n'.format(artist, album, title))
        if album_recurse:
            if labelid is not None:
                query = 'labelid={}'.format(labelid)
            else:
                query = '&(album="{}", artist="{}")'.format(album, artist)
            main_query(query)
        else:
            if filename and album and artist:
                if args.transcode:
                    transcode(filename, artist, album)
            else:
                sys.stderr.write('Incomplete metadata for {}\n'.format(filename))


def transcode(filename, artist, album):
    path = os.path.join(TARGET, album)
    fn, ext = os.path.splitext(filename)
    outfile = os.path.join(path, os.path.basename(fn) + '.ogg')
    if not os.path.exists(outfile):
        if not os.path.exists(path):
            os.makedirs(path)
        subprocess.call(['ffmpeg', '-loglevel', 'quiet', '-i', filename, outfile])
        sys.stdout.write('Transcoded {}\n'.format(outfile))


main_query(args.query, album_recurse=args.album)
Published on May 20, 2017 at 1:02 p.m. by Nicolas . You can follow the discussion with the comment feed for this post. Feeling generous? Donate!

0 comments

Start a new thread

Cancel reply
Markdown. Syntax highlighting with <code lang="php"><?php echo "Hello, world!"; ?></code> etc.