album art handling moved inside AlbumArtGraphicsView - maybe works
This commit is contained in:
parent
99f144892a
commit
5bd6bb5709
@ -1,6 +1,12 @@
|
|||||||
import os
|
import os
|
||||||
import tempfile
|
import tempfile
|
||||||
from PyQt5.QtWidgets import QGraphicsScene, QGraphicsView, QMenu, QAction
|
from PyQt5.QtWidgets import (
|
||||||
|
QGraphicsPixmapItem,
|
||||||
|
QGraphicsScene,
|
||||||
|
QGraphicsView,
|
||||||
|
QMenu,
|
||||||
|
QAction,
|
||||||
|
)
|
||||||
from PyQt5.QtCore import QEvent, Qt, pyqtSignal, QUrl, QPoint
|
from PyQt5.QtCore import QEvent, Qt, pyqtSignal, QUrl, QPoint
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QDragEnterEvent,
|
QDragEnterEvent,
|
||||||
@ -22,8 +28,8 @@ class AlbumArtGraphicsView(QGraphicsView):
|
|||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.setAcceptDrops(True)
|
self.setAcceptDrops(True)
|
||||||
self.setContextMenuPolicy(Qt.CustomContextMenu)
|
self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
|
||||||
self.scene = QGraphicsScene
|
self.album_art_scene: QGraphicsScene = QGraphicsScene()
|
||||||
self.customContextMenuRequested.connect(self.showContextMenu)
|
self.customContextMenuRequested.connect(self.showContextMenu)
|
||||||
|
|
||||||
def dragEnterEvent(self, event: QDragEnterEvent | None):
|
def dragEnterEvent(self, event: QDragEnterEvent | None):
|
||||||
@ -35,6 +41,8 @@ class AlbumArtGraphicsView(QGraphicsView):
|
|||||||
event.ignore()
|
event.ignore()
|
||||||
|
|
||||||
def dragMoveEvent(self, event: QDragMoveEvent | None):
|
def dragMoveEvent(self, event: QDragMoveEvent | None):
|
||||||
|
if event is None:
|
||||||
|
return
|
||||||
if event.mimeData().hasUrls():
|
if event.mimeData().hasUrls():
|
||||||
event.accept()
|
event.accept()
|
||||||
else:
|
else:
|
||||||
@ -42,6 +50,8 @@ class AlbumArtGraphicsView(QGraphicsView):
|
|||||||
|
|
||||||
def dropEvent(self, event: QDropEvent | None):
|
def dropEvent(self, event: QDropEvent | None):
|
||||||
"""Handles drag and drop pic onto view to add album art to songs"""
|
"""Handles drag and drop pic onto view to add album art to songs"""
|
||||||
|
if event is None:
|
||||||
|
return
|
||||||
urls = event.mimeData().urls()
|
urls = event.mimeData().urls()
|
||||||
if urls:
|
if urls:
|
||||||
first_url = urls[0].toLocalFile()
|
first_url = urls[0].toLocalFile()
|
||||||
@ -74,10 +84,36 @@ class AlbumArtGraphicsView(QGraphicsView):
|
|||||||
# DO
|
# DO
|
||||||
contextMenu.exec_(self.mapToGlobal(position)) # Show the menu
|
contextMenu.exec_(self.mapToGlobal(position)) # Show the menu
|
||||||
|
|
||||||
|
def load_album_art(self, album_art_data: bytes) -> None:
|
||||||
|
"""Displays the album art for the currently playing track in the GraphicsView"""
|
||||||
|
if album_art_data:
|
||||||
|
# Clear the scene
|
||||||
|
try:
|
||||||
|
self.album_art_scene.clear()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
# Reset the scene
|
||||||
|
self.setScene(self.album_art_scene)
|
||||||
|
# Create pixmap for album art
|
||||||
|
pixmap = QPixmap()
|
||||||
|
pixmap.loadFromData(album_art_data)
|
||||||
|
# Create a QGraphicsPixmapItem for more control over pic
|
||||||
|
pixmap_item = QGraphicsPixmapItem(pixmap)
|
||||||
|
pixmap_item.setTransformationMode(
|
||||||
|
Qt.TransformationMode.SmoothTransformation
|
||||||
|
) # For better quality scaling
|
||||||
|
# Add pixmap item to the scene
|
||||||
|
self.album_art_scene.addItem(pixmap_item)
|
||||||
|
# Set the scene
|
||||||
|
self.setScene(self.album_art_scene)
|
||||||
|
# Adjust the album art scaling
|
||||||
|
self.adjust_pixmap_scaling(pixmap_item)
|
||||||
|
|
||||||
def copy_album_art_to_clipboard(self):
|
def copy_album_art_to_clipboard(self):
|
||||||
"""Copies album art to the clipboard"""
|
"""Copies album art to the clipboard"""
|
||||||
if not self.scene().items():
|
if not self.scene().items():
|
||||||
return # dont care if no pic
|
return # dont care if no pic
|
||||||
|
# FIXME: i want types here. what is actually going on...
|
||||||
clipboard = self.qapp.clipboard()
|
clipboard = self.qapp.clipboard()
|
||||||
pixmap_item = self.scene().items()[0]
|
pixmap_item = self.scene().items()[0]
|
||||||
clipboard.setPixmap(pixmap_item.pixmap())
|
clipboard.setPixmap(pixmap_item.pixmap())
|
||||||
@ -96,7 +132,7 @@ class AlbumArtGraphicsView(QGraphicsView):
|
|||||||
else:
|
else:
|
||||||
pixmap = clipboard.pixmap()
|
pixmap = clipboard.pixmap()
|
||||||
# Put image on screen and emit signal for ID3 tags to be updated
|
# Put image on screen and emit signal for ID3 tags to be updated
|
||||||
if pixmap != None: # Add pixmap raw data image
|
if pixmap is not None: # Add pixmap raw data image
|
||||||
try:
|
try:
|
||||||
self.scene().clear()
|
self.scene().clear()
|
||||||
except Exception:
|
except Exception:
|
||||||
@ -114,6 +150,18 @@ class AlbumArtGraphicsView(QGraphicsView):
|
|||||||
"""Emits a signal for the album art of the current song to be deleted"""
|
"""Emits a signal for the album art of the current song to be deleted"""
|
||||||
self.albumArtDeleted.emit()
|
self.albumArtDeleted.emit()
|
||||||
|
|
||||||
|
def adjust_pixmap_scaling(self, pixmap_item) -> None:
|
||||||
|
"""Adjust the scaling of the pixmap item to fit the QGraphicsView, maintaining aspect ratio"""
|
||||||
|
viewWidth = self.width()
|
||||||
|
viewHeight = self.height()
|
||||||
|
pixmapSize = pixmap_item.pixmap().size()
|
||||||
|
# Calculate scaling factor while maintaining aspect ratio
|
||||||
|
scaleX = viewWidth / pixmapSize.width()
|
||||||
|
scaleY = viewHeight / pixmapSize.height()
|
||||||
|
scaleFactor = min(scaleX, scaleY)
|
||||||
|
# Apply scaling to the pixmap item
|
||||||
|
pixmap_item.setScale(scaleFactor)
|
||||||
|
|
||||||
def load_qapp(self, qapp):
|
def load_qapp(self, qapp):
|
||||||
"""Necessary for talking between components..."""
|
"""Necessary for talking between components..."""
|
||||||
self.qapp = qapp
|
self.qapp = qapp
|
||||||
|
|||||||
41
main.py
41
main.py
@ -287,7 +287,6 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
# get metadata
|
# get metadata
|
||||||
self.current_song_metadata = self.tableView.get_current_song_metadata()
|
self.current_song_metadata = self.tableView.get_current_song_metadata()
|
||||||
logging.info("current song metadata: %s", self.current_song_metadata)
|
logging.info("current song metadata: %s", self.current_song_metadata)
|
||||||
self.current_song_album_art = self.tableView.get_current_song_album_art()
|
|
||||||
# read the file
|
# read the file
|
||||||
url = QUrl.fromLocalFile(self.tableView.get_current_song_filepath())
|
url = QUrl.fromLocalFile(self.tableView.get_current_song_filepath())
|
||||||
# load the audio content
|
# load the audio content
|
||||||
@ -315,44 +314,8 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
self.albumLabel.setText(album)
|
self.albumLabel.setText(album)
|
||||||
self.titleLabel.setText(title)
|
self.titleLabel.setText(title)
|
||||||
# set album artwork
|
# set album artwork
|
||||||
self.load_album_art(self.current_song_album_art)
|
album_art_data = self.tableView.get_current_song_album_art()
|
||||||
|
self.albumGraphicsView.load_album_art(album_art_data)
|
||||||
def load_album_art(self, album_art_data) -> None:
|
|
||||||
"""Displays the album art for the currently playing track in the GraphicsView"""
|
|
||||||
if self.current_song_album_art:
|
|
||||||
# Clear the scene
|
|
||||||
try:
|
|
||||||
self.album_art_scene.clear()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
# Reset the scene
|
|
||||||
self.albumGraphicsView.setScene(None)
|
|
||||||
# Create pixmap for album art
|
|
||||||
pixmap = QPixmap()
|
|
||||||
pixmap.loadFromData(album_art_data)
|
|
||||||
# Create a QGraphicsPixmapItem for more control over pic
|
|
||||||
pixmap_item = QGraphicsPixmapItem(pixmap)
|
|
||||||
pixmap_item.setTransformationMode(
|
|
||||||
Qt.TransformationMode.SmoothTransformation
|
|
||||||
) # For better quality scaling
|
|
||||||
# Add pixmap item to the scene
|
|
||||||
self.album_art_scene.addItem(pixmap_item)
|
|
||||||
# Set the scene
|
|
||||||
self.albumGraphicsView.setScene(self.album_art_scene)
|
|
||||||
# Adjust the album art scaling
|
|
||||||
self.adjust_pixmap_scaling(pixmap_item)
|
|
||||||
|
|
||||||
def adjust_pixmap_scaling(self, pixmap_item) -> None:
|
|
||||||
"""Adjust the scaling of the pixmap item to fit the QGraphicsView, maintaining aspect ratio"""
|
|
||||||
viewWidth = self.albumGraphicsView.width()
|
|
||||||
viewHeight = self.albumGraphicsView.height()
|
|
||||||
pixmapSize = pixmap_item.pixmap().size()
|
|
||||||
# Calculate scaling factor while maintaining aspect ratio
|
|
||||||
scaleX = viewWidth / pixmapSize.width()
|
|
||||||
scaleY = viewHeight / pixmapSize.height()
|
|
||||||
scaleFactor = min(scaleX, scaleY)
|
|
||||||
# Apply scaling to the pixmap item
|
|
||||||
pixmap_item.setScale(scaleFactor)
|
|
||||||
|
|
||||||
def set_album_art_for_selected_songs(self, album_art_path: str) -> None:
|
def set_album_art_for_selected_songs(self, album_art_path: str) -> None:
|
||||||
"""Sets the ID3 tag APIC (album art) for all selected song filepaths"""
|
"""Sets the ID3 tag APIC (album art) for all selected song filepaths"""
|
||||||
|
|||||||
@ -1,22 +1,23 @@
|
|||||||
from mutagen.id3 import ID3, APIC
|
from mutagen.id3 import ID3, APIC
|
||||||
|
|
||||||
def get_album_art(file):
|
|
||||||
|
def get_album_art(file: str) -> bytes:
|
||||||
"""Get the album art for an audio file
|
"""Get the album art for an audio file
|
||||||
# Parameters
|
# Parameters
|
||||||
`file` | str | Fully qualified path to file
|
`file` | str | Fully qualified path to file
|
||||||
# Returns
|
# Returns
|
||||||
Data for album art or default file
|
Data for album art or default file
|
||||||
"""
|
"""
|
||||||
default_image_path = './assets/default_album_art.jpg'
|
default_image_path = "./assets/default_album_art.jpg"
|
||||||
try:
|
try:
|
||||||
audio = ID3(file)
|
audio = ID3(file)
|
||||||
for tag in audio.getall('APIC'):
|
for tag in audio.getall("APIC"):
|
||||||
if tag.type == 3: # 3 is the type for front cover
|
if tag.type == 3: # 3 is the type for front cover
|
||||||
return tag.data
|
return tag.data
|
||||||
if audio.getall('APIC'):
|
if audio.getall("APIC"):
|
||||||
return audio.getall('APIC')[0].data
|
return audio.getall("APIC")[0].data
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error retrieving album art: {e}")
|
print(f"Error retrieving album art: {e}")
|
||||||
with open(default_image_path, 'rb') as file:
|
with open(default_image_path, "rb") as f:
|
||||||
print(f'album art type: {type(file.read())}')
|
print(f"album art type: {type(f.read())}")
|
||||||
return file.read()
|
return f.read()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user