-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPyMusic.py
More file actions
222 lines (188 loc) · 7.81 KB
/
PyMusic.py
File metadata and controls
222 lines (188 loc) · 7.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt
import icons_rc
from PyQt5.QtMultimedia import *
from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtWidgets import QApplication, QWidget, QInputDialog, QLineEdit, QFileDialog
import shutil
configLoc = "./config.json"
import ConfigFunctions
import MusicClass
from os.path import isfile, join
from os import *
import sys
import UI
import CustomSlider
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
# gets user settings
self.getSettings()
# setup play state
self.isPlaying = False # 0 is paused 1 is playing
# index of currently playing song -- used for
self.currentSong = 0
# gets the playlist of songs from folder see func
self.getPlaylist()
# player stuff
self.player = QMediaPlayer()
self.player.setPlaylist(self.playlist)
self.player.setVolume(self.volume)
# setupUi is all stuff made in QtDesigner
UI.setupUi(self)
# connects basically setting functions to event handlers
self.connects()
# very important
self.changeSpeakerImg()
self.getMusicList()
# MORE INIT STUFF
# gets settings and change object state this will probably be chagned later so its a function
def getSettings(self):
# configLoc does not need to be passed
self.volume, self.musicLoc = ConfigFunctions.getSettings(configLoc)
# this will be changed out later for a more robust loader of multiple songs
def getPlaylist(self):
self.playlist = QMediaPlaylist()
# build out and allow for dirs I could use recursion to make this possible
def getMusicList(self):
# this makes a list, gets all files in directory, then makes class with item and adds to list and to fileview
self.musicList = []
onlyfiles = [f for f in listdir(self.musicLoc) if isfile(join(self.musicLoc, f))]
for i, music in enumerate(onlyfiles):
musicClass = MusicClass.Song(self.musicLoc, music)
self.musicList.append(musicClass)
self.addSongToView(musicClass)
# HELPERS
def addSongToView(self, musicClass):
min, sec = musicClass.duration
self.songTableModel.addItem(["", musicClass.artist, musicClass.songName, str(min) + "." + str(sec)])
# this will be built out later
def displayErrorMessage(self, error):
print(error)
# changes speaker image based on volume
def changeSpeakerImg(self):
img = QtGui.QPixmap(":/icons/speaker-none.png")
if self.volume > 70:
img = QtGui.QPixmap(":/icons/speaker-max.png")
elif self.volume < 70 and self.volume > 30:
img = QtGui.QPixmap(":/icons/speaker-med.png")
elif self.volume < 30 and self.volume > 0:
img = QtGui.QPixmap(":/icons/speaker-low.png")
self.speakerImage.setText("")
self.speakerImage.setPixmap(img)
def setCurrentSong(self, index):
self.currentSong = index
self.songTableModel.setCurrentSong(index)
# CONNECTS
# basically event listeners for changes
def connects(self):
self.previous.clicked.connect(self.prevSong)
self.play.clicked.connect(self.changeSongState)
self.forward.clicked.connect(self.nextSong)
self.audioSlider.valueChanged.connect(self.changeAudioVolume)
self.songSlider.sliderMoved.connect(self.changeSongPosition)
#self.songSlider.releaseMouse.connect(self.changeSongPosition)
#self.songSlider.valueChanged.connect(self.changeSongPosition)
#self.player.positionChanged.connect(self.changeSliderPosition)
self.fileMenuOpen.triggered.connect(self.getFile)
self.changeDefaultFolder.triggered.connect(self.getDirectory)
self.songView.doubleClicked.connect(self.playSongAtIndex)
# FILE THINGIES
def getFile(self):
# open dialog, check if user has file, move file to music Folder
fileInfo = QFileDialog.getOpenFileName(self, 'Open File')
currentLoc, typeOrSomething = fileInfo
if currentLoc == '':
return
try:
fileName = currentLoc.split('/')[-1]
musicClass = MusicClass.Song(self.musicLoc, fileName)
self.musicList.append(musicClass)
self.addSongToView(fileName)
except:
self.displayErrorMessage("Error: File was not able to be opened.")
return
shutil.move(currentLoc, self.musicLoc)
def getDirectory(self):
# open dialog, check if user has file, move file to music Folder
dir = QFileDialog.getExistingDirectory(self, "Select Directory")
if not dir == '':
self.musicLoc = dir
ConfigFunctions.updateConfig(self.volume, dir, configLoc)
# PLAYLIST AND AUDIO PLAYER STUFFS
def changeAudioVolume(self):
self.volume = self.audioSlider.value()
self.player.setVolume(self.volume)
self.changeSpeakerImg()
ConfigFunctions.updateConfig(self.volume, self.musicLoc, configLoc)
# song slider change connects
# these don't work properly fix later
def changeSongPosition(self, position):
self.player.setPosition(position * (self.player.duration() / 100))
def changeSliderPosition(self, position):
self.songSlider.setSliderPosition(position / (self.player.duration() / 100))
# These are basically the same
# check mediaCount in playlist if > 1 use playlist funcs
# if not move up current song index and play song at new index
def nextSong(self):
if self.playlist.mediaCount() > 1:
self.playlist.next()
else:
self.playlist.clear()
nextSong = self.currentSong + 1
if nextSong >= len(self.musicList):
nextSong = 0
self.setCurrentSong(nextSong)
self.playlist.addMedia(self.musicList[nextSong].returnMediaContent())
self.playSong()
def prevSong(self):
if self.playlist.mediaCount() > 1:
self.playlist.previous()
else:
self.playlist.clear()
nextSong = self.currentSong - 1
if nextSong < 0:
nextSong = len(self.musicList) - 1
self.setCurrentSong(nextSong)
self.playlist.addMedia(self.musicList[nextSong].returnMediaContent())
self.playSong()
def playSongAtIndex(self, index):
# get music list, get MusicClass at row clicked, return MediaContentClass of that index
songClass = self.musicList[index.row()]
self.setCurrentSong(index.row())
song = songClass.returnMediaContent()
# remove song and add new song then play
pos = self.playlist.currentIndex()
self.playlist.removeMedia(pos)
self.playlist.insertMedia(pos, song)
self.playSong()
# This is for the play/pause button
def changeSongState(self):
# stop may be added later
if not self.isPlaying:
self.playSong()
elif self.isPlaying:
self.pauseSong()
# play song and update the model
def playSong(self):
self.player.play()
self.isPlaying = True
self.songTableModel.songPlay()
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/icons/pause.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.play.setIcon(icon)
# play song and update the model
def pauseSong(self):
self.player.pause()
self.isPlaying = False
self.songTableModel.songPause()
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/icons/Play.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.play.setIcon(icon)
# does stuff
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())