from PyQt5 import QtCore, QtGui, QtWidgets, QtMultimedia
from PyQt5.QtGui import QPixmap
from PIL import Image
from io import BytesIO
import mutagen
import eyed3
import os
import random
from interface import Ui_MediaPlayer
from equaliser import EqualizerDialog
class Player(QtWidgets.QMainWindow, Ui_MediaPlayer):
def __init__(self):
super(Player, self).__init__()
self.setupUi(self)
self.setAcceptDrops(True)
self.songsList.setDragEnabled(True)
self.setWindowTitle("NeonPlayer")
self.buttonPlay.clicked.connect(self.play)
self.songsList.itemDoubleClicked.connect(self.play)
self.buttonLoad.clicked.connect(self.load)
self.buttonDelete.clicked.connect(self.delete)
self.buttonNext.clicked.connect(self.next_track)
self.buttonPrev.clicked.connect(self.prev_track)
self.songsList.itemClicked.connect(self.song_changed)
self.songsList.itemDoubleClicked.connect(self.play_by_double_click)
self.buttonRandom.clicked.connect(self.shuffle_songs)
self.buttonRepeat.clicked.connect(self.change_repeat_status)
self.buttonEqualiser.clicked.connect(self.open_dialog)
self.dir = ""
self.playStatus = 0
self.repeatStatus = 0
self.current_position = 0
self.mediaPlayer = QtMultimedia.QMediaPlayer()
self.volumeSlider.valueChanged[int].connect(self.change_volume)
self.volumeSlider.setValue(50)
self.volume = self.volumeSlider.value()
self.mediaPlayer.setVolume(self.volume)
self.positionSlider.sliderMoved.connect(self.set_position)
self.positionSlider.sliderPressed.connect(self.slider_pressed)
self.positionSlider.sliderReleased.connect(self.slider_released)
self.positionSlider.sliderReleased.connect(self.update_current_position)
self.mediaPlayer.positionChanged.connect(self.update_current_position)
self.mediaPlayer.durationChanged.connect(self.update_duration)
self.mediaPlayer.mediaStatusChanged.connect(self.media_status_changed)
self.positionSliderTimer = QtCore.QTimer(self)
self.positionSliderTimer.timeout.connect(self.update_current_position)
self.positionSliderTimer.start(100)
self.low_boost = 1.0
self.mid_boost = 1.0
self.high_boost = 1.0
def open_dialog(self):
try:
dialog = EqualizerDialog(self)
dialog.verticalSlider_low.valueChanged.connect(self.set_low_boost)
dialog.verticalSlider_mid.valueChanged.connect(self.set_mid_boost)
dialog.verticalSlider_high.valueChanged.connect(self.set_high_boost)
dialog.exec_()
except Exception as e:
print(f"ошибка в диалоге: {e}")
def set_low_boost(self, value):
self.low_boost = value
def set_mid_boost(self, value):
self.mid_boost = value
def set_high_boost(self, value):
self.high_boost = value
def dragEnterEvent(self, event):
if event.mimeData().hasUrls():
event.acceptProposedAction()
def dropEvent(self, event):
for url in event.mimeData().urls():
file_path = url.toLocalFile()
if file_path.endswith(".mp3") and os.path.isfile(file_path):
self.songsList.addItem(QtWidgets.QListWidgetItem(file_path))
def song_changed(self):
self.mediaPlayer.stop()
if self.playStatus == 1:
self.playStatus = 0
else:
self.playStatus = 1
item = self.songsList.currentItem()
file_name = os.path.join(self.dir, item.text())
self.set_info(file_name)
self.play()
def play_by_double_click(self):
self.mediaPlayer.stop()
self.playStatus = 0
self.play()
def shuffle_songs(self):
current_items = [self.songsList.item(i).text() for i in range(self.songsList.count())]
random.shuffle(current_items)
self.songsList.clear()
self.songsList.addItems(current_items)
def play(self):
try:
if self.playStatus == 0:
if self.current_position == 0:
item = self.songsList.currentItem()
if item:
file_name = os.path.join(self.dir, item.text())
content = QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile(file_name))
self.mediaPlayer.setMedia(content)
self.mediaPlayer.play()
self.playStatus = 1
else:
self.songsList.setCurrentRow(0)
self.play()
self.set_info(file_name)
else:
self.mediaPlayer.setPosition(self.current_position)
self.mediaPlayer.play()
self.playStatus = 1
self.set_button_play_style()
else:
self.current_position = self.mediaPlayer.position()
self.mediaPlayer.stop()
self.playStatus = 0
self.set_button_play_style()
except Exception as e:
print(f"ошибка в play: {e}")
def next_track(self):
current_row = self.songsList.currentRow()
if current_row + 1 == self.songsList.count():
current_row = -1
self.songsList.setCurrentRow(current_row + 1)
item = self.songsList.currentItem()
if item:
file_name = os.path.join(self.dir, item.text())
content = QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile(file_name))
self.mediaPlayer.setMedia(content)
self.current_position = 0
if self.playStatus == 1:
self.mediaPlayer.play()
self.set_info(file_name)
else:
self.songsList.setCurrentRow(0)
if self.playStatus == 1:
self.play()
def prev_track(self):
current_row = self.songsList.currentRow()
if current_row == 0:
current_row = self.songsList.count()
self.songsList.setCurrentRow(current_row - 1)
item = self.songsList.currentItem()
if item:
file_name = os.path.join(self.dir, item.text())
content = QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile(file_name))
self.mediaPlayer.setMedia(content)
self.current_position = 0
if self.playStatus == 1:
self.mediaPlayer.play()
self.set_info(file_name)
else:
self.songsList.setCurrentRow(0)
if self.playStatus == 1:
self.play()
def load(self):
file_dialog = QtWidgets.QFileDialog()
file_dialog.setNameFilter("MP3 files (*.mp3)")
file_dialog.setFileMode(QtWidgets.QFileDialog.ExistingFile)
file_dialog.setViewMode(QtWidgets.QFileDialog.List)
if file_dialog.exec_():
selected_files = file_dialog.selectedFiles()
if selected_files:
selected_file = selected_files[0]
self.songsList.addItem(selected_file)
self.dir = os.path.dirname(selected_file)
def delete(self):
item = self.songsList.currentItem()
if item:
row = self.songsList.row(item)
self.songsList.takeItem(row)
del item
if self.playStatus == 1:
current_row = self.songsList.currentRow()
self.songsList.setCurrentRow(current_row - 1)
self.next_track()
def change_volume(self, value):
self.mediaPlayer.setVolume(value)
def update_duration(self, duration):
self.positionSlider.setMaximum(duration)
remaining_time = QtCore.QTime(0, 0)
remaining_time = remaining_time.addMSecs(duration - self.mediaPlayer.position())
self.timeCurrent.setText(remaining_time.toString("mm:ss"))
#Слайдер позиции в треке
def set_position(self, pos):
self.mediaPlayer.setPosition(pos)
def slider_pressed(self):
self.mediaPlayer.setMuted(True)
def slider_released(self):
self.mediaPlayer.setMuted(False)
self.update_current_position()
def update_current_position(self):
position = self.mediaPlayer.position()
if self.playStatus == 0:
position = self.current_position
self.positionSlider.setValue(position)
current_time = QtCore.QTime(0, 0)
current_time = current_time.addMSecs(position)
self.timeElapsed.setText(current_time.toString("mm:ss"))
#Зацикливание трека и плейлиста
def media_status_changed(self, status):
current_row = self.songsList.currentRow()
if status == QtMultimedia.QMediaPlayer.EndOfMedia and current_row + 1 != self.songsList.count():
if self.repeatStatus == 0:
self.next_track()
elif self.repeatStatus == 1:
self.current_position = 0
self.playStatus = 0
self.play()
else:
self.next_track()
elif status == QtMultimedia.QMediaPlayer.EndOfMedia and current_row + 1 == self.songsList.count():
if self.repeatStatus == 2:
self.songsList.setCurrentRow(0)
self.current_position = 0
self.playStatus = 0
self.play()
else:
self.playStatus = 0
self.set_button_play_style()
def change_repeat_status(self):
self.repeatStatus += 1
if self.repeatStatus == 3:
self.repeatStatus = 0
self.set_repeat_style()
@staticmethod
def get_artist(file_path):
audiofile = eyed3.load(file_path)
if audiofile.tag:
artist = audiofile.tag.artist
return artist
else:
return "Unknown"
@staticmethod
def get_title(file_path):
audiofile = eyed3.load(file_path)
if audiofile.tag:
title = audiofile.tag.title
return title
else:
return "Unknown"
@staticmethod
def get_picture(file_path):
audiofile = mutagen.File(file_path)
default_pic_path = 'pic/default_pic.png'
try:
for tag in audiofile.items():
if tag[0][:4] == 'APIC':
pic = tag[1]
img = Image.open(BytesIO(pic.data))
img = img.resize((310, 310), Image.Resampling.LANCZOS)
img.save("temp_cover.jpg")
return QPixmap("temp_cover.jpg")
return QtGui.QPixmap(default_pic_path)
except Exception as e:
print(f"ошибка в get_picture: {e}")
def set_info(self, file_path):
self.musicName.setText(Player.get_title(file_path))
self.singerName.setText(Player.get_artist(file_path))
pixmap = Player.get_picture(file_path)
if pixmap:
self.musicPicture.setPixmap(pixmap)
def set_button_play_style(self):
if self.playStatus == 0:
self.buttonPlay.setStyleSheet("QPushButton{\n"
" border-image: url(pic/play.png);\n"
"}\n"
"QPushButton:hover{\n"
" border-image: url(pic/play_hover.png);\n"
"}\n"
"QPushButton:pressed{\n"
" border-image: url(pic/play_pressed.png);\n"
"}")
else:
self.buttonPlay.setStyleSheet("QPushButton{\n"
" border-image: url(pic/pause.png);\n"
"}\n"
"QPushButton:hover{\n"
" border-image: url(pic/pause_hover.png);\n"
"}\n"
"QPushButton:pressed{\n"
" border-image: url(pic/pause_pressed.png);\n"
"}")
def set_repeat_style(self):
if self.repeatStatus == 0:
self.buttonRepeat.setStyleSheet("QPushButton{\n"
" border-image: url(pic/repeat.png);\n"
"}\n"
"QPushButton:hover{\n"
" border-image: url(pic/repeat_hover.png);\n"
"}\n"
"QPushButton:pressed{\n"
" border-image: url(pic/repeat.png);\n"
"}")
elif self.repeatStatus == 1:
self.buttonRepeat.setStyleSheet("QPushButton{\n"
" border-image: url(pic/repeat1.png);\n"
"}\n"
"QPushButton:hover{\n"
" border-image: url(pic/repeat1_hover.png);\n"
"}\n"
"QPushButton:pressed{\n"
" border-image: url(pic/repeat1.png);\n"
"}")
elif self.repeatStatus == 2:
self.buttonRepeat.setStyleSheet("QPushButton{\n"
" border-image: url(pic/repeat2.png);\n"
"}\n"
"QPushButton:hover{\n"
" border-image: url(pic/repeat2_hover.png);\n"
"}\n"
"QPushButton:pressed{\n"
" border-image: url(pic/repeat2.png);\n"
"}")