delete album art for selected songs changed to delete album art for current song

This commit is contained in:
tsi-billypom 2024-09-30 16:02:25 -04:00
parent 5141b27a8c
commit 99f144892a
3 changed files with 58 additions and 66 deletions

View File

@ -111,8 +111,7 @@ class AlbumArtGraphicsView(QGraphicsView):
) # emit signal that album art was pasted ) # emit signal that album art was pasted
def delete_album_art(self): def delete_album_art(self):
"""Emits a signal for the album art to be deleted""" """Emits a signal for the album art of the current song to be deleted"""
# Signal emits and ID3 tag is updated
self.albumArtDeleted.emit() self.albumArtDeleted.emit()
def load_qapp(self, qapp): def load_qapp(self, qapp):

57
main.py
View File

@ -1,5 +1,4 @@
import os import os
import configparser
import sys import sys
import logging import logging
from subprocess import run from subprocess import run
@ -18,7 +17,6 @@ from PyQt5.QtWidgets import (
QMainWindow, QMainWindow,
QApplication, QApplication,
QGraphicsScene, QGraphicsScene,
QHeaderView,
QGraphicsPixmapItem, QGraphicsPixmapItem,
QMessageBox, QMessageBox,
QStatusBar, QStatusBar,
@ -154,7 +152,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
self.current_song_metadata: ID3 | dict | None = None self.current_song_metadata: ID3 | dict | None = None
self.current_song_album_art: bytes | None = None self.current_song_album_art: bytes | None = None
self.album_art_scene: QGraphicsScene = QGraphicsScene() self.album_art_scene: QGraphicsScene = QGraphicsScene()
self.config: ConfigParser = configparser.ConfigParser() self.config: ConfigParser = ConfigParser()
self.player: QMediaPlayer = QMediaPlayer() # Audio player object self.player: QMediaPlayer = QMediaPlayer() # Audio player object
self.probe: QAudioProbe = QAudioProbe() # Gets audio data self.probe: QAudioProbe = QAudioProbe() # Gets audio data
self.audio_visualizer: AudioVisualizer = AudioVisualizer(self.player) self.audio_visualizer: AudioVisualizer = AudioVisualizer(self.player)
@ -168,7 +166,6 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
# Audio probe for processing audio signal in real time # Audio probe for processing audio signal in real time
self.probe.setSource(self.player) self.probe.setSource(self.player)
self.probe.audioBufferProbed.connect(self.process_probe) self.probe.audioBufferProbed.connect(self.process_probe)
# Slider Timer (realtime playback feedback horizontal bar) # Slider Timer (realtime playback feedback horizontal bar)
self.timer.start(100) self.timer.start(100)
self.timer.timeout.connect(self.move_slider) self.timer.timeout.connect(self.move_slider)
@ -183,20 +180,13 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
self.PlotWidget.getAxis("left").setTicks([]) # Remove y-axis ticks self.PlotWidget.getAxis("left").setTicks([]) # Remove y-axis ticks
self.PlotWidget.getAxis("left").setLabel("") # Remove y-axis label self.PlotWidget.getAxis("left").setLabel("") # Remove y-axis label
# Playlist left-pane
# self.playlistTreeView
# Connections # Connections
self.playbackSlider.sliderReleased.connect( self.playbackSlider.sliderReleased.connect(
lambda: self.player.setPosition(self.playbackSlider.value()) lambda: self.player.setPosition(self.playbackSlider.value())
) # maybe sliderReleased works better than sliderMoved ) # sliderReleased works better than sliderMoved
self.volumeSlider.sliderMoved[int].connect( self.volumeSlider.sliderMoved[int].connect(lambda: self.volume_changed())
lambda: self.volume_changed()
) # Move slider to adjust volume
self.playButton.clicked.connect(self.on_play_clicked) # Click to play/pause self.playButton.clicked.connect(self.on_play_clicked) # Click to play/pause
self.previousButton.clicked.connect( self.previousButton.clicked.connect(self.on_previous_clicked)
self.on_previous_clicked
) # Click to previous song
self.nextButton.clicked.connect(self.on_next_clicked) # Click to next song self.nextButton.clicked.connect(self.on_next_clicked) # Click to next song
# FILE MENU # FILE MENU
@ -219,9 +209,8 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
) )
# QTableView # QTableView
self.tableView.viewport().installEventFilter( # for drag & drop functionality
self self.tableView.viewport().installEventFilter(self)
) # for drag & drop functionality
## CONNECTIONS ## CONNECTIONS
# tableView # tableView
@ -246,11 +235,9 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
self.albumGraphicsView.albumArtDropped.connect( self.albumGraphicsView.albumArtDropped.connect(
self.set_album_art_for_selected_songs self.set_album_art_for_selected_songs
) )
# FIXME: this should delete the album art for the current song - not all selected songs self.albumGraphicsView.albumArtDeleted.connect(
# Move functionality to remove album for selected songs to the batch metadata editor self.delete_album_art_for_current_song
# self.albumGraphicsView.albumArtDeleted.connect( )
# self.delete_album_art_for_selected_songs
# )
def reload_config(self) -> None: def reload_config(self) -> None:
"""does what it says""" """does what it says"""
@ -297,19 +284,21 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
def play_audio_file(self) -> None: def play_audio_file(self) -> None:
"""Start playback of tableView.current_song_filepath track & moves playback slider""" """Start playback of tableView.current_song_filepath track & moves playback slider"""
self.current_song_metadata = ( # get metadata
self.tableView.get_current_song_metadata() self.current_song_metadata = self.tableView.get_current_song_metadata()
) # get metadata logging.info("current song metadata: %s", self.current_song_metadata)
self.current_song_album_art = self.tableView.get_current_song_album_art() self.current_song_album_art = self.tableView.get_current_song_album_art()
url = QUrl.fromLocalFile( # read the file
self.tableView.get_current_song_filepath() url = QUrl.fromLocalFile(self.tableView.get_current_song_filepath())
) # read the file # load the audio content
content = QMediaContent(url) # load the audio content content = QMediaContent(url)
self.player.setMedia(content) # what content to play # set the player to play the content
self.player.setMedia(content)
self.player.play() # play self.player.play() # play
self.move_slider() # mover self.move_slider() # mover
# assign metadata # assign metadata
if self.current_song_metadata is not None:
artist = ( artist = (
self.current_song_metadata["TPE1"][0] self.current_song_metadata["TPE1"][0]
if "artist" in self.current_song_metadata if "artist" in self.current_song_metadata
@ -406,10 +395,9 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
) )
audio.save() audio.save()
def delete_album_art_for_selected_songs(self) -> None: def delete_album_art_for_current_song(self) -> None:
"""Handles deleting the ID3 tag APIC (album art) for all selected songs""" """Handles deleting the ID3 tag APIC (album art) for current song"""
filepaths = self.tableView.get_selected_songs_filepaths() file = self.tableView.get_current_song_filepath()
for file in filepaths:
# delete APIC data # delete APIC data
try: try:
audio = ID3(file) audio = ID3(file)
@ -594,6 +582,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
self.tableView.load_music_table() self.tableView.load_music_table()
def process_probe(self, buff) -> None: def process_probe(self, buff) -> None:
"""Audio visualizer buffer processing"""
buff.startTime() buff.startTime()
self.update_audio_visualization() self.update_audio_visualization()

View File

@ -1,11 +1,13 @@
import os import os
import logging import logging
from mutagen.id3 import ID3, TIT2, ID3NoHeaderError from mutagen.id3 import ID3
from mutagen.id3._frames import TIT2
from mutagen.id3._util import ID3NoHeaderError
def get_id3_tags(filename): def get_id3_tags(filename):
"""Get the ID3 tags for an audio file""" """Get the ID3 tags for an audio file"""
logging.info(f"filename: {filename}") logging.info(filename)
try: try:
# Open the MP3 file and read its content # Open the MP3 file and read its content
@ -17,7 +19,9 @@ def get_id3_tags(filename):
if os.path.exists(filename): if os.path.exists(filename):
audio.save(os.path.abspath(filename)) audio.save(os.path.abspath(filename))
# If 'TIT2' tag is not set, add it with a default value (title will be the filename without extension) # NOTE: If 'TIT2' tag is not set, we add it with a default value
# title = filename without extension
title = os.path.splitext(os.path.basename(filename))[0] title = os.path.splitext(os.path.basename(filename))[0]
list_of_id3_tags = list(audio.keys()) list_of_id3_tags = list(audio.keys())
if "TIT2" in list_of_id3_tags: if "TIT2" in list_of_id3_tags: