class Window(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self, parent=None): super().__init__(parent) # load config self.data = yaml_loader() # load ui self.setupUi(self) # load icons self.setWindowTitle("Sputofy") self.setWindowIcon(QIcon(os.path.join(RES_PATH, "logo.svg"))) loopIcon = QIcon() loopIcon.addPixmap(QPixmap(os.path.join(RES_PATH, "loopIconOFF.svg"))) self.loopBtn.setIcon(loopIcon) prevIcon = QIcon() prevIcon.addPixmap(QPixmap(os.path.join(RES_PATH, "backwardIcon.svg"))) self.prevBtn.setIcon(prevIcon) playIcon = QIcon() playIcon.addPixmap(QPixmap(os.path.join(RES_PATH, "playIcon.svg"))) self.playBtn.setIcon(playIcon) nextIcon = QIcon() nextIcon.addPixmap(QPixmap(os.path.join(RES_PATH, "forwardIcon.svg"))) self.nextBtn.setIcon(nextIcon) randomIcon = QIcon() randomIcon.addPixmap( QPixmap(os.path.join(RES_PATH, "randomIconOFF.svg"))) self.randomBtn.setIcon(randomIcon) volumeIcon = QIcon() volumeIcon.addPixmap(QPixmap(os.path.join(RES_PATH, "volumeIcon.svg"))) self.volumeBtn.setIcon(volumeIcon) # window's settings self.xCor = self.data['last_position']['xPos'] self.yCor = self.data['last_position']['yPos'] self.widthSize = self.data['last_window_size']['width'] self.heightSize = self.data['last_window_size']['height'] self.setGeometry(self.xCor, self.yCor, self.widthSize, self.heightSize) # load YouTubeToMP3 self.YouTubeToMP3 = YouTubeToMP3Window() # open YouTubeToMP3 using button self.actionYT_MP3.triggered.connect(self.YouTubeToMP3.show_window) # info action self.actionInfo.triggered.connect(self.info_handle) #=========================== mediaplayer ============================== # create media player object self.mediaPlayer = QMediaPlayer(None) # open button self.actionOpen_Song.triggered.connect(self.open_song) self.actionOpen_Folder.triggered.connect(self.open_folder) # play button self.playBtn.setEnabled(False) self.playBtn.clicked.connect( self.play_video ) # when btn is pressed: if it is playing it pause, if it is paused it plays # QShortcut(QKeySequence("Space"), self).activated.connect(self.play_video)metodo da ricordare in caso di problemi #TODO # duration slider self.durationSlider.setEnabled(False) self.durationSliderMaxValue = 0 self.durationSlider.valueChanged.connect( self.mediaPlayer.setPosition ) # set mediaPlayer position using the value took from the slider QShortcut('Right', self, lambda: self.durationSlider.setValue( self.durationSlider.value() + 10000)) # 1s = 1000ms QShortcut('Left', self, lambda: self.durationSlider.setValue( self.durationSlider.value() - 10000)) # 1s = 1000ms QShortcut('Shift+Right', self, lambda: self.durationSlider.setValue( self.durationSliderMaxValue - 1000)) # jump to the end-1s of song QShortcut('Shift+Left', self, lambda: self.durationSlider.setValue(0)) # restart song # volumeSlider self.volumeSlider.setProperty("value", 100) self.volumeSlider.setRange(0, 100) self.volumeSlider.setValue( self.data['volume'] if self.data['volume'] != 0 else self.data['volume'] + 1 ) # set slider value | if saved volume is equal to 0 load with volume = 1 else load the saved volume self.mediaPlayer.setVolume( self.data['volume'] if self.data['volume'] != 0 else self.data['volume'] + 1 ) # set mediaPlayer volume | if saved volume is equal to 0 load with volume = 1 else load the saved volume self.volumeLabel.setText( f"{self.data['volume']}%" if self.data['volume'] != 0 else f"{self.data['volume']+1}%" ) # set volume label text | if saved volume is equal to 0 load with volume = 1 else load the saved volume self.volumeSlider.valueChanged.connect( self.mediaPlayer.setVolume ) # set mediaPlayer volume using the value took from the slider QShortcut('Up', self, lambda: self.volumeSlider.setValue( self.volumeSlider.value() + 1)) # volume + 1 QShortcut('Down', self, lambda: self.volumeSlider.setValue( self.volumeSlider.value() - 1)) # volume - 1 QShortcut( 'Shift+Up', self, lambda: self.volumeSlider.setValue(100)) # set maximum volume QShortcut( 'Shift+Down', self, lambda: self.volumeSlider.setValue(0)) # set minimun volume(mute) # volumeBtn self.volumeBtn.clicked.connect( self.volume_toggle) # mute/unmute volume pressing btn self.isMuted = False # starting with a non-muted volume self.previousVolume = self.data[ 'volume'] # loading last registered volume # media player signals self.mediaPlayer.durationChanged.connect( self.duration_changed) # set range of duration slider self.mediaPlayer.positionChanged.connect( self.position_changed) # duration slider progress self.mediaPlayer.stateChanged.connect( self.player_state) # see when it's playing or in pause self.mediaPlayer.volumeChanged.connect( self.volume_icon) # change volumebtn icon #=========================== playlist ============================== # create the playlist self.playlist = QMediaPlaylist() self.playlist.setPlaybackMode(2) self.mediaPlayer.setPlaylist(self.playlist) # clear the playlist self.playlistIsEmpty = True # playlistList model self.model = PlaylistModel(self.playlist) self.playlistView.setModel(self.model) self.playlist.currentIndexChanged.connect( self.playlist_position_changed) selection_model = self.playlistView.selectionModel() selection_model.selectionChanged.connect( self.playlist_selection_changed) #=========================== playlist function ============================== self.mediaList = [] # array of loaded songs self.currentPlaylist = "" # current loaded playlist name self.isCustomPlaylist = False # add song name on title self.playlist.currentMediaChanged.connect(self.set_title) # playlist buttons self.nextBtn.clicked.connect(self.next_song) # seek track forward self.prevBtn.clicked.connect(self.prev_song) # seek track backward self.mediaPlayer.mediaStatusChanged.connect( self.auto_next_track ) # once song is ended seek track forward and play it self.actionLoopIt.triggered.connect( self.loop_song) # (1) loop the same song self.actionShuffle.triggered.connect( self.shuffle_playlist) # change song's order self.loopBtn.clicked.connect(self.loop) # (3) loop the playlist self.randomBtn.clicked.connect( self.random) # (4) play random song without end # create new playlist self.actionCreatePlaylist.triggered.connect(self.custom_playlist) # delete current playlist self.actionDeletePlaylist.triggered.connect(self.delete_playlist) # remove all songs self.actionClearQueue.triggered.connect(self.clear_queue) # load playlist self.actionDict = {} # dictionary of action Objects for action in self.data['playlistList']: self.actionDict[action] = self.menuPlaylist.addAction( action, partial(self.load_playlist, action)) if len(self.data['playlistList']) == 0: self.menuPlaylist.menuAction().setVisible(False) #================== Songs opening ==================# def open_folder(self): foldername = QFileDialog.getExistingDirectory(self, "Open folder", "c:\\") if foldername: self.playlist.clear() self.mediaList.clear() for song in os.listdir(foldername): media = f"{foldername}/{song}" self.playlist.addMedia(QMediaContent(QUrl(media))) self.mediaList.append(media) self.playlist.setCurrentIndex(0) self.playBtn.setEnabled(True) self.durationSlider.setEnabled(True) self.playlistIsEmpty = False self.isCustomPlaylist = False self.model.layoutChanged.emit() # load songs in list view self.set_title() self.mediaPlayer.pause() # adjust play/pause icon def open_song(self): filename, _ = QFileDialog.getOpenFileName(self, "Open Song", "c:\\") if filename: if self.playlistIsEmpty == False: self.playlist.clear() self.mediaList.clear() self.playlistIsEmpty = True self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(filename))) self.mediaList.append(filename) self.playBtn.setEnabled(True) self.durationSlider.setEnabled(True) self.isCustomPlaylist = False self.model.layoutChanged.emit() # load song in list view self.set_title() # adjust play/pause icon if self.playlist.mediaCount( ) == 1: # if there is 1 song and you add another self.playlist.setCurrentIndex(0) self.mediaPlayer.pause() def load_playlist(self, playlistName): self.playlist.clear() self.mediaList.clear() # reload config self.data = yaml_loader() for song in self.data['playlistList'][playlistName]: self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(song))) self.mediaList.append(song) self.playlist.setCurrentIndex(0) self.playBtn.setEnabled(True) self.durationSlider.setEnabled(True) self.playlistIsEmpty = False self.isCustomPlaylist = True self.model.layoutChanged.emit() # load songs in list view self.currentPlaylist = playlistName # name of current loaded playlist self.set_title() self.statusbar.showMessage(f'Playlist "{playlistName}" loaded', 4000) self.menuPlaylist.menuAction().setVisible(True) # adjust play/pause icon self.mediaPlayer.pause() def set_title(self): if self.playlist.mediaCount() == 0: self.setWindowTitle("Sputofy") else: if self.isCustomPlaylist == False: self.setWindowTitle( f"Sputofy - {os.path.splitext(self.playlist.currentMedia().canonicalUrl().fileName())[0]} - {self.playlist.currentIndex()+1}/{self.playlist.mediaCount()}" ) else: self.setWindowTitle( f"Sputofy - {self.currentPlaylist} - {os.path.splitext(self.playlist.currentMedia().canonicalUrl().fileName())[0]} - {self.playlist.currentIndex()+1}/{self.playlist.mediaCount()}" ) #=======================================================# #================== Player Functions ==================# def play_video(self): if self.durationSlider.isEnabled(): # if slider was enabled if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def duration_changed(self, duration): self.durationSlider.setRange(0, duration) if duration > 0: self.totalTime_Label.setText(time_format(round( duration / 1000))) # duration is in ms self.durationSliderMaxValue = duration def position_changed(self, position): if position >= 0: self.elapsedTime_Label.setText(time_format( (position / 1000))) # position is in ms # Disable the events to prevent updating triggering a setPosition event (can cause stuttering). self.durationSlider.blockSignals(True) self.durationSlider.setValue(position) self.durationSlider.blockSignals(False) #=======================================================# #================== Playlist Settings ==================# #TODO Work in progress def playlist_array(self): index = self.playlist.mediaCount() mediaList = [] for i in range(index): # songPath = (self.playlist.media(path).canonicalUrl().path())#.split("/",1)[1] # mediaList.append(songPath) # print(self.playlist.media(i).canonicalUrl().path()) mediaList.append(self.playlist.media(i).canonicalUrl().fileName()) return mediaList def custom_playlist(self): if not self.playlist.mediaCount() == 0: name, is_notEmpty = QInputDialog.getText(self, "playlist", "save playlist as:") if name: if name in self.data['playlistList']: self.statusbar.showMessage( "playlist not created (name is already used)", 4000) else: self.data['playlistList'][name] = self.mediaList yaml_dump(self.data) # add new action Object to dictionary self.actionDict[name] = self.menuPlaylist.addAction( name, partial(self.load_playlist, name)) self.load_playlist( name) # instantly loading the new playlist else: self.statusbar.showMessage( "playlist not created (you should give a name to your baby :/)", 4000) else: self.statusbar.showMessage("there are no songs to playlist", 4000) def delete_playlist(self): if self.isCustomPlaylist: if len(self.data['playlistList']) == 1: self.menuPlaylist.menuAction().setVisible(False) self.data['playlistList'].pop( self.currentPlaylist) # remove playlist from dictionary self.menuPlaylist.removeAction(self.actionDict[ self.currentPlaylist]) # remove relative action self.actionDict.pop( self.currentPlaylist) # remove relative action Object self.playlist.clear() self.model.layoutChanged.emit() self.setWindowTitle("Sputofy") yaml_dump(self.data) self.statusbar.showMessage( 'succesfully deleted "' + self.currentPlaylist + '" playlist', 4000) else: self.statusbar.showMessage("cannot delete a non custom playlist", 4000) def clear_queue(self): self.playlist.clear() self.mediaList.clear() self.playBtn.setEnabled(False) self.model.layoutChanged.emit() def playlist_position_changed(self, i): if i > -1: ix = self.model.index(i) self.playlistView.setCurrentIndex(ix) def playlist_selection_changed(self, ix): # We receive a QItemSelection from selectionChanged. i = ix.indexes()[0].row() self.posizione = i self.playlist.setCurrentIndex(i) self.mediaPlayer.play() #=======================================================# #================== Playback Settings ==================# def next_song(self): if self.playlist.currentIndex() == self.playlist.mediaCount() - 1: self.playlist.setCurrentIndex(0) else: self.playlist.next() def prev_song(self): if self.playlist.currentIndex() == 0: self.playlist.setCurrentIndex(self.playlist.mediaCount() - 1) else: self.playlist.previous() def loop_song(self): if self.playlist.playbackMode() != 1: self.playlist.setPlaybackMode(1) self.actionLoopIt.setText("Loop it: ON") self.loopBtn.setIcon( QIcon(os.path.join(RES_PATH, "loopIconOFF.svg"))) self.randomBtn.setIcon( QIcon(os.path.join(RES_PATH, "randomIconOFF.svg"))) else: self.playlist.setPlaybackMode(2) self.actionLoopIt.setText("Loop it: OFF") def shuffle_playlist(self): if self.playlist.mediaCount(): self.playlist.shuffle() self.model.layoutChanged.emit() else: self.statusbar.showMessage("there are no songs to shuffle", 4000) def loop(self): if self.playlist.playbackMode() != 3: self.playlist.setPlaybackMode(3) self.loopBtn.setIcon( QIcon(os.path.join(RES_PATH, "loopIconON.svg"))) self.randomBtn.setIcon( QIcon(os.path.join(RES_PATH, "randomIconOFF.svg"))) self.actionLoopIt.setText("Loop it: OFF") else: self.playlist.setPlaybackMode(2) self.loopBtn.setIcon( QIcon(os.path.join(RES_PATH, "loopIconOFF.svg"))) def random(self): if self.playlist.playbackMode() != 4: self.playlist.setPlaybackMode(4) self.randomBtn.setIcon( QIcon(os.path.join(RES_PATH, "randomIconON.svg"))) self.loopBtn.setIcon( QIcon(os.path.join(RES_PATH, "loopIconOFF.svg"))) self.actionLoopIt.setText("Loop it: OFF") else: self.playlist.setPlaybackMode(2) self.randomBtn.setIcon( QIcon(os.path.join(RES_PATH, "randomIconOFF.svg"))) def auto_next_track(self): if self.mediaPlayer.mediaStatus() == QMediaPlayer.EndOfMedia: if self.playlist.playbackMode() == 2: # index starts from 0 mediacount starts from 1 if self.playlist.currentIndex( ) != self.playlist.mediaCount() - 1: self.playlist.next() self.mediaPlayer.play() else: # if ended song was the last one set the index to the first one and pause self.playlist.setCurrentIndex(0) self.mediaPlayer.pause() # loop playlist elif self.playlist.playbackMode() == 3: self.playlist.next() self.mediaPlayer.play() # random song elif self.playlist.playbackMode() == 4: while self.playlist.previousIndex( ) == self.playlist.currentIndex( ): # preventing repeating the same song self.playlist.setCurrentIndex( random.randint(0, self.playlist.mediaCount() - 1)) #=======================================================# #================== Volume Settings ==================# def volume_icon(self, volume): self.volumeLabel.setText(f"{volume}%") if volume: volumeIcon = QIcon() volumeIcon.addPixmap( QPixmap(os.path.join(RES_PATH, "volumeIcon.svg")), QIcon.Normal, QIcon.Off) self.volumeBtn.setIcon(volumeIcon) self.previousVolume = self.volumeSlider.value() self.isMuted = False else: volumeMutedIcon = QIcon() volumeMutedIcon.addPixmap( QPixmap(os.path.join(RES_PATH, "volumeMutedIcon.svg")), QIcon.Normal, QIcon.Off) self.volumeBtn.setIcon(volumeMutedIcon) self.isMuted = True def volume_toggle(self): if self.isMuted == False: self.volumeSlider.setValue(0) self.isMuted = True elif self.isMuted == True: if self.previousVolume == 0: self.volumeSlider.setValue(10) else: self.volumeSlider.setValue(self.previousVolume) self.isMuted = False #=======================================================# def mousePressEvent(self, event): ''' remove the border around the buttons created by using tab key ''' focused_widget = QtWidgets.QApplication.focusWidget() try: focused_widget.clearFocus() except: pass QMainWindow.mousePressEvent(self, event) def player_state(self, event): ''' event handler that adjust the play/pause icon ''' if event == QMediaPlayer.PlayingState: pauseIcon = QIcon() pauseIcon.addPixmap( QPixmap(os.path.join(RES_PATH, "pauseIcon.svg")), QIcon.Normal, QIcon.Off) self.playBtn.setIcon(pauseIcon) elif event == QMediaPlayer.PausedState: playIcon = QIcon() playIcon.addPixmap(QPixmap(os.path.join(RES_PATH, "playIcon.svg")), QIcon.Normal, QIcon.Off) self.playBtn.setIcon(playIcon) def closeEvent(self, event): ''' event handler that take window information and save it in config before the window close ''' # retrieve position xAxis = self.geometry().x() yAxis = self.geometry().y() self.data['last_position']['xPos'] = xAxis self.data['last_position']['yPos'] = yAxis # retrieve size width = self.width() height = self.height() self.data['last_window_size']['width'] = width self.data['last_window_size']['height'] = height # retrieve volume self.data['volume'] = self.mediaPlayer.volume() # retrieve user user = os.getlogin() self.data[ 'default_folder'] = f"C:\\Users\\{user}\\Desktop\\sputofy_songs" yaml_dump(self.data) def info_handle(self): info = "Sputofy\n1.0.0\n©2020 "+\ "Sputofy is a free audio player based on the converted youtube songs made by a_str0\n\n"+\ "Sputofy is written using python 3.x and PyQt5 modules" msg = QMessageBox.about(self, "About", info)
class Ui_Dialog(QMainWindow): def __init__(self): super().__init__() self.player = QMediaPlayer() self.playlist = QMediaPlaylist() self.palette = QPalette() self.VerticalLayout = QVBoxLayout() self.userAction = -1 # 0- stopped, 1- playing 2-paused self.width = 550 self.height = 700 self.PlayerIsActive = 0 # 0 - not active, 1 - active self.nameFont = 'Plug_2.png' self.msgBox = QMessageBox() def setupUi(self, Dialog): Dialog.resize(self.width, self.height) Dialog.setWindowTitle('MyPlayer') Dialog.setWindowIcon(QIcon(self.nameFont)) # Add MainMenu self.mainMenu = QMenuBar(Dialog) self.fileMenu = self.mainMenu.addMenu('File') self.ChangeThemeMenu = self.mainMenu.addMenu('Change') self.DataBaseSongs = self.mainMenu.addMenu('Recommend') self.helpMenu = self.mainMenu.addMenu('About') # Add In Menu Actions self.openAction = QAction('Open File') self.openAction.setShortcut('Ctrl+O') self.openActions = QAction('Open Directory') self.exitAction = QAction('Exit') self.exitAction.setShortcut('Ctrl+Q') self.loadBackgroung = QAction('Load my background') self.changeBlack = QAction('Change Black') self.changeWhite = QAction('Change white') self.RecommendedDataBase = QAction('Recommended data base of songs') self.Developer = QAction('About Developer') self.Program = QAction('About Program') self.Help_ = QAction('Help') # Add to Menus Actions self.fileMenu.addAction(self.openAction) self.fileMenu.addAction(self.openActions) self.fileMenu.addAction(self.exitAction) self.ChangeThemeMenu.addAction(self.changeBlack) self.ChangeThemeMenu.addAction(self.changeWhite) self.ChangeThemeMenu.addAction(self.loadBackgroung) self.DataBaseSongs.addAction(self.RecommendedDataBase) self.helpMenu.addAction(self.Developer) self.helpMenu.addAction(self.Program) self.helpMenu.addAction(self.Help_) # Create Slider Volume self.volumeslider = QSlider(Qt.Horizontal, Dialog) self.volumeslider.setFocusPolicy(Qt.NoFocus) self.volumeslider.setGeometry(420, 650, 120, 30) self.volumeslider.setValue(100) self.volumeslider.setTickInterval(20) self.volumeslider.setTickPosition(QSlider.TicksBelow) self.volumeslider.valueChanged[int].connect(self.changeVolume) #Create Slider Status of song self.songSlider = QSlider(Qt.Horizontal, Dialog) self.songSlider.setGeometry(17, 602, 521, 15) self.songSlider.setRange(0, 0) self.songSlider.sliderMoved.connect(self.set_position) # Add labels self.timeInStart = QLabel(Dialog) self.timeInStart.setGeometry(10, 612, 70, 25) self.AllTimeSong = QLabel(Dialog) self.AllTimeSong.setGeometry(500, 610, 70, 25) self.PictureAlbum = QLabel(Dialog) self.PictureAlbum.setGeometry(20, 170, 300, 300) self.showInfoToMusic_1 = QLabel(Dialog) self.showInfoToMusic_2 = QLabel(Dialog) self.showInfoToMusic_3 = QLabel(Dialog) self.showInfoToMusic_4 = QLabel(Dialog) # Add labals in Vertical layout widget self.verticalLayoutWidget = QtWidgets.QWidget(Dialog) self.verticalLayoutWidget.setGeometry(QtCore.QRect(350, 230, 200, 200)) self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.showInfoToMusic_1 = QtWidgets.QLabel(self.verticalLayoutWidget) self.verticalLayout.addWidget(self.showInfoToMusic_1) self.showInfoToMusic_1.setFont(QtGui.QFont("Times", 12, QtGui.QFont.Bold)) self.showInfoToMusic_2 = QtWidgets.QLabel(self.verticalLayoutWidget) self.verticalLayout.addWidget(self.showInfoToMusic_2) self.showInfoToMusic_2.setFont(QtGui.QFont("Times", 12, QtGui.QFont.Bold)) self.showInfoToMusic_3 = QtWidgets.QLabel(self.verticalLayoutWidget) self.verticalLayout.addWidget(self.showInfoToMusic_3) self.showInfoToMusic_3.setFont(QtGui.QFont("Times", 12, QtGui.QFont.Bold)) self.showInfoToMusic_4 = QtWidgets.QLabel(self.verticalLayoutWidget) self.verticalLayout.addWidget(self.showInfoToMusic_4) self.showInfoToMusic_4.setFont(QtGui.QFont("Times", 12, QtGui.QFont.Bold)) #Create buttons #initialization self.PlayBtn = QPushButton(Dialog) self.StopBtn = QPushButton(Dialog) self.BreakBtn = QPushButton(Dialog) self.NextBtn = QPushButton(Dialog) self.PrevBtn = QPushButton(Dialog) self.shuffleBtn = QPushButton(Dialog) #Show buttons self.PlayBtn.setGeometry(QtCore.QRect(245, 630, 60, 60)) self.PlayBtn.setStyleSheet('''background: transparent; border-image: url(Play.png) ''') self.StopBtn.setGeometry(QtCore.QRect(190, 635, 55, 55)) self.StopBtn.setStyleSheet('''background: transparent; border-image: url(Stop.png)''') self.BreakBtn.setGeometry(QtCore.QRect(305, 635, 55, 55)) self.BreakBtn.setStyleSheet('''background: transparent; border-image: url(Break.png) ''') self.NextBtn.setGeometry(QtCore.QRect(355, 635, 55, 55)) self.NextBtn.setStyleSheet('''background: transparent; border-image: url(Next_song.png) ''') self.PrevBtn.setGeometry(QtCore.QRect(140, 635, 55, 55)) self.PrevBtn.setStyleSheet('''background: transparent; border-image: url(Prev_song.png) ''') self.shuffleBtn.setGeometry(QtCore.QRect(90, 635, 55, 55)) self.shuffleBtn.setStyleSheet('''background: transparent; border-image: url(Shuffle_.png) ''') # Events self.player.positionChanged.connect(self.position_changed) self.player.durationChanged.connect(self.duration_changed) self.RecommendedDataBase.triggered.connect(self.connect_list) self.exitAction.triggered.connect(self.quit_trigger) self.openAction.triggered.connect(self.file_open) self.openActions.triggered.connect(self.addFiles) self.PlayBtn.clicked.connect(self.playMusic) self.BreakBtn.clicked.connect(self.stopMusic) self.StopBtn.clicked.connect(self.pauseMusic) self.PrevBtn.clicked.connect(self.prevSong) self.shuffleBtn.clicked.connect(self.shufflelist) self.NextBtn.clicked.connect(self.nextSong) self.loadBackgroung.triggered.connect(self.LoadYourBackground) self.changeBlack.triggered.connect(self.ChangeBlackTheme) self.changeWhite.triggered.connect(self.ChangeWhiteTheme) self.Developer.triggered.connect(self.AboutDeveloper) self.Program.triggered.connect(self.AboutProgram) self.Help_.triggered.connect(self.Help) self.ChangeBlackTheme() QtCore.QMetaObject.connectSlotsByName(Dialog) # Triggered function def AboutDeveloper(self): textOnDev = open('Developer.txt').read() self.msgBox.setStyleSheet('QMessageBox {background-image: url(BlackFont.png)}') self.msgBox.setText('About Developer') self.msgBox.setInformativeText(textOnDev) self.msgBox.setStandardButtons(QMessageBox.Close) self.msgBox.show() def AboutProgram(self): TextOnDev = open('Program.txt').read() self.msgBox.setStyleSheet('QMessageBox {background-image: url(BlackFont.png)}') self.msgBox.setText('About Program') self.msgBox.setInformativeText(TextOnDev) self.msgBox.setStandardButtons(QMessageBox.Close) self.msgBox.show() def Help(self): TextOnDev = open('Help.txt').read() self.msgBox.setStyleSheet('QMessageBox {background-image: url(BlackFont.png)}') self.msgBox.setText('Help') self.msgBox.setInformativeText(TextOnDev) self.msgBox.setStandardButtons(QMessageBox.Close) self.msgBox.show() def connect_list(self): self.w2 = Window2() dic_music = MusicParser.parse() x = 550 y = 50 for i, j in dic_music.items(): #h = QLabel(self.w2) #h.setGeometry(10,0, x,y) verticalLayoutWidget = QtWidgets.QWidget(self.w2) verticalLayoutWidget.setGeometry(QtCore.QRect(10, 0, x, y)) verticalLayout = QtWidgets.QVBoxLayout(verticalLayoutWidget) verticalLayout.setContentsMargins(0, 0, 0, 0) left_label = QLabel(verticalLayoutWidget) verticalLayout.addWidget(left_label) left_label.setFont(QtGui.QFont("Times", 9, QtGui.QFont.Bold)) left_label.setText(i + ' - ' + j) y += 60 self.w2.show() def position_changed(self, position): self.songSlider.setValue(position) self.timeInStart.setText(str(time.strftime("%M:%S", time.gmtime(position / 1000)))) def duration_changed(self, duration): self.songSlider.setRange(0, duration) def set_position(self, position): self.player.setPosition(position) def quit_trigger(self): qApp.quit() def file_open(self): self.song = QFileDialog.getOpenFileName(self, "Open Song", "", "Sound Files (*.mp3 *.ogg *.wav *.m4a)") if self.song[0] != '': self.PlayerIsActive = 1 url = QUrl.fromLocalFile(self.song[0]) if self.playlist.mediaCount() == 0: self.playlist.addMedia(QMediaContent(url)) self.player.setPlaylist(self.playlist) self.player.play() self.userAction = 1 else: self.playlist.addMedia(QMediaContent(url)) if self.PlayerIsActive == 1: self.showImage() self.ShowInfoAboutSong() self.showSlider() def showSlider(self): self.songSlider.setMaximum(self.long) def showImage(self): self.audioFile = mutagen.File(self.song[0]) pixmap_1 = QPixmap('Plug_2.png').scaled(300, 300) try: photo = self.audioFile.tags.getall('APIC')[0].data pixmap = QPixmap() pixmap.loadFromData(photo) pixmap.scaled(300, 300) self.PictureAlbum.setPixmap(pixmap) except IndexError: self.PictureAlbum.setPixmap(pixmap_1) def ShowInfoAboutSong(self): #Open song in mutagen audioFile = mutagen.File(self.song[0]) #Create time label (all time song) self.long = audioFile.info.length #Open all info about song and editing singer = audioFile.tags.getall('TPE1') song_title = audioFile.tags.getall('TIT2') YearOfSong = audioFile.tags.getall('TDRC') Bitrate = (audioFile.info.bitrate) // 1000 singer = str(singer[0]) song_title = str(song_title[0]) #show all info on labels try: self.AllTimeSong.setText(str(time.strftime("%M:%S", time.gmtime(round(self.long))))) self.showInfoToMusic_1.setToolTip(singer.encode('latin1').decode('cp1251')) self.showInfoToMusic_2.setToolTip(song_title.encode('latin1').decode('cp1251')) self.showInfoToMusic_1.setText(singer.encode('latin1').decode('cp1251')) self.showInfoToMusic_2.setWordWrap(True) self.showInfoToMusic_2.setText(song_title.encode('latin1').decode('cp1251')) self.showInfoToMusic_2.setWordWrap(True) self.showInfoToMusic_3.setText(str(YearOfSong[0])) self.showInfoToMusic_4.setText(str(Bitrate) + ' kbps') except IndexError: self.showInfoToMusic.setText('') except UnicodeEncodeError: self.showInfoToMusic_2.setText(song_title) self.showInfoToMusic_1.setText(singer) def show_more_music(self): try: self.audioFile = mutagen.File(self.sp_songs[self.playlist.currentIndex()]) pixmap_1 = QPixmap('Plug_2.png').scaled(300, 300) try: photo = self.audioFile.tags.getall('APIC')[0].data pixmap = QPixmap() pixmap.loadFromData(photo) pixmap.scaled(300, 300) self.PictureAlbum.setPixmap(pixmap) except IndexError: self.PictureAlbum.setPixmap(pixmap_1) except IndexError: pass try: self.index = 0 audioFile = mutagen.File(self.sp_songs[self.playlist.currentIndex()]) self.long = audioFile.info.length singer = audioFile.tags.getall('TPE1') song_title = audioFile.tags.getall('TIT2') YearOfSong = audioFile.tags.getall('TDRC') Bitrate = (audioFile.info.bitrate) // 1000 singer = str(singer[0]) song_title = str(song_title[0]) try: self.AllTimeSong.setText(str(time.strftime("%M:%S", time.gmtime(round(self.long))))) self.showInfoToMusic_1.setToolTip(singer.encode('latin1').decode('cp1251')) self.showInfoToMusic_2.setToolTip(song_title.encode('latin1').decode('cp1251')) self.showInfoToMusic_1.setText(singer.encode('latin1').decode('cp1251')) self.showInfoToMusic_2.setWordWrap(True) self.showInfoToMusic_2.setText(song_title.encode('latin1').decode('cp1251')) self.showInfoToMusic_2.setWordWrap(True) self.showInfoToMusic_3.setText(str(YearOfSong[0])) self.showInfoToMusic_4.setText(str(Bitrate) + ' kbps') except IndexError: self.showInfoToMusic.setText('') except UnicodeEncodeError: self.showInfoToMusic_2.setText(song_title) self.showInfoToMusic_1.setText(singer) except IndexError: pass def addFiles(self): if self.playlist.mediaCount() != 0: self.folderIterator() else: self.folderIterator() self.player.setPlaylist(self.playlist) self.player.playlist().setCurrentIndex(0) self.player.play() self.userAction = 1 self.PlayerIsActive = 1 self.show_more_music() self.playlist.currentIndexChanged.connect(self.show_more_music) def folderIterator(self): folderChosen = QFileDialog.getExistingDirectory(self, 'Open Music Folder', '') if folderChosen != None: it = QDirIterator(folderChosen) it.next() self.sp_songs = [] while it.hasNext(): if it.fileInfo().isDir() == False and it.filePath() != '.': fInfo = it.fileInfo() if fInfo.suffix() in ('mp3', 'ogg', 'wav', 'm4a'): self.sp_songs.append(it.filePath()) self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(it.filePath()))) it.next() if it.fileInfo().isDir() == False and it.filePath() != '.': self.sp_songs.append(it.filePath()) fInfo = it.fileInfo() if fInfo.suffix() in ('mp3', 'ogg', 'wav', 'm4a'): self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(it.filePath()))) def ChangeBlackTheme(self): oImage = QImage("BlackFont.png") sImage = oImage.scaled(QtCore.QSize(self.width, self.height)) self.palette.setBrush(QPalette.Window, QBrush(sImage)) self.palette.setColor(QPalette.Text, Qt.white) self.palette.setColor(QPalette.WindowText, Qt.white) self.palette.setColor(QPalette.ToolTipText, Qt.white) QApplication.setPalette(self.palette) def ChangeWhiteTheme(self): oImage = QImage("WhiteFont_.jpg") sImage = oImage.scaled(QtCore.QSize(self.width, self.height)) self.palette.setBrush(QPalette.Window, QBrush(sImage)) self.palette.setColor(QPalette.Text, Qt.black) self.palette.setColor(QPalette.WindowText, Qt.black) self.palette.setColor(QPalette.ToolTipText, Qt.black) QApplication.setPalette(self.palette) def LoadYourBackground(self): font = QFileDialog.getOpenFileName(self, "Open Image", "", "Image Files (*.png *.jpg *.JPEG )") oImage = QImage(font[0]) sImage = oImage.scaled(QtCore.QSize(self.width, self.height)) self.palette.setBrush(QPalette.Window, QBrush(sImage)) self.palette.setColor(QPalette.Text, Qt.white) self.palette.setColor(QPalette.WindowText, Qt.white) self.palette.setColor(QPalette.ToolTipText, Qt.white) QApplication.setPalette(self.palette) def playMusic(self): if self.playlist.mediaCount() == 0: self.file_open() elif self.playlist.mediaCount() != 0: self.player.play() self.userAction = 1 self.PlayerIsActive = 1 def pauseMusic(self): self.userAction = 2 self.player.pause() self.PlayerIsActive = 0 def stopMusic(self): self.PlayerIsActive = 0 self.userAction = 0 self.player.stop() self.playlist.clear() def changeVolume(self, value): self.player.setVolume(value) def prevSong(self): if self.playlist.mediaCount() == 0: self.file_open() elif self.playlist.mediaCount() != 0: self.player.playlist().previous() try: self.show_more_music() except AttributeError: pass def shufflelist(self): if self.playlist.mediaCount() == 0: self.file_open() elif self.playlist.mediaCount() != 0: try: self.show_more_music() self.playlist.shuffle() except AttributeError: pass def nextSong(self): if self.playlist.mediaCount() == 0: self.file_open() elif self.playlist.mediaCount() != 0: try: self.player.playlist().next() self.show_more_music() except AttributeError: pass
class App(QMainWindow): def __init__(self): super().__init__() self.player = QMediaPlayer() self.playlist = QMediaPlaylist() self.title = 'Personal audio player v2.3' self.left = 300 self.top = 300 self.width = 300 self.height = 150 self.color = 0 # 0- toggle to dark 1- toggle to light self.userAction = -1 # 0- stopped, 1- playing 2-paused self.duration = 0 #self.getRecommendedPlaylist() self.initUI() def initUI(self): # Add file menu menubar = self.menuBar() filemenu = menubar.addMenu('File') windowmenu = menubar.addMenu('Window') connectTo = menubar.addMenu('Connect to...') fileAct = QAction('Open File', self) folderAct = QAction('Open Folder', self) themeAct = QAction('Toggle light/dark theme', self) yandexMusic = QAction('Yandex Music', self) deezer = QAction('Deezer', self) spotify = QAction('Spotify', self) pandora = QAction('Pandora', self) mixcloud = QAction('Pandora', self) fileAct.setShortcut('Ctrl+O') folderAct.setShortcut('Ctrl+D') themeAct.setShortcut('Ctrl+T') filemenu.addAction(fileAct) filemenu.addAction(folderAct) windowmenu.addAction(themeAct) connectTo.addAction(yandexMusic) connectTo.addAction(deezer) connectTo.addAction(pandora) connectTo.addAction(mixcloud) connectTo.addAction(spotify) fileAct.triggered.connect(self.openFile) folderAct.triggered.connect(self.addFiles) themeAct.triggered.connect(self.toggleColors) yandexMusic.triggered.connect(self.connectYandexMusic) deezer.triggered.connect(self.connectYandexMusic) pandora.triggered.connect(self.connectYandexMusic) mixcloud.triggered.connect(self.connectYandexMusic) spotify.triggered.connect(self.connectYandexMusic) self.addControls() self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) self.toggleColors() self.show() def downloadTrack(self, name): page = requests.get("http://zaycev.net/search.html?query_search=" + name).text parser = fromstring(page) fileJSON = parser.xpath('//div/@data-url') resp = requests.get("http://zaycev.net" + fileJSON[1]) data = resp.json() with open("track.json", 'w') as outfile: json.dump(data, outfile) connection_file = open("track.json", 'r') conn_string = json.load(connection_file) track = requests.get(conn_string['url'].rsplit('?')[0]) try: os.makedirs('./tracks') except OSError: pass out = open("./tracks/" + name.strip() + ".mp3", 'wb') out.write(track.content) out.close() QMessageBox.about(self, "Track added!", name.strip() + " was added") def playRecommend(self): try: similarTracks = open("playlist.txt", 'r') i = 0 for line in similarTracks.readlines(): if i == 5: break else: i = i+1 print(line) self.downloadTrack(line) self.openFileRec("./tracks/" + line.strip() + ".mp3") except: QMessageBox.about(self, "Play error!", "Unknown error!") def getRecommendedPlaylist(self, song): try: audio = ID3(song[0]) title = ''.join(audio['TIT2'].text[0].rsplit('(')[0]) if title[-1] == ' ': title = title[0:-1] artist = audio['TPE1'].text[0] if artist[-1] == ' ': artist = artist[0:-1] print(artist + " " + title) resp = requests.get("http://ws.audioscrobbler.com/2.0/?method=track.getsimilar&artist=" + artist + "&track=" + title + "&api_key=API_key&format=json") data = resp.json() with open("playlist" + artist + "-" + title + ".json", 'w') as outfile: json.dump(data, outfile) connection_file = open("playlist" + artist + "-" + title + ".json", 'r') conn_string = json.load(connection_file) with open("playlist.txt", 'a') as playlistFile: for track in conn_string['similartracks']['track']: playlistFile.write(track['artist']['name'] + " " + track['name'] + "\n") playlistFile.close() except: QMessageBox.about(self, "Error!", "Some trouble with export title or artist name, try other track") def getRecommendedPlaylistFolder(self, song): audio = ID3(song) title = ''.join(audio['TIT2'].text[0].rsplit('(')[0]) if title[-1] == ' ': title = title[0:-1] artist = audio['TPE1'].text[0] if artist[-1] == ' ': artist = artist[0:-1] print(artist + " " + title) resp = requests.get("http://ws.audioscrobbler.com/2.0/?method=track.getsimilar&artist=" + artist + "&track=" + title + "&api_key=API_key&format=json") data = resp.json() with open("playlist" + artist + "-" + title + ".json", 'w') as outfile: json.dump(data, outfile) connection_file = open("playlist" + artist + "-" + title + ".json", 'r') conn_string = json.load(connection_file) with open("playlist.txt", 'a') as playlistFile: for track in conn_string['similartracks']['track']: playlistFile.write(track['artist']['name'] + " " + track['name'] + "\n") playlistFile.close() def addControls(self): wid = QWidget(self) self.setCentralWidget(wid) # Add song controls volumeslider = QSlider(Qt.Horizontal, self) volumeslider.setFocusPolicy(Qt.NoFocus) volumeslider.valueChanged[int].connect(self.changeVolume) volumeslider.setValue(50) sldPosition = QSlider(Qt.Horizontal, self) sldPosition.setMinimum(0) sldPosition.setFocusPolicy(Qt.NoFocus) #sldPosition.valueChanged.connect(self.player.setPosition) self.player.positionChanged.connect(sldPosition.setValue) sldPosition.setMaximum(180000) playBtn = QPushButton('Play') # play button pauseBtn = QPushButton('Pause') # pause button stopBtn = QPushButton('Stop') # stop button # Add playlist controls prevBtn = QPushButton('Prev') shuffleBtn = QPushButton('Shuffle') nextBtn = QPushButton('Next') playRecommendedBtn = QPushButton('Play Recommended Playlist') like = QPushButton('Like') dislike = QPushButton('DisLike') # Add button layouts controlArea = QVBoxLayout() # centralWidget controls = QHBoxLayout() playlistCtrlLayout = QHBoxLayout() playRec = QHBoxLayout() ld = QHBoxLayout() # Add buttons to song controls layout controls.addWidget(playBtn) controls.addWidget(pauseBtn) controls.addWidget(stopBtn) # Add buttons to playlist controls layout playlistCtrlLayout.addWidget(prevBtn) playlistCtrlLayout.addWidget(shuffleBtn) playlistCtrlLayout.addWidget(nextBtn) playRec.addWidget(playRecommendedBtn) ld.addWidget(like) ld.addWidget(dislike) # Add to vertical layout controlArea.addWidget(sldPosition) controlArea.addWidget(volumeslider) controlArea.addLayout(controls) controlArea.addLayout(playlistCtrlLayout) controlArea.addLayout(playRec) controlArea.addLayout(ld) wid.setLayout(controlArea) # Connect each signal to their appropriate function playBtn.clicked.connect(self.playhandler) pauseBtn.clicked.connect(self.pausehandler) stopBtn.clicked.connect(self.stophandler) prevBtn.clicked.connect(self.prevSong) shuffleBtn.clicked.connect(self.shufflelist) nextBtn.clicked.connect(self.nextSong) playRecommendedBtn.clicked.connect(self.playRecommend) like.clicked.connect(self.like) dislike.clicked.connect(self.dislike) self.statusBar() self.playlist.currentMediaChanged.connect(self.songChanged) def like(self, text): QMessageBox.about(self, "Attention!", "You have Liked track!") def dislike(self, text): QMessageBox.about(self, "Attention!", "You have DisLiked track!") def connectYandexMusic(self): apple = LoginWindow() apple.exec_() def openFile(self): print("File button clicked!") song = QFileDialog.getOpenFileName(self, "Open Song", "~", "Sound Files (*.mp3 *.ogg *.wav *.m4a)") print(song[0]) if song[0] != '': url = QUrl.fromLocalFile(song[0]) if self.playlist.mediaCount() == 0: self.playlist.addMedia(QMediaContent(url)) self.player.setPlaylist(self.playlist) self.player.play() self.userAction = 1 print(self.playlist.mediaCount()) else: self.playlist.addMedia(QMediaContent(url)) print(self.playlist.mediaCount()) self.getRecommendedPlaylist(song) def openFileRec(self, path): song = path if song != '': url = QUrl.fromLocalFile(song) if self.playlist.mediaCount() == 0: self.playlist.addMedia(QMediaContent(url)) self.player.setPlaylist(self.playlist) self.player.play() self.userAction = 1 print(self.playlist.mediaCount()) else: self.playlist.addMedia(QMediaContent(url)) print(self.playlist.mediaCount()) def addFiles(self): print("Folder button clicked!") if self.playlist.mediaCount() != 0: self.folderIterator() print(self.playlist.mediaCount()) else: self.folderIterator() self.player.setPlaylist(self.playlist) self.player.playlist().setCurrentIndex(0) self.player.play() print(self.playlist.mediaCount()) self.userAction = 1 def folderIterator(self): folderChosen = QFileDialog.getExistingDirectory(self, 'Open Music Folder', '~') if folderChosen != None: it = QDirIterator(folderChosen) it.next() while it.hasNext(): if it.fileInfo().isDir() == False and it.filePath() != '.': fInfo = it.fileInfo() print(it.filePath(), fInfo.suffix()) if fInfo.suffix() in ('mp3', 'ogg', 'wav', 'm4a'): print('added file', fInfo.fileName()) self.getRecommendedPlaylistFolder(it.filePath()) self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(it.filePath()))) it.next() if it.fileInfo().isDir() == False and it.filePath() != '.': fInfo = it.fileInfo() print(it.filePath(), fInfo.suffix()) if fInfo.suffix() in ('mp3', 'ogg', 'wav', 'm4a'): print('added file', fInfo.fileName()) self.getRecommendedPlaylistFolder(it.filePath()) self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(it.filePath()))) def playhandler(self): if self.playlist.mediaCount() == 0: self.openFile() elif self.playlist.mediaCount() != 0: self.player.play() print(self.playlist.mediaCount()) self.userAction = 1 def pausehandler(self): self.userAction = 2 self.player.pause() def stophandler(self): self.userAction = 0 self.player.stop() self.playlist.clear() print("Playlist cleared!") self.statusBar().showMessage("Stopped and cleared playlist") def changeVolume(self, value): self.player.setVolume(value) def changePosition(self, value): self.player.setPosition(value) def prevSong(self): if self.playlist.mediaCount() == 0: self.openFile() elif self.playlist.mediaCount() != 0: self.player.playlist().previous() def shufflelist(self): self.playlist.shuffle() print("Shuffled playlist!") def nextSong(self): if self.playlist.mediaCount() == 0: self.openFile() elif self.playlist.mediaCount() != 0: self.player.playlist().next() def songChanged(self, media): if not media.isNull(): url = media.canonicalUrl() self.statusBar().showMessage(url.fileName()) def toggleColors(self): app.setStyle("Fusion") palette = QPalette() if self.color == 0: palette.setColor(QPalette.Window, QColor(53, 53, 53)) palette.setColor(QPalette.WindowText, Qt.white) palette.setColor(QPalette.Base, QColor(25, 25, 25)) palette.setColor(QPalette.AlternateBase, QColor(53, 53, 53)) palette.setColor(QPalette.ToolTipBase, Qt.white) palette.setColor(QPalette.ToolTipText, Qt.white) palette.setColor(QPalette.Text, Qt.white) palette.setColor(QPalette.Button, QColor(53, 53, 53)) palette.setColor(QPalette.ButtonText, Qt.white) palette.setColor(QPalette.BrightText, Qt.red) palette.setColor(QPalette.Link, QColor(235, 101, 54)) palette.setColor(QPalette.Highlight, QColor(235, 101, 54)) palette.setColor(QPalette.HighlightedText, Qt.black) app.setPalette(palette) self.color = 1 elif self.color == 1: palette.setColor(QPalette.Window, Qt.white) palette.setColor(QPalette.WindowText, Qt.black) palette.setColor(QPalette.Base, QColor(240, 240, 240)) palette.setColor(QPalette.AlternateBase, Qt.white) palette.setColor(QPalette.ToolTipBase, Qt.white) palette.setColor(QPalette.ToolTipText, Qt.white) palette.setColor(QPalette.Text, Qt.black) palette.setColor(QPalette.Button, Qt.white) palette.setColor(QPalette.ButtonText, Qt.black) palette.setColor(QPalette.BrightText, Qt.red) palette.setColor(QPalette.Link, QColor(66, 155, 248)) palette.setColor(QPalette.Highlight, QColor(66, 155, 248)) palette.setColor(QPalette.HighlightedText, Qt.black) app.setPalette(palette) self.color = 0
class App(QMainWindow): def __init__(self): super().__init__() self.player = QMediaPlayer() self.playlist = QMediaPlaylist() self.title = 'PyTunes' self.left = 300 self.top = 300 self.width = 300 self.height = 150 self.color = 0 # 0- toggle to dark 1- toggle to light self.userAction = -1 # 0- stopped, 1- playing 2-paused self.initUI() def initUI(self): # Add file menu menubar = self.menuBar() filemenu = menubar.addMenu('File') windowmenu = menubar.addMenu('Window') fileAct = QAction('Open File', self) folderAct = QAction('Open Folder', self) themeAct = QAction('Toggle light/dark theme', self) fileAct.setShortcut('Ctrl+O') folderAct.setShortcut('Ctrl+D') themeAct.setShortcut('Ctrl+T') filemenu.addAction(fileAct) filemenu.addAction(folderAct) windowmenu.addAction(themeAct) fileAct.triggered.connect(self.openFile) folderAct.triggered.connect(self.addFiles) themeAct.triggered.connect(self.toggleColors) self.addControls() self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) self.toggleColors() self.show() def addControls(self): wid = QWidget(self) self.setCentralWidget(wid) # Add song controls volumeslider = QSlider(Qt.Horizontal, self) volumeslider.setFocusPolicy(Qt.NoFocus) volumeslider.valueChanged[int].connect(self.changeVolume) volumeslider.setValue(100) playBtn = QPushButton('Play') # play button pauseBtn = QPushButton('Pause') # pause button stopBtn = QPushButton('Stop') # stop button # Add playlist controls prevBtn = QPushButton('Prev') shuffleBtn = QPushButton('Shuffle') nextBtn = QPushButton('Next') # Add button layouts controlArea = QVBoxLayout() # centralWidget controls = QHBoxLayout() playlistCtrlLayout = QHBoxLayout() # Add buttons to song controls layout controls.addWidget(playBtn) controls.addWidget(pauseBtn) controls.addWidget(stopBtn) # Add buttons to playlist controls layout playlistCtrlLayout.addWidget(prevBtn) playlistCtrlLayout.addWidget(shuffleBtn) playlistCtrlLayout.addWidget(nextBtn) # Add to vertical layout controlArea.addWidget(volumeslider) controlArea.addLayout(controls) controlArea.addLayout(playlistCtrlLayout) wid.setLayout(controlArea) # Connect each signal to their appropriate function playBtn.clicked.connect(self.playhandler) pauseBtn.clicked.connect(self.pausehandler) stopBtn.clicked.connect(self.stophandler) prevBtn.clicked.connect(self.prevSong) shuffleBtn.clicked.connect(self.shufflelist) nextBtn.clicked.connect(self.nextSong) self.statusBar() self.playlist.currentMediaChanged.connect(self.songChanged) def openFile(self): song = QFileDialog.getOpenFileName( self, "Open Song", "~", "Sound Files (*.mp3 *.ogg *.wav *.m4a)") if song[0] != '': url = QUrl.fromLocalFile(song[0]) if self.playlist.mediaCount() == 0: self.playlist.addMedia(QMediaContent(url)) self.player.setPlaylist(self.playlist) self.player.play() self.userAction = 1 else: self.playlist.addMedia(QMediaContent(url)) def addFiles(self): if self.playlist.mediaCount() != 0: self.folderIterator() else: self.folderIterator() self.player.setPlaylist(self.playlist) self.player.playlist().setCurrentIndex(0) self.player.play() self.userAction = 1 def folderIterator(self): folderChosen = QFileDialog.getExistingDirectory( self, 'Open Music Folder', '~') if folderChosen != None: it = QDirIterator(folderChosen) it.next() while it.hasNext(): if it.fileInfo().isDir() == False and it.filePath() != '.': fInfo = it.fileInfo() if fInfo.suffix() in ('mp3', 'ogg', 'wav', 'm4a'): self.playlist.addMedia( QMediaContent(QUrl.fromLocalFile(it.filePath()))) it.next() if it.fileInfo().isDir() == False and it.filePath() != '.': fInfo = it.fileInfo() if fInfo.suffix() in ('mp3', 'ogg', 'wav', 'm4a'): self.playlist.addMedia( QMediaContent(QUrl.fromLocalFile(it.filePath()))) def playhandler(self): if self.playlist.mediaCount() == 0: self.openFile() elif self.playlist.mediaCount() != 0: self.player.play() self.userAction = 1 def pausehandler(self): self.userAction = 2 self.player.pause() def stophandler(self): self.userAction = 0 self.player.stop() self.playlist.clear() self.statusBar().showMessage("Stopped and cleared playlist") def changeVolume(self, value): self.player.setVolume(value) def prevSong(self): if self.playlist.mediaCount() == 0: self.openFile() elif self.playlist.mediaCount() != 0: self.player.playlist().previous() def shufflelist(self): self.playlist.shuffle() def nextSong(self): if self.playlist.mediaCount() == 0: self.openFile() elif self.playlist.mediaCount() != 0: self.player.playlist().next() def songChanged(self, media): if not media.isNull(): url = media.canonicalUrl() self.statusBar().showMessage(url.fileName()) def toggleColors(self): app.setStyle("Fusion") palette = QPalette() if self.color == 0: palette.setColor(QPalette.Window, QColor(53, 53, 53)) palette.setColor(QPalette.WindowText, Qt.white) palette.setColor(QPalette.Base, QColor(25, 25, 25)) palette.setColor(QPalette.AlternateBase, QColor(53, 53, 53)) palette.setColor(QPalette.ToolTipBase, Qt.white) palette.setColor(QPalette.ToolTipText, Qt.white) palette.setColor(QPalette.Text, Qt.white) palette.setColor(QPalette.Button, QColor(53, 53, 53)) palette.setColor(QPalette.ButtonText, Qt.white) palette.setColor(QPalette.BrightText, Qt.red) palette.setColor(QPalette.Link, QColor(235, 101, 54)) palette.setColor(QPalette.Highlight, QColor(235, 101, 54)) palette.setColor(QPalette.HighlightedText, Qt.black) app.setPalette(palette) self.color = 1 elif self.color == 1: palette.setColor(QPalette.Window, Qt.white) palette.setColor(QPalette.WindowText, Qt.black) palette.setColor(QPalette.Base, QColor(240, 240, 240)) palette.setColor(QPalette.AlternateBase, Qt.white) palette.setColor(QPalette.ToolTipBase, Qt.white) palette.setColor(QPalette.ToolTipText, Qt.white) palette.setColor(QPalette.Text, Qt.black) palette.setColor(QPalette.Button, Qt.white) palette.setColor(QPalette.ButtonText, Qt.black) palette.setColor(QPalette.BrightText, Qt.red) palette.setColor(QPalette.Link, QColor(66, 155, 248)) palette.setColor(QPalette.Highlight, QColor(66, 155, 248)) palette.setColor(QPalette.HighlightedText, Qt.black) app.setPalette(palette) self.color = 0
class MyWindow(QMainWindow): text_update = pyqtSignal(str) # Create main window def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.central = QWidget(self) self.player = QMediaPlayer() self.playlist = QMediaPlaylist() self.inference = Inference() self.folder_chosen = False self.textbox = QTextEdit(self.central) self.textbox.setFont(TEXT_FONT) self.textbox.setMinimumSize(300, 100) self.text_update.connect(self.append_text) sys.stdout = self print("Camera number %u" % camera_num) print("Image size %u x %u" % IMG_SIZE) if DISP_SCALE > 1: print("Display scale %u:1" % DISP_SCALE) self.vlayout = QVBoxLayout() # Window layout self.displays = QHBoxLayout() self.disp = ImageWidget(self) self.displays.addWidget(self.disp) self.vlayout.addLayout(self.displays) self.label = QLabel(self) self.vlayout.addWidget(self.label) self.vlayout.addWidget(self.textbox) # TODO provision for allowing song to play # DONE self.current_song_start_time = datetime.now() volumeslider = QSlider(Qt.Horizontal, self) volumeslider.setFocusPolicy(Qt.NoFocus) volumeslider.valueChanged[int].connect(self.changeVolume) volumeslider.setValue(100) playBtn = QPushButton('Play') # play button pauseBtn = QPushButton('Pause') # pause button stopBtn = QPushButton('Stop') # stop button # Add playlist controls prevBtn = QPushButton('Prev') shuffleBtn = QPushButton('Shuffle') nextBtn = QPushButton('Next') # Add button layouts #controlArea = QVBoxLayout() # centralWidget controls = QHBoxLayout() playlistCtrlLayout = QHBoxLayout() # Add buttons to song controls layout controls.addWidget(playBtn) controls.addWidget(pauseBtn) controls.addWidget(stopBtn) # Add buttons to playlist controls layout playlistCtrlLayout.addWidget(prevBtn) playlistCtrlLayout.addWidget(shuffleBtn) playlistCtrlLayout.addWidget(nextBtn) # Add to vertical layout self.vlayout.addWidget(volumeslider) self.vlayout.addLayout(controls) self.vlayout.addLayout(playlistCtrlLayout) self.central.setLayout(self.vlayout) #self.central.setLayout(controlArea) self.setCentralWidget(self.central) # Connect each signal to their appropriate function playBtn.clicked.connect(self.playhandler) pauseBtn.clicked.connect(self.pausehandler) stopBtn.clicked.connect(self.stophandler) prevBtn.clicked.connect(self.prevSong) shuffleBtn.clicked.connect(self.shufflelist) nextBtn.clicked.connect(self.nextSong) self.statusBar() self.playlist.currentMediaChanged.connect(self.songChanged) self.mainMenu = self.menuBar() # Menu bar exitAction = QAction('&Exit', self) exitAction.setShortcut('Ctrl+Q') exitAction.triggered.connect(self.close) self.fileMenu = self.mainMenu.addMenu('&File') fileAct = QAction('Open File', self) folderAct = QAction('Open Folder', self) fileAct.setShortcut('Ctrl+O') folderAct.setShortcut('Ctrl+D') self.fileMenu.addAction(fileAct) self.fileMenu.addAction(folderAct) fileAct.triggered.connect(self.openFile) folderAct.triggered.connect(self.addFiles) self.fileMenu.addAction(exitAction) #self.addControls() # Start image capture & display def start(self): self.timer = QTimer(self) # Timer to trigger display self.timer.timeout.connect(lambda: self.show_image(image_queue, self.disp, DISP_SCALE)) self.timer.start(DISP_MSEC) self.capture_thread = threading.Thread(target=grab_images, args=(camera_num, image_queue)) self.capture_thread.start() # Thread to grab images # Fetch camera image from queue, and display it def show_image(self, imageq, display, scale): if not imageq.empty(): image = imageq.get() if image is not None and len(image) > 0: img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) self.display_image(img, display, scale) # Display an image, reduce size if required def display_image(self, img, display, scale=1): disp_size = img.shape[1]//scale, img.shape[0]//scale disp_bpl = disp_size[0] * 3 if scale > 1: img = cv2.resize(img, disp_size, interpolation=cv2.INTER_CUBIC) global PREDICTION_STATUS if PREDICTION_STATUS != -1: # print(PREDICTION_STATUS) self.handle_inference(PREDICTION_STATUS) # img_try = cv2.imread('test_image.jpg') # img_try = cv2.cvtColor(img , cv2.COLOR_BGR2RGB) # self.inference.perform_inference(img) # if self.inference.network.wait() == 0 : # result = self.inference.network.extract_output() # pred = np.argmax(result[0, :]) # print(pred) # self.handle_inference( pred ) qimg = QImage(img.data, disp_size[0], disp_size[1], disp_bpl, IMG_FORMAT) display.setImage(qimg) # Handle sys.stdout.write: update text display def write(self, text): self.text_update.emit(str(text)) def flush(self): pass def check_song_is_playing(self): if (datetime.now() - self.current_song_start_time ).seconds >= 4: return False else: return True def handle_inference(self, result): if self.folder_chosen == True and self.check_song_is_playing() == False: global PREDICTION_STATUS if result == 1: #self.pausehandler() PREDICTION_STATUS = -1 pass elif result == 5: self.playhandler() elif result == 0: #self.stophandler() PREDICTION_STATUS = -1 pass elif result == 4: PREDICTION_STATUS = -1 elif result == 2: self.prevSong() elif result == 3: self.nextSong() # Append to text display def append_text(self, text): cur = self.textbox.textCursor() # Move cursor to end of text cur.movePosition(QTextCursor.End) s = str(text) while s: head,sep,s = s.partition("\n") # Split line at LF cur.insertText(head) # Insert text at cursor if sep: # New line if LF cur.insertBlock() self.textbox.setTextCursor(cur) # Update visible cursor # Window is closing: stop video capture def closeEvent(self, event): global capturing capturing = False self.capture_thread.join() def openFile(self): song = QFileDialog.getOpenFileName(self, "Open Song", "~", "Sound Files (*.mp3 *.ogg *.wav *.m4a)") if song[0] != '': url = QUrl.fromLocalFile(song[0]) if self.playlist.mediaCount() == 0: self.playlist.addMedia(QMediaContent(url)) self.player.setPlaylist(self.playlist) self.player.play() else: self.playlist.addMedia(QMediaContent(url)) def addFiles(self): if self.playlist.mediaCount() != 0: self.folderIterator() else: self.folderIterator() self.player.setPlaylist(self.playlist) self.player.playlist().setCurrentIndex(0) self.player.play() def folderIterator(self): folderChosen = QFileDialog.getExistingDirectory(self, 'Open Music Folder', '~') if folderChosen != None: it = QDirIterator(folderChosen) it.next() while it.hasNext(): if it.fileInfo().isDir() == False and it.filePath() != '.': fInfo = it.fileInfo() if fInfo.suffix() in ('mp3', 'ogg', 'wav', 'm4a'): self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(it.filePath()))) self.folder_chosen = True it.next() self.playlist.setPlaybackMode(QMediaPlaylist.Loop) if it.fileInfo().isDir() == False and it.filePath() != '.': fInfo = it.fileInfo() if fInfo.suffix() in ('mp3', 'ogg', 'wav', 'm4a'): self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(it.filePath()))) self.folder_chosen = True def playhandler(self): if self.playlist.mediaCount() == 0: self.folder_chosen = False self.addFiles() elif self.playlist.mediaCount() != 0: self.player.play() self.current_song_start_time = datetime.now() global PREDICTION_STATUS PREDICTION_STATUS = -1 def pausehandler(self): print('Stopped and cleared playlist') self.player.pause() global PREDICTION_STATUS PREDICTION_STATUS = -1 def stophandler(self): self.folder_chosen = False self.player.stop() self.playlist.clear() print('Stopped and cleared playlist') self.statusBar().showMessage("Stopped and cleared playlist") global PREDICTION_STATUS PREDICTION_STATUS = -1 def changeVolume(self, value): self.player.setVolume(value) def prevSong(self): print('playing previous song') if self.playlist.mediaCount() == 0: self.folder_chosen = False self.addFiles() elif self.playlist.mediaCount() != 0: self.player.playlist().previous() self.current_song_start_time = datetime.now() global PREDICTION_STATUS PREDICTION_STATUS = -1 def shufflelist(self): self.playlist.shuffle() def nextSong(self): print('playing next song') if self.playlist.mediaCount() == 0: self.folder_chosen = False self.addFiles() elif self.playlist.mediaCount() != 0: self.player.playlist().next() self.current_song_start_time = datetime.now() global PREDICTION_STATUS PREDICTION_STATUS = -1 def songChanged(self, media): if not media.isNull(): url = media.canonicalUrl() print('Now playing ' +url.fileName()) self.statusBar().showMessage(url.fileName())
class MusicApp(QMainWindow): def __init__(self): super().__init__() self.player = QMediaPlayer() self.playlist = QMediaPlaylist() self.title = 'GestureTunes - player' self.left = 300 self.top = 300 self.width = 600 self.height = 340 self.volume_initial_value = 60 self.model = QStandardItemModel(0, 1) self.song_list = QtWidgets.QTableView() self.play_btn = QPushButton('播放') self.media_controls = QHBoxLayout() # 共享变量 self.image_to_show = None self.rec_res = { "set": False, "used": True, "direction": None, "fingers": 0 } # 摄像头窗口 self.widget = QWidget() self.widget.move(1000, 200) self.widget.resize(300, 200) self.widget.setWindowTitle("GestureTunes - gesture panel") # 窗口标题 self.videoFrame = QLabel('正在打开摄像头,请稍等...') video_area = QVBoxLayout() self.widget.setLayout(video_area) video_area.addWidget(self.videoFrame) self.widget.show() # self.widget.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) # 定时器 self.timer = QTimer() self.timer.setInterval(20) self.timer.start() self.timer.timeout.connect(self.show_image) self.have_song = False self.volume_slider = QSlider(Qt.Horizontal, self) self.volume_slider.setTracking(True) # 播放模式 self.play_style = '列表循环' self.single_img = QIcon('pics/single.png') self.loop_img = QIcon('pics/loop.png') self.play_style_btn = QPushButton() self.play_style_btn.setIcon(self.loop_img) self.play_tip = '' self.playlist.setPlaybackMode(QMediaPlaylist.Loop) # 初始化界面 self.init_ui() def init_ui(self): # Add file menu menubar = self.menuBar() file_menu = menubar.addMenu('文件') fileAct = QAction('打开文件', self) folderAct = QAction('打开文件夹', self) file_menu.addAction(fileAct) file_menu.addAction(folderAct) fileAct.triggered.connect(self.open_file) folderAct.triggered.connect(self.add_files) self.add_listener() self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) self.show() def add_listener(self): wid = QWidget(self) self.setCentralWidget(wid) # 播放控件 self.volume_slider = QSlider(Qt.Horizontal, self) self.volume_slider.setFocusPolicy(Qt.NoFocus) self.volume_slider.valueChanged[int].connect(self.change_volume) self.volume_slider.setValue(self.volume_initial_value) open_btn = QPushButton('打开...') prev_btn = QPushButton('上一首') next_btn = QPushButton('下一首') # 显示播放列表 self.set_play_list() self.song_list.setSelectionBehavior( QtWidgets.QAbstractItemView.SelectRows) self.song_list.setShowGrid(False) self.song_list.setTextElideMode(QtCore.Qt.ElideLeft) # 按钮的layout control_area = QVBoxLayout() # centralWidget self.media_controls = QHBoxLayout() # 将播放控件添加到layout self.media_controls.addWidget(open_btn) self.media_controls.addWidget(prev_btn) self.media_controls.addWidget(self.play_btn) self.media_controls.addWidget(next_btn) self.media_controls.addWidget(self.play_style_btn) self.media_controls.addWidget(self.volume_slider) # 将layout添加到界面中 control_area.addWidget(self.song_list) control_area.addLayout(self.media_controls) wid.setLayout(control_area) # 设置监听 self.play_btn.clicked.connect(self.start_or_stop) open_btn.clicked.connect(self.add_files) prev_btn.clicked.connect(self.prev) next_btn.clicked.connect(self.next) self.song_list.doubleClicked.connect(self.change_song) self.play_style_btn.clicked.connect(self.change_play_style) self.statusBar() self.playlist.currentMediaChanged.connect(self.song_changed) def set_play_list(self): self.model.clear() self.song_list.horizontalHeader().hide() # self.song_list.verticalHeader().hide() # QHeaderView() self.song_list.setModel(self.model) # 把数据添加至QtableView中 self.song_list.horizontalHeader().setSectionResizeMode( QHeaderView.Stretch) self.song_list.setEditTriggers( QAbstractItemView.NoEditTriggers) # 设置不可编辑单元格 if self.playlist.mediaCount(): # 添加数据 for index in range(self.playlist.mediaCount()): self.model.appendRow([ # 添加一行数据 QStandardItem( self.playlist.media(index).canonicalUrl().fileName()) ]) self.song_list.selectRow(0) def open_file(self): song = QFileDialog.getOpenFileName(self, "打开文件", "~", "音频文件 (*.mp3 *.ogg *.wav *.m4a)") if song[0] != '': url = QUrl.fromLocalFile(song[0]) if self.playlist.mediaCount() == 0: self.playlist.addMedia(QMediaContent(url)) self.player.setPlaylist(self.playlist) self.player.play() else: self.playlist.addMedia(QMediaContent(url)) self.set_play_list() self.have_song = True def add_files(self): if self.playlist.mediaCount() != 0: self.playlist.clear() self.folder_iterator() self.player.setPlaylist(self.playlist) self.player.playlist().setCurrentIndex(0) self.song_list.selectRow(0) self.set_play_list() self.player.pause() self.play_tip = "暂停:" + self.playlist.currentMedia().canonicalUrl( ).fileName() self.statusBar().showMessage(self.play_tip + " - " + self.play_style) self.have_song = True def folder_iterator(self): folder_chosen = QFileDialog.getExistingDirectory(self, '打开文件夹', '~') if folder_chosen is not None: it = QDirIterator(folder_chosen) it.next() while it.hasNext(): if (not it.fileInfo().isDir()) and it.filePath() != '.': f_info = it.fileInfo() if f_info.suffix() in ('mp3', 'ogg', 'wav', 'm4a'): self.playlist.addMedia( QMediaContent(QUrl.fromLocalFile(it.filePath()))) it.next() if (not it.fileInfo().isDir()) and it.filePath() != '.': f_info = it.fileInfo() if f_info.suffix() in ('mp3', 'ogg', 'wav', 'm4a'): self.playlist.addMedia( QMediaContent(QUrl.fromLocalFile(it.filePath()))) def start_or_stop(self): print(self.player.state()) if self.playlist.mediaCount() == 0: self.open_file() else: if self.player.state() == QMediaPlayer.PlayingState or \ (self.player.state() == QMediaPlayer.PlayingState and self.play_btn.text() == '暂停'): self.player.pause() self.play_btn.setText('播放') self.play_tip = "暂停:" + self.playlist.currentMedia( ).canonicalUrl().fileName() elif self.player.state() == QMediaPlayer.PausedState or \ (self.player.state() == QMediaPlayer.PlayingState and self.play_btn.text() == '播放'): self.player.play() self.play_btn.setText('暂停') self.play_tip = "正在播放:" + self.playlist.currentMedia( ).canonicalUrl().fileName() self.statusBar().showMessage(self.play_tip + " - " + self.play_style) def change_volume(self, value): self.player.setVolume(value) def volume_up(self): volume = self.player.volume( ) + 10 if self.player.volume() + 10 <= 100 else 100 self.player.setVolume(volume) self.volume_slider.setTracking(True) self.volume_slider.setValue(volume) def volume_down(self): volume = self.player.volume( ) - 10 if self.player.volume() - 10 >= 0 else 0 self.player.setVolume(volume) self.volume_slider.setTracking(True) self.volume_slider.setValue(volume) def prev(self): if self.playlist.mediaCount() == 0: self.open_file() elif self.playlist.mediaCount() != 0: self.player.playlist().previous() def shuffle(self): self.playlist.shuffle() def next(self): if self.playlist.mediaCount() == 0: self.open_file() elif self.playlist.mediaCount() != 0: self.player.playlist().next() def song_changed(self, media): if not media.isNull(): url = media.canonicalUrl() self.play_tip = "正在播放:" + url.fileName() self.statusBar().showMessage(self.play_tip + " - " + self.play_style) self.song_list.selectRow(self.playlist.currentIndex()) def change_song(self): index = self.song_list.currentIndex().row() # 获取双击所在行 self.playlist.setCurrentIndex(index) def change_play_style(self): if self.playlist.playbackMode() == QMediaPlaylist.Loop: self.playlist.setPlaybackMode(QMediaPlaylist.CurrentItemInLoop) self.play_style = "单曲循环" self.play_style_btn.setIcon(self.single_img) elif self.playlist.playbackMode() == QMediaPlaylist.CurrentItemInLoop: self.playlist.setPlaybackMode(QMediaPlaylist.Loop) self.play_style = "列表循环" self.play_style_btn.setIcon(self.loop_img) self.statusBar().showMessage(self.play_tip + " - " + self.play_style) def convert_image(self, frame): if len(frame.shape) == 2: # 若是灰度图则转为三通道 frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2BGR) rgb_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # 将BGR转为RGB rgb_image = np.asanyarray(rgb_image) label_image = QImage(rgb_image.data, rgb_image.shape[1], rgb_image.shape[0], QImage.Format_RGB888) # 转化为QImage self.image_to_show = QPixmap(label_image) def show_image(self): if self.image_to_show is not None: self.videoFrame.setPixmap(self.image_to_show) if self.rec_res['set'] and not self.rec_res['used']: final_direction = self.rec_res['direction'] final_fingers = self.rec_res['fingers'] if final_fingers == 3: self.start_or_stop() self.rec_res['used'] = True return if final_fingers == 5: self.change_play_style() self.rec_res['used'] = True return if final_direction is not None and final_direction != 'NOT_FOUND': if final_direction == "RIGHT": self.next() self.rec_res['used'] = True if final_direction == "LEFT": self.prev() self.rec_res['used'] = True if final_direction == "UP": self.volume_up() self.rec_res['used'] = True if final_direction == "DOWN": self.volume_down() self.rec_res['used'] = True def set_rec_res(self, res): self.rec_res = res