Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
PyQt5 Music Player
#6
Much better now. A thought occurred to me.
Why the extra exit button?
Maybe a volume slider makes more sense at this point.

#!/usr/bin/python3
# -*- coding: utf-8 -*-
from functools import partial
import os
import sys
from PyQt5.QtCore import Qt, QUrl, QDir
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QGridLayout, \
QFrame, QGraphicsDropShadowEffect, QGraphicsView, QGraphicsScene, QLabel, \
QPushButton, QHBoxLayout, QStyle, QListWidget, QFileDialog, QSlider, QVBoxLayout
from PyQt5.QtGui import QGradient, QFont, QColor, QCursor, QIcon, QPixmap
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent, QMediaPlaylist, \
QMediaMetaData
 
 
class Window(QMainWindow):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setWindowTitle('PyQt5 Music Player')
 
        # Create a containers
        btn_box = QHBoxLayout()
        btn_box2 = QHBoxLayout()
        container = QGridLayout()
        info_container = QGridLayout()
        frame = QFrame()
        frame.setFrameShape(QFrame.Box)
        frame.setFrameShadow(QFrame.Sunken)
        frame.setLayout(info_container)
 
 
 
 
        # Create some variables
        self.dir = f'{QDir.currentPath()}'
        self.url = QUrl()
        self.player = QMediaPlayer()
        self.content = QMediaContent()
        self.playlist = QMediaPlaylist(self.player)
        self.player.setPlaylist(self.playlist)
 
        # Used to changed to notify self.update that the playlist index has changed.
        # Will update the highlighted line in the listbox
        self.playlist.currentIndexChanged.connect(self.update)
 
        # Signal that the metadate has changed
        self.player.metaDataChanged.connect(self.meta_data)
 
        # Labels for the track information
        self.artist = QLabel('Artist: ')
        self.album_title = QLabel('Album: ')
        self.track_title = QLabel('Track: ')
        self.released = QLabel('Released: ')
        self.genre = QLabel('Genre: ')
        self.art = QLabel()
 
 
        # Add track information to the info container
        info_container.addWidget(self.artist, 0, 0, 1, 1)
        info_container.addWidget(self.album_title, 1, 0, 1, 1)
        info_container.addWidget(self.track_title, 2, 0, 1, 1)
        info_container.addWidget(self.released, 3, 0, 1, 1)
        info_container.addWidget(self.genre, 4, 0, 1, 1)
        info_container.addWidget(self.art, 5, 0, 1, 1)
 
        # Create the status and track labels
        self.status = QLabel('Status: ')
        self.status.setFrameShape(QFrame.Box)
        self.status.setFrameShadow(QFrame.Sunken)
 
        self.track = QLabel('Track: ')
        self.track.setFrameShape(QFrame.Box)
        self.track.setFrameShadow(QFrame.Sunken)
 
        # Define and create the listbox
        self.musiclist = QListWidget()
        self.musiclist.setFrameShape(QFrame.Box)
        self.musiclist.setFrameShadow(QFrame.Sunken)
        self.musiclist.setStyleSheet('background-color: snow;')
 
        # Used for track play when double clicked
        self.musiclist.itemDoubleClicked.connect(self._doubleclick)
 
        # Create the control buttons & button styles
        btn_style = '''QPushButton{background-color: skyblue;}
                       QPushButton:hover{background-color: lightskyblue; color: dodgerblue; \
                       font-weight: bold;}'''
 
        # Create buttons for getting audio files and clearing playlist
        file_btn = QPushButton('Get Audio')
        file_btn.setIcon(self.style().standardIcon(QStyle.SP_DirOpenIcon))
        file_btn.released.connect(self._files)
        file_btn.setCursor(Qt.PointingHandCursor)
        file_btn.setStyleSheet(btn_style)
        file_btn.setMaximumWidth(100)
 
        clear_btn = QPushButton('Clear List')
        clear_btn.setIcon(self.style().standardIcon(QStyle.SP_TrashIcon))
        clear_btn.released.connect(self._clear)
        clear_btn.setCursor(Qt.PointingHandCursor)
        clear_btn.setStyleSheet(btn_style)
        clear_btn.setMaximumWidth(100)
 
        # Create & style the control buttons
        self.play_btn = QPushButton('Play')
        self.play_btn.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.play_btn.released.connect(self._state)
        self.play_btn.setCursor(Qt.PointingHandCursor)
        self.play_btn.setStyleSheet(btn_style)
 
        self.prev_btn = QPushButton('Prev')
        self.prev_btn.setIcon(self.style().standardIcon(QStyle.SP_MediaSkipBackward))
        self.prev_btn.released.connect(self._prev)
        self.prev_btn.setCursor(Qt.PointingHandCursor)
        self.prev_btn.setStyleSheet(btn_style)
 
        self.next_btn = QPushButton('Next')
        self.next_btn.setIcon(self.style().standardIcon(QStyle.SP_MediaSkipForward))
        self.next_btn.released.connect(self._next)
        self.next_btn.setCursor(Qt.PointingHandCursor)
        self.next_btn.setStyleSheet(btn_style)
 
        self.stop_btn = QPushButton('Stop')
        self.stop_btn.setIcon(self.style().standardIcon(QStyle.SP_MediaStop))
        self.stop_btn.released.connect(self._stop)
        self.stop_btn.setCursor(Qt.PointingHandCursor)
        self.stop_btn.setStyleSheet(btn_style)
        
        self.vol_slider = QSlider(orientation=1)
        self.vol_slider.setFixedWidth(80)
        self.vol_slider.setRange(0, 100)
        self.vol_slider.valueChanged.connect(self.set_volume)
        self.vol_slider.setValue(75)
        self.vol_slider.setStyleSheet("""QSlider::groove:horizontal {
                                        border: 1px solid #999999;
                                        height: 8px;
                                        background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #686da0, stop:1 #c4c4c4);
                                        margin: 2px 0;
}

                                        QSlider::handle:horizontal {
                                            background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #729fcf, stop:1 #3465a4);
                                            border: 1px solid #5c5c5c;
                                            width: 18px;
                                            margin: -2px 0;
                                            border-radius: 3px;}""")
 
        self.exit_btn = QPushButton('Exit')
        self.exit_btn.released.connect(sys.exit)
        self.exit_btn.setCursor(Qt.PointingHandCursor)
        self.exit_btn.setStyleSheet('QPushButton{background-color: firebrick;} \
                                    QPushButton:hover{background-color: red; color: white; \
                                    font-weight: bold;}')
 
 
        # Add the buttons to layout
        btn_box.addWidget(file_btn)
        btn_box.addWidget(clear_btn)
        btn_box2.addWidget(self.play_btn)
        btn_box2.addWidget(self.prev_btn)
        btn_box2.addWidget(self.next_btn)
        btn_box2.addWidget(self.stop_btn)
        btn_box2.addWidget(self.vol_slider)
 
 
        # Add layouts to container layout
        container.addWidget(self._header_footer(100, 100, 40, 'PyQt5 Music Player'), 0, 0, 1, 3)
        container.addWidget(self.status, 1, 0, 1, 1)
        container.addWidget(self.track, 1, 1, 1, 1)
        container.addLayout(btn_box, 1, 2, 1, 1)
        container.addWidget(frame, 2, 0, 2, 1)
        container.addWidget(self.musiclist, 2, 1, 1, 2)
        container.addLayout(btn_box2, 3, 1, 1, 2)
        container.addWidget(self._header_footer(40, 40, 10, 'my-python.org - 10/16/2021'), 4, 0, 1, 3)
 
        # Create the widget and add the button box layout
        widget = QWidget()
        widget.setLayout(container)
        self.setCentralWidget(widget)
        
    def set_volume(self):
        self.player.setVolume(self.vol_slider.value())
 
    # Get music metadata
    def meta_data(self):
        if self.player.isMetaDataAvailable():
            self.artist.setText(f'Artist: {self.player.metaData(QMediaMetaData.AlbumArtist)}')
            self.album_title.setText(f'Album: {self.player.metaData(QMediaMetaData.AlbumTitle)}')
            self.track_title.setText(f'Track: {self.player.metaData(QMediaMetaData.Title)}')
            self.released.setText(f'Released: {self.player.metaData(QMediaMetaData.Year)}')
            self.genre.setText(f'Genre: {self.player.metaData(QMediaMetaData.Genre)}')
            self.track.setText(f'Track: {self.player.metaData(QMediaMetaData.Title)}')
            pixmap = QPixmap(self.player.metaData(QMediaMetaData.CoverArtImage))
            pixmap = pixmap.scaled(int(pixmap.width()/3), int(pixmap.height()/3))
            self.art.setPixmap(pixmap)
 
    # Create the header
    def _header_footer(self, minheight, maxheight, fontsize, text):
        shadow = QGraphicsDropShadowEffect()
        shadow.setBlurRadius(3)
        shadow.setOffset(3, 3)
 
        scene = QGraphicsScene()
 
        view = QGraphicsView()
        view.setMinimumSize(800, minheight)
        view.setMaximumHeight(maxheight)
        view.setScene(scene)
 
        gradient = QGradient(QGradient.RichMetal)
 
        scene.setBackgroundBrush(gradient)
 
        font = QFont('comic sans ms', fontsize, QFont.Bold)
 
        text = scene.addText(text)
        text.setDefaultTextColor(QColor(250,250,250))
        text.setFont(font)
 
        text.setGraphicsEffect(shadow)
 
        return view
 
    # Method for double clicking a track and play
    def _doubleclick(self):
        self.playlist.setCurrentIndex(self.musiclist.currentRow())
        self.player.play()
 
    # Method for clearing the playlist and musiclist
    def _clear(self):
        self.player.stop()
        self.musiclist.clear()
        self.playlist.clear()
        self.play_btn.setText('Play')
        self.status.setText('Status: ')
        self.track.setText('Track: ')
        self.artist.setText('Artist: ')
        self.album_title.setText('Album: ')
        self.track_title.setText('Track: ')
        self.released.setText('Released: ')
        self.genre.setText('Genre: ')
        pixmap = QPixmap()
        self.art.setPixmap(pixmap)
 
 
    # Method for adding tracks to the playlist and musiclist
    def _files(self):
        files = QFileDialog.getOpenFileNames(None, 'Get Audio Files',
                                         filter='Audio Files (*.mp3 *.ogg *.wav)')
 
        for file in files[0]:
            self.playlist.addMedia(QMediaContent(self.url.fromLocalFile(file)))
            file = file.split('/')
            self.musiclist.addItem(f'{file[-1][:-4]}')
 
        self.musiclist.setCurrentRow(0)
        self.playlist.setCurrentIndex(0)
 
    # Methods for the control buttons
    def _prev(self):
        if self.playlist.previousIndex() == -1:
            self.playlist.setCurrentIndex(self.playlist.mediaCount()-1)
        else:
            self.playlist.previous()
 
    def _next(self):
        self.playlist.next()
        if self.playlist.currentIndex() == -1:
            self.playlist.setCurrentIndex(0)
            self.player.play()
 
    def _stop(self):
        self.player.stop()
        self.play_btn.setText('Play')
        self.playlist.setCurrentIndex(0)
        self.musiclist.setCurrentRow(0)
        self.status.setText('Status: Now Stopped')
 
    def _state(self):
        if self.playlist.mediaCount() > 0:
            if self.player.state() != QMediaPlayer.PlayingState:
                self.play_btn.setText('Pause')
                self.status.setText('Status: Now Playing')
                self.player.setVolume(self.vol_slider.value())
                self.player.play()
            else:
                self.play_btn.setText('Play')
                self.player.pause()
                self.status.setText('Status: Now Paused')
 
        else:
            pass
 
    # Method for updating the listbox when the playlist updates
    def update(self):
        self.musiclist.setCurrentRow(self.playlist.currentIndex())
        if self.playlist.currentIndex() < 0:
            self.musiclist.setCurrentRow(0)
            self.playlist.setCurrentIndex(0)
 
def main():
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec())
 
if __name__ == '__main__':
    main()
Reply


Messages In This Thread
PyQt5 Music Player - by menator01 - Oct-14-2021, 09:38 AM
RE: PyQt5 Music Player - by Larz60+ - Oct-14-2021, 08:49 PM
RE: PyQt5 Music Player - by Axel_Erfurt - Oct-14-2021, 09:16 PM
RE: PyQt5 Music Player - by menator01 - Oct-15-2021, 05:58 AM
RE: PyQt5 Music Player - by menator01 - Oct-16-2021, 09:44 PM
RE: PyQt5 Music Player - by Axel_Erfurt - Oct-16-2021, 10:49 PM
RE: PyQt5 Music Player - by menator01 - Oct-16-2021, 11:00 PM
RE: PyQt5 Music Player - by Axel_Erfurt - Oct-17-2021, 09:26 PM
RE: PyQt5 Music Player - by menator01 - Oct-17-2021, 10:03 PM
RE: PyQt5 Music Player - by Axel_Erfurt - Oct-18-2021, 04:09 PM
RE: PyQt5 Music Player - by Axel_Erfurt - Oct-18-2021, 05:12 PM
RE: PyQt5 Music Player - by menator01 - Oct-18-2021, 06:44 PM
RE: PyQt5 Music Player - by Axel_Erfurt - Oct-19-2021, 05:21 PM
RE: PyQt5 Music Player - by menator01 - Oct-29-2021, 06:49 PM
RE: PyQt5 Music Player - by menator01 - Nov-02-2021, 09:34 AM
RE: PyQt5 Music Player - by Axel_Erfurt - Nov-02-2021, 08:04 PM
RE: PyQt5 Music Player - by menator01 - Nov-03-2021, 08:30 AM
RE: PyQt5 Music Player - by Axel_Erfurt - Nov-03-2021, 09:05 AM
RE: PyQt5 Music Player - by menator01 - Nov-03-2021, 09:06 AM
RE: PyQt5 Music Player - by Axel_Erfurt - Nov-03-2021, 09:11 AM
RE: PyQt5 Music Player - by menator01 - Nov-03-2021, 05:49 PM
RE: PyQt5 Music Player - by Axel_Erfurt - Nov-03-2021, 05:59 PM

Possibly Related Threads…
Thread Author Replies Views Last Post
  Basic Music Player with tkinter menator01 4 4,773 Jul-31-2021, 04:27 AM
Last Post: ndc85430

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020