User Tools

Site Tools


python:mp3-id3-lyrics-tag-move

MP3 ID3 Lyrics tag move

Move LYRICS text tag to USLT (Unsynchronised Lyrics Tag) tag of MP3 files recursively in current directory or any given target directory. The script retains the modification time of files.

Requires mutagen python3 module.

move_lyrics_id3_tag.py
#!/usr/bin/python3

import os, sys
import re
from pathlib import Path
import subprocess
from mutagen.id3 import ID3, USLT
import argparse

parser = argparse.ArgumentParser(description='Convert LYRICS tag to USLT tag of mp3 files.')
parser.add_argument('path', nargs='?', type=str, default=os.path.abspath(os.path.dirname(sys.argv[0])),
                   help='directory to process (default current directory)')
parser.add_argument('-w', '-W', '--no-dryrun', dest='nodryrun', action='store_const', 
                   const='yes', default='no', 
                   help='write changes to files (default: no)')
parser.add_argument('-r', '-R', '--recursive', dest='recursive', action='store_const',
                   const='yes', default='no',
                   help='process path recursively (default: no recursion)')
args = parser.parse_args()


if args.recursive == 'yes':
    pattern = '**/*.mp3'
else:
    pattern = '*.mp3'

# loop through mp3 files in directory/directories
for fname in Path(args.path).glob(pattern):
    #Get stats of original file
    st = os.stat(fname)
    #Load tags of original file
    _track = ID3(fname)

    print(fname)

    lyrics = _track.getall("TXXX:LYRICS")
    #print(lyrics)
    if not lyrics:
        print("No legacy Lyrics tag available")
        continue

    uslt_lyrics = _track.getall("USLT")
    if uslt_lyrics and uslt_lyrics[0].text and len(uslt_lyrics[0].text)>40:
        print("USLT Lyrics tag already available with content")
        continue

    if len(lyrics[0].text[0])<40:
        print("Lyrics too short, removing tag without copying")
        print(lyrics[0].text[0])
    else:
        print("copying lyrics")

        #insert lyrics into USLT frame
        _track.delall("USLT")

        #save lycis in USLT frame
        _track["USLT"] = (USLT(encoding=1, text=lyrics[0].text[0]))

        #compare new USLT entry with old lyrics entry
        new_uslt=_track.getall("USLT")
        #repr(new_uslt)
        #print(new_uslt)
        if new_uslt[0].text != lyrics[0].text[0]:
            print("New tag not the same as the old one, skipping")
            continue
        else:
            print("Lyrics copied")

    if args.nodryrun == "yes":
        #saving tag info
        #delete old LYRICS tag
        _track.delall("TXXX:LYRICS")
        #Update ID3 tag to v2.3
        _track.update_to_v23()
        #Save ID3 tag v2.3
        _track.save(v2_version=3)
        #Restore atime and mtime to timestamps before saving it
        os.utime(fname, (st.st_atime, st.st_mtime))
        #Done
        print("File saved")
    else:
        print("Dry-run, file not changed")
python/mp3-id3-lyrics-tag-move.txt · Last modified: 2023/05/29 11:55 by 127.0.0.1