ID3 over EasyID3, USLT working

This commit is contained in:
billypom on debian 2024-05-30 19:50:04 -04:00
parent fb2a512401
commit b5042292ed
5 changed files with 74 additions and 75 deletions

View File

@ -1,4 +1,4 @@
from mutagen.easyid3 import EasyID3 from mutagen.id3 import ID3
import DBA import DBA
from PyQt5.QtGui import ( from PyQt5.QtGui import (
QDragMoveEvent, QDragMoveEvent,
@ -141,12 +141,9 @@ class MusicTable(QTableView):
current_song = self.get_selected_song_metadata() current_song = self.get_selected_song_metadata()
print(f"MusicTable.py | show_lyrics_menu | current song: {current_song}") print(f"MusicTable.py | show_lyrics_menu | current song: {current_song}")
try: try:
lyrics = current_song["lyrics"] lyrics = current_song["USLT::XXX"].text
except Exception: except Exception as e:
pass print(f'MusicTable.py | show_lyrics_menu | could not retrieve lyrics | {e}')
try:
lyrics = current_song["USLT"]
except Exception:
lyrics = "" lyrics = ""
lyrics_window = LyricsWindow(selected_song_filepath, lyrics) lyrics_window = LyricsWindow(selected_song_filepath, lyrics)
lyrics_window.exec_() lyrics_window.exec_()
@ -224,9 +221,9 @@ class MusicTable(QTableView):
for filepath in filepaths: for filepath in filepaths:
try: try:
# Read file metadata # Read file metadata
audio = EasyID3(filepath) audio = ID3(filepath)
artist = audio.get("artist", ["Unknown Artist"])[0] artist = audio["TIT2"].text[0] if not '' or None else 'Unknown Artist'
album = audio.get("album", ["Unknown Album"])[0] album = audio["TALB"].text[0] if not '' or None else 'Unknown Album'
# Determine the new path that needs to be made # Determine the new path that needs to be made
new_path = os.path.join( new_path = os.path.join(
target_dir, artist, album, os.path.basename(filepath) target_dir, artist, album, os.path.basename(filepath)
@ -351,7 +348,7 @@ class MusicTable(QTableView):
"""Returns the selected songs filepath""" """Returns the selected songs filepath"""
return self.selected_song_filepath return self.selected_song_filepath
def get_selected_song_metadata(self) -> EasyID3 | dict: def get_selected_song_metadata(self) -> ID3 | dict:
"""Returns the selected song's ID3 tags""" """Returns the selected song's ID3 tags"""
return get_id3_tags(self.selected_song_filepath) return get_id3_tags(self.selected_song_filepath)
@ -359,7 +356,7 @@ class MusicTable(QTableView):
"""Returns the currently playing song filepath""" """Returns the currently playing song filepath"""
return self.current_song_filepath return self.current_song_filepath
def get_current_song_metadata(self) -> EasyID3 | dict: def get_current_song_metadata(self) -> ID3 | dict:
"""Returns the currently playing song's ID3 tags""" """Returns the currently playing song's ID3 tags"""
return get_id3_tags(self.current_song_filepath) return get_id3_tags(self.current_song_filepath)

BIN
out.mp3 Normal file

Binary file not shown.

View File

@ -21,24 +21,45 @@ def add_files_to_library(files):
if any(filepath.lower().endswith(ext) for ext in extensions): if any(filepath.lower().endswith(ext) for ext in extensions):
filename = filepath.split("/")[-1] filename = filepath.split("/")[-1]
audio = get_id3_tags(filepath) audio = get_id3_tags(filepath)
# print("add_files_to_library audio:") print("add_files_to_library audio:")
# print(audio) print(audio)
# Skip if no title is found (but should never happen # Skip if no title is found (but should never happen
if "title" not in audio: if "TIT2" not in audio:
continue continue
title = audio["TIT2"].text[0]
try:
artist = audio["TPE1"].text[0]
except KeyError:
artist = ""
try:
album = audio["TALB"].text[0]
except KeyError:
album = ""
try:
genre = audio["TCON"].text[0]
except KeyError:
genre = ""
try:
date = audio["TDRC"].text[0]
except KeyError:
date = ""
try:
bitrate = audio["TBIT"].text[0]
except KeyError:
bitrate = ""
# Append data tuple to insert_data list # Append data tuple to insert_data list
insert_data.append( insert_data.append(
( (
filepath, filepath,
safe_get(audio, "title", [])[0], title,
safe_get(audio, "album", [])[0] if "album" in audio else None, album,
safe_get(audio, "artist", [])[0] if "artist" in audio else None, artist,
",".join(safe_get(audio, "genre", [])) genre,
if "genre" in audio
else None,
filename.split(".")[-1], filename.split(".")[-1],
safe_get(audio, "date", [])[0] if "date" in audio else None, date,
safe_get(audio, "bitrate", [])[0] if "birate" in audio else None, bitrate
) )
) )
# Check if batch size is reached # Check if batch size is reached

View File

@ -1,5 +1,5 @@
from mutagen.easyid3 import EasyID3 from mutagen.id3 import ID3
from mutagen import File from mutagen.id3._frames import TIT2
import os import os
@ -12,34 +12,22 @@ def get_id3_tags(file):
if all tags are empty, at minimum fill in the 'title' if all tags are empty, at minimum fill in the 'title'
""" """
is_easy_id3 = False
try: try:
is_easy_id3 = True audio = ID3(file)
audio = EasyID3(file) except:
except Exception as e:
is_easy_id3 = False
audio = {} audio = {}
# print('get_id3_tags audio:')
# print(audio)
# Check if all tags are empty # Check if all tags are empty
tags_are_empty = all(not values for values in audio.values()) # tags_are_empty = all(not values for values in audio.values())
if tags_are_empty: try:
# split on / to get just the filename title = os.path.splitext(os.path.basename(file))[0]
# os.path.splitext to get name without extension frame = TIT2(encoding=3, text=[title])
audio["title"] = [os.path.splitext(file.split("/")[-1])[0]] audio["TIT2"] = frame
except Exception as e:
if audio["title"] is None: # I guess a song could have other tags print(f'get_id3_tags.py | Exception: {e}')
# without a title, so i make sure to have title pass
audio["title"] = [os.path.splitext(file.split("/")[-1])[0]] try:
if is_easy_id3: # i can ignore this error because of this check
audio.save() # type: ignore audio.save() # type: ignore
except:
pass
return audio return audio
# import sys
# my_file = sys.argv[1]
# data = get_id3_tags(my_file)
# print(data)

View File

@ -5,7 +5,7 @@ from mutagen.id3 import ID3
from mutagen.id3._util import ID3NoHeaderError from mutagen.id3._util import ID3NoHeaderError
from mutagen.mp3 import MP3 from mutagen.mp3 import MP3
from mutagen.easyid3 import EasyID3 from mutagen.easyid3 import EasyID3
from mutagen.id3._frames import ( from mutagen.id3 import (
Frame, Frame,
TIT2, TIT2,
TPE1, TPE1,
@ -89,49 +89,42 @@ def set_id3_tag(filepath: str, tag_name: str, value: str):
Returns: Returns:
True / False""" True / False"""
print( # print(
f"set_id3_tag.py | filepath: {filepath} | tag_name: {tag_name} | value: {value}" # f"set_id3_tag.py | filepath: {filepath} | tag_name: {tag_name} | value: {value}"
) # )
try: try:
try: # Load existing tags try: # Load existing tags
audio_file = MP3(filepath, ID3=ID3) audio_file = ID3(filepath)
except ID3NoHeaderError: # Create new tags if none exist except ID3NoHeaderError: # Create new tags if none exist
audio_file = MP3(filepath) audio_file = ID3()
audio_file.add_tags()
if tag_name == "album_date": if tag_name == "album_date":
tyer_tag, tdat_tag = handle_year_and_date_id3_tag(value) tyer_tag, tdat_tag = handle_year_and_date_id3_tag(value)
# always update TYER # always update TYER
audio_file.tags.add(tyer_tag) audio_file.add(tyer_tag)
if tdat_tag: if tdat_tag:
# update TDAT if we have it # update TDAT if we have it
audio_file.tags.add(tdat_tag) audio_file.add(tdat_tag)
elif tag_name == "lyrics": elif tag_name == "lyrics":
try:
audio = ID3(filepath) audio = ID3(filepath)
frame = USLT(encoding=3, lang="eng", desc="desc", text=value) except:
audio = ID3()
audio.delall("USLT")
frame = USLT(encoding=3, text=value)
audio.add(frame) audio.add(frame)
audio.save() audio.save()
return True
elif tag_name in id3_tag_mapping: # Tag accounted for elif tag_name in id3_tag_mapping: # Tag accounted for
tag_class = id3_tag_mapping[tag_name] tag_class = id3_tag_mapping[tag_name]
print(f"set_id3_tag.py | tag_class: {tag_class}")
# if issubclass(tag_class, EasyID3) or issubclass(tag_class, ID3): # Type safety
if issubclass(tag_class, Frame): if issubclass(tag_class, Frame):
audio_file.tags.add(tag_class(encoding=3, text=value)) # Add the tag frame = tag_class(encoding=3, text=[value])
print(f"AAAAAAAAAAAAAA") audio_file.add(frame) # Add the tag
else: else:
# dialog = ErrorDialog(f'ID3 tag not supported.\nTag: {tag_name}\nTag class: {tag_class}\nValue:{value}')
# dialog.exec_()
# return False
pass pass
else: else:
# dialog = ErrorDialog(f"Invalid ID3 tag. Tag: {tag_name}, Value:{value}")
# dialog.exec_()
# return False
pass pass
audio_file.save(v2_version=3) audio_file.save(filepath)
print("set_id3_tag.py | ID3 tags updated:")
print(get_id3_tags(filepath))
print("set_id3_tag.py | -----")
return True return True
except Exception as e: except Exception as e:
dialog = ErrorDialog(f"An unhandled exception occurred:\n{e}") dialog = ErrorDialog(f"An unhandled exception occurred:\n{e}")