diff --git a/.idea/MusicPlayer.iml b/.idea/MusicPlayer.iml
index d0876a7..8437fe6 100644
--- a/.idea/MusicPlayer.iml
+++ b/.idea/MusicPlayer.iml
@@ -2,7 +2,7 @@
-
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index d1e22ec..dc9ea49 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,4 +1,4 @@
-
+
\ No newline at end of file
diff --git a/bin/csv_parsers.py b/bin/csv_parsers.py
new file mode 100644
index 0000000..d1f593c
--- /dev/null
+++ b/bin/csv_parsers.py
@@ -0,0 +1,122 @@
+"""@package docstring
+This is a simplification of the csv module"""
+
+import csv
+
+
+class CsvRead:
+ """This is a class that reads csv files and depending on the module selected does do different things with it"""
+ def __init__(self):
+ self.__imp = ""
+ self.__raw = ""
+ self.__raw_list = ""
+
+ def importing(self, path):
+ """Returns a list of the imported csv-file, requires path, either direct system path or relative path"""
+ self.__imp = open(path)
+ self.__raw = csv.reader(self.__imp, delimiter=',')
+ self.__raw_list = list(self.__raw)
+ self.__imp.close()
+ return self.__raw_list
+
+
+class CsvWrite:
+ """This is a class that modifies csv files"""
+ def __init__(self):
+ self.__impl = []
+ self.__strpop = []
+ self.__removed = []
+ self.__removing = 0
+ self.__change = 0
+ self.__appending = 0
+ self.__imp = []
+ self.__raw = []
+
+ def rem_str(self, path, row):
+ """Opens the csv-file in write mode which is specified as an argument either as direct or relative path"""
+ self.__imp = open(path)
+ self.__raw = csv.reader(self.__imp, delimiter=',')
+ self.__impl = list(self.__raw)
+ self.__removed = self.__impl.pop(row + 1)
+ with open(path, "w") as removedata:
+ self.__removing = csv.writer(removedata, delimiter=',', quoting=csv.QUOTE_MINIMAL)
+ self.__removing.writerow(self.__impl.pop(0))
+ while len(self.__impl) > 0:
+ with open(path, "a") as removedata:
+ self.__removing = csv.writer(removedata, delimiter=',', quoting=csv.QUOTE_MINIMAL)
+ self.__removing.writerow(self.__impl.pop(0))
+ self.__imp.close()
+ removedata.close()
+
+
+ def chg_str(self, path, row, pos, new_value):
+ """Opens the csv-file in write mode to change a value, e.g. if a recipes is changed."""
+ self.__imp = open(path)
+ self.__raw = csv.reader(self.__imp, delimiter=',')
+ self.__impl = list(self.__raw)
+ self.__strpop = self.__impl.pop(row)
+ self.__strpop.pop(pos)
+ self.__strpop.insert(pos, new_value)
+ self.__impl.insert(row, self.__strpop)
+ with open(path, "w") as changedata:
+ self.__change = csv.writer(changedata, delimiter=',', quoting=csv.QUOTE_MINIMAL)
+ self.__change.writerow(self.__impl.pop(0))
+ while len(self.__impl) > 0:
+ with open(path, "a") as changedata:
+ self.__removing = csv.writer(changedata, delimiter=',', quoting=csv.QUOTE_MINIMAL)
+ self.__removing.writerow(self.__impl.pop(0))
+ self.__imp.close()
+ changedata.close()
+
+ def chg_str_rem(self, path, row, pos):
+ """Opens the csv-file in write mode to change a value, e.g. if a recipes is changed."""
+ self.__imp = open(path)
+ self.__raw = csv.reader(self.__imp, delimiter=',')
+ self.__impl = list(self.__raw)
+ self.__strpop = self.__impl.pop(row)
+ self.__strpop.pop(pos)
+ self.__strpop.pop(pos)
+ self.__impl.insert(row, self.__strpop)
+ with open(path, "w") as changedata:
+ self.__change = csv.writer(changedata, delimiter=',', quoting=csv.QUOTE_MINIMAL)
+ self.__change.writerow(self.__impl.pop(0))
+ while len(self.__impl) > 0:
+ with open(path, "a") as changedata:
+ self.__removing = csv.writer(changedata, delimiter=',', quoting=csv.QUOTE_MINIMAL)
+ self.__removing.writerow(self.__impl.pop(0))
+ self.__imp.close()
+ changedata.close()
+
+ def chg_str_add(self, path, row, new_value1, new_value2):
+ """Opens the csv-file in write mode to change a value, e.g. if a recipes is changed."""
+ self.__imp = open(path)
+ self.__raw = csv.reader(self.__imp, delimiter=',')
+ self.__impl = list(self.__raw)
+ self.__strpop = self.__impl.pop(row)
+ self.__strpop.append(new_value1)
+ self.__strpop.append(new_value2)
+ self.__impl.insert(row, self.__strpop)
+ with open(path, "w") as changedata:
+ self.__change = csv.writer(changedata, delimiter=',', quoting=csv.QUOTE_MINIMAL)
+ self.__change.writerow(self.__impl.pop(0))
+ while len(self.__impl) > 0:
+ with open(path, "a") as changedata:
+ self.__removing = csv.writer(changedata, delimiter=',', quoting=csv.QUOTE_MINIMAL)
+ self.__removing.writerow(self.__impl.pop(0))
+ self.__imp.close()
+ changedata.close()
+
+ def app_str(self, path, value):
+ """Opens the csv-file in append mode and writes given input. CsvWrite.app_str(path, value).
+ Path can be specified both as direct or relative. value is a list. Will return an error if type of value is
+ not a list."""
+ with open(path, "a") as appenddata:
+ self.__appending = csv.writer(appenddata, delimiter=',', quoting=csv.QUOTE_MINIMAL)
+ self.__appending.writerow(value)
+ appenddata.close()
+
+ def write_str(self, path, value):
+ with open(path, "w") as writedata:
+ self.__change = csv.writer(writedata, delimiter=',', quoting=csv.QUOTE_MINIMAL)
+ self.__change.writerow(value)
+ writedata.close()
diff --git a/bin/filepathanalysis.py b/bin/filepathanalysis.py
new file mode 100644
index 0000000..55c013d
--- /dev/null
+++ b/bin/filepathanalysis.py
@@ -0,0 +1,26 @@
+import os
+
+
+class PathAnalysis:
+ def __init__(self):
+ self.__output = []
+ self.__input = []
+ self.__file_extension = ""
+ self.__filepath = ""
+ self.__returns = []
+ self.__names = []
+
+ def validsonglistcreator(self, path):
+ self.__input = os.listdir(path)
+ for self.item in self.__input:
+ self.__file_extension = self.item[(len(self.item) - 4):]
+ if self.__file_extension == ".mp3" or self.__file_extension == ".wav":
+ self.__filepath = str(path)
+ self.__filepath += f"/{str(self.item)}"
+ self.__names.append(self.item)
+ self.__output.append(self.__filepath)
+ else:
+ pass
+ self.__returns.append(self.__output)
+ self.__returns.append(self.__names)
+ return self.__returns
diff --git a/bin/gui/gui.kv b/bin/gui/gui.kv
index f37ef3b..9c78511 100644
--- a/bin/gui/gui.kv
+++ b/bin/gui/gui.kv
@@ -1,6 +1,11 @@
RootScreen:
Home:
Main:
+ ShowcaseS
+
+###########
+# POPUPS
+###########
:
title: "NOTICE!"
@@ -20,6 +25,46 @@ RootScreen:
on_release:
root.dismiss()
+:
+ title: "NOTICE!"
+ font_size: 50
+ size_hint: 0.5, 0.4
+ auto_dismiss: False
+ GridLayout:
+ cols:1
+ Label:
+ text: "Path without any mp3/wav files specified"
+ font_size: 18
+ Label:
+ text: "Please enter another path and try again"
+ font_size: 15
+ Button:
+ text:"Ok"
+ on_release:
+ root.dismiss()
+
+:
+ title: "NOTICE!"
+ font_size: 50
+ size_hint: 0.5, 0.4
+ auto_dismiss: False
+ GridLayout:
+ cols:1
+ Label:
+ text: "Invalid path specified"
+ font_size: 18
+ Label:
+ text: "Please enter a valid path and try again"
+ font_size: 15
+ Button:
+ text:"Ok"
+ on_release:
+ root.dismiss()
+
+###########
+# SCREENS
+###########
+
:
name: "Home"
md_bg_color: app.theme_cls.accent_color
@@ -42,6 +87,7 @@ RootScreen:
hint_text: "Path to Folder containing the Music files"
pos_hint: {"x":0.2, "y":0.5}
size_hint_x: 0.6
+ text: "/home/janis/Downloads"
Button:
text: "Start"
color: app.theme_cls.primary_color
@@ -52,11 +98,74 @@ RootScreen:
root.change_screen()
:
+ on_pre_enter: root.initialize()
name: "Main"
GridLayout:
cols: 1
+ GridLayout:
+ cols: 2
+ Button:
+ text: "Next"
+ on_release:
+ root.nextsong()
+ Button:
+ text: "Rewind"
+ on_release:
+ root.rewindsong()
Button:
- text: "Back"
+ text: "Play"
+ id: pp_button
on_release:
- app.root.current = "Home"
+ root.playmusic()
+ GridLayout:
+ cols: 2
+ Button:
+ text: "Back"
+ on_release:
+ root.go_back()
+ Button:
+ text: "Showcase"
+ on_release:
+ app.root.current = "Showcase"
+ root.manager.transition.direction = "left"
+
+:
+ on_pre_enter: root.screen_updater_start()
+ name: "Showcase"
+ md_bg_color: (0, 0, 0, 1)
+ FloatLayout:
+ Label:
+ text: "Currently Playing"
+ pos_hint: {"y": 0.4}
+ font_size: 35
+ color: app.theme_cls.primary_color
+ MDProgressBar:
+ orientation: "horizontal"
+ value: 100
+ pos_hint: {"y": 0.35}
+ color: app.theme_cls.primary_dark
+ Label:
+ id: current_song
+ text: "Currently playing Song will appear here"
+ pos_hint: {"y": 0.25}
+ font_size: 30
+ color: app.theme_cls.primary_color
+ Label:
+ text: "upcoming"
+ font_size: 25
+ color: app.theme_cls.primary_color
+ Label:
+ id: upcoming_songs
+ text: "Upcoming Songs will appear here"
+ pos_hint: {"y": -0.25}
+ font_size: 20
+ color: app.theme_cls.primary_color
+ Button:
+ text: "back"
+ font_size: 10
+ size_hint: 0.05, 0.05
+ background_color: app.theme_cls.accent_light
+ on_release:
+ app.root.current = "Main"
+ root.manager.transition.direction = "right"
\ No newline at end of file
diff --git a/bin/player.py b/bin/player.py
new file mode 100644
index 0000000..747a310
--- /dev/null
+++ b/bin/player.py
@@ -0,0 +1,96 @@
+import pygame.mixer as mx
+import bin.csv_parsers
+import copy
+import bin.filepathanalysis
+import pygame
+import time
+
+pa = bin.filepathanalysis.PathAnalysis()
+cvr = bin.csv_parsers.CsvRead()
+cvw = bin.csv_parsers.CsvWrite()
+
+
+class Player:
+ def __init__(self):
+ self.__running = 1
+ self.event = ""
+ self.__recent_change = 1000000
+ self.__imports = []
+ self.information = []
+ self.current_playing_pos = 0
+
+ def start_playing(self):
+ # initialize playing
+ if pygame.get_init() == True:
+ pass
+ else:
+ pygame.init()
+ self.path = cvr.importing("./data/temp.csv").pop(0)
+ self.__imports = pa.validsonglistcreator(self.path.pop())
+ self.playlist = self.__imports.pop(0)
+ self.playlist_backup = copy.deepcopy(self.playlist)
+ self.information = self.__imports.pop(0)
+ mx.init()
+ self.current_playing = self.playlist.pop(0)
+ mx.music.load(self.current_playing)
+ mx.music.play()
+ mx.music.pause()
+
+ def infoupdater(self):
+ self.transmission = []
+ cvw.write_str("./data/songtemp.csv", [self.current_playing_pos])
+ cvw.app_str("./data/songtemp.csv", self.information)
+
+ def musicmanager(self, inst, other):
+ self.start_playing()
+ self.infoupdater()
+ while self.__running == 1:
+ if self.__recent_change < 1:
+ pass
+ else:
+ self.__recent_change -= 1
+ # instructions from main class
+ if other.value == 1:
+ other.value = 0
+ mx.music.unload()
+ if len(self.playlist) > 0:
+ pass
+ else:
+ self.playlist = copy.deepcopy(self.playlist_backup)
+ self.current_playing_pos = -1
+ self.current_playing = self.playlist.pop(0)
+ self.current_playing_pos += 1
+ mx.music.load(self.current_playing)
+ mx.music.play()
+ self.__recent_change = 1000000
+ self.infoupdater()
+
+ elif other.value == 2:
+ mx.music.rewind()
+ other.value = 0
+
+ elif other.value == 3:
+ self.__recent_change = 1000000
+ other.value = 0
+ else:
+ if inst.value == 1:
+ mx.music.unpause()
+ else:
+ mx.music.pause()
+ # Main event-checking part
+ if mx.music.get_busy() is False and inst.value == 1 and self.__recent_change == 0:
+ mx.music.unload()
+ if len(self.playlist) > 0:
+ pass
+ else:
+ self.playlist = copy.deepcopy(self.playlist_backup)
+ self.current_playing_pos = -1
+ self.current_playing = self.playlist.pop(0)
+ self.current_playing_pos += 1
+ mx.music.load(self.current_playing)
+ mx.music.play()
+ self.__recent_change = 10000000
+ self.infoupdater()
+ else:
+ pass
+
diff --git a/data/songtemp.csv b/data/songtemp.csv
new file mode 100644
index 0000000..304c865
--- /dev/null
+++ b/data/songtemp.csv
@@ -0,0 +1,2 @@
+0
+Metaheuristic - Freedom Trail Studio.mp3,Heal You - Freedom Trail Studio.mp3,Straw Squeak.mp3
diff --git a/data/temp.csv b/data/temp.csv
new file mode 100644
index 0000000..0ace8cd
--- /dev/null
+++ b/data/temp.csv
@@ -0,0 +1 @@
+/home/janis/Downloads
diff --git a/musicplayer.py b/musicplayer.py
index 187dbfb..312195a 100644
--- a/musicplayer.py
+++ b/musicplayer.py
@@ -1,10 +1,26 @@
-import playsound as ps
+import multiprocessing
import os
+from kivy.core.window import Window, Config
from kivy.uix.screenmanager import ScreenManager
from kivymd.uix.screen import MDScreen
from kivymd.app import MDApp
from kivy.base import Builder
from kivy.uix.popup import Popup
+from kivy.clock import Clock
+import bin.csv_parsers
+import bin.filepathanalysis
+import bin.player
+import pygame
+import pygame.mixer as mx
+import copy
+import time
+
+
+
+pl = bin.player.Player()
+pa = bin.filepathanalysis.PathAnalysis()
+cvr = bin.csv_parsers.CsvRead()
+cvw = bin.csv_parsers.CsvWrite()
###########
@@ -16,6 +32,14 @@ class PathMissingPU(Popup):
pass
+class PathWrongPU(Popup):
+ pass
+
+
+class invalidpathPU(Popup):
+ pass
+
+
###########
# SCREENS
###########
@@ -24,23 +48,128 @@ class PathMissingPU(Popup):
class Home(MDScreen):
def change_screen(self):
if self.ids.filepath.text != "":
- self.manager.current = "Main"
- self.manager.transition.directio = "right"
+ self.analyse_dir()
else:
self.openpathmpu()
+ def analyse_dir(self):
+ try:
+ self.__fcontent = os.listdir(self.ids.filepath.text)
+ self.__good_files = 0
+ for self.item in self.__fcontent:
+ self.__filextension = self.item[(len(self.item) - 4):]
+ if self.__filextension == ".mp3" or self.__filextension == ".wav":
+ self.__good_files += 1
+ else:
+ pass
+ # self.__good_files = 1
+ if self.__good_files > 0:
+ cvw.write_str("./data/temp.csv", [self.ids.filepath.text])
+ self.manager.current = "Main"
+ self.manager.transition.direction = "left"
+ else:
+ self.openpathfpu()
+ except:
+ self.ivpathpu()
+
def openpathmpu(self):
self.pmpu = PathMissingPU()
self.pmpu.open()
-class Main(MDScreen):
- pass
+ def openpathfpu(self):
+ self.wppu = PathWrongPU()
+ self.wppu.open()
+ def ivpathpu(self):
+ self.ivppu = invalidpathPU()
+ self.ivppu.open()
+
+
+class Main(MDScreen):
+ def __init__(self, **kwargs):
+ super().__init__(**kwargs)
+ self.instructions = multiprocessing.Value('i', 0)
+ self.others = multiprocessing.Value('i', 0)
+ self.keyboard = Window.request_keyboard(None, self)
+ self.keyboard.bind(on_key_down=self.key_pressed)
+ self.quit_requests = 0
+
+ def key_pressed(self, keyboard, keycode, text, modifiers):
+ # print(keycode[1])
+ self.key = keycode[1]
+ if self.key == "spacebar":
+ self.playmusic()
+ elif self.key == "right":
+ self.nextsong()
+ elif self.key == "left":
+ self.rewindsong()
+ else:
+ pass
+
+ def initialize(self):
+ try:
+ if self.mplayer.is_alive() == True:
+ pass
+ else:
+ self.mplayer = multiprocessing.Process(name="player", target=pl.musicmanager, args=(self.instructions, self.others,))
+ self.mplayer.start()
+ except:
+ self.mplayer = multiprocessing.Process(name="player", target=pl.musicmanager, args=(self.instructions, self.others,))
+ self.mplayer.start()
+
+ def playmusic(self):
+ self.others.value = 3
+ if self.instructions.value == 0:
+ self.instructions.value = 1
+ self.ids.pp_button.text = "Pause"
+ else:
+ self.instructions.value = 0
+ self.ids.pp_button.text = "Play"
+
+ def nextsong(self):
+ self.others.value = 1
+
+ def rewindsong(self):
+ self.others.value = 2
+
+ def go_back(self):
+ try:
+ self.mplayer.kill()
+ except:
+ pass
+ self.manager.current = "Home"
+ self.manager.transition.direction = "right"
+
+class ShowcaseS(MDScreen):
+ def screen_updater_start(self):
+ Clock.schedule_interval(self.screen_updating, 2)
+
+
+ def screen_updating(self, waste):
+ self.__info = cvr.importing("./data/songtemp.csv")
+ self.__currents_imp = self.__info.pop(0)
+ self.__currents = int(self.__currents_imp.pop(0))
+ self.__upcoming = self.__info.pop(0)
+ self.__current = self.__upcoming.pop(self.__currents)
+ self.ids.current_song.text = self.__current[:(len(self.__current) - 4)]
+ if len(self.__upcoming) <= self.__currents:
+ self.ids.upcoming_songs.text = "No more songs in Queue"
+ else:
+ self.__upcoming2 = str(self.__upcoming.pop(self.__currents))
+ self.__upcoming_output = self.__upcoming2[:(len(self.__upcoming2) - 4)]
+ self.__length_output = 0
+ for i in range(len(self.__upcoming) - self.__currents):
+ if self.__length_output > 5:
+ pass
+ else:
+ self.__upcoming2 = str(self.__upcoming.pop(self.__currents))
+ self.__upcoming_output += f"\n{self.__upcoming2[:(len(self.__upcoming2) - 4)]}"
+ self.__length_output += 1
+ self.ids.upcoming_songs.text = self.__upcoming_output
class RootScreen(ScreenManager):
pass
-
class MusicPlayer(MDApp):
def build(self):
self.title = "MusicPlayer"
@@ -50,6 +179,12 @@ class MusicPlayer(MDApp):
return Builder.load_file("./bin/gui/gui.kv")
if __name__ == "__main__":
+ Config.set('graphics', 'width', '800')
+ Config.set('graphics', 'height', '600')
+ Config.set('graphics', 'resizable', True)
+ Config.set('kivy', 'exit_on_escape', '0')
+ Config.set('input', 'mouse', 'mouse,multitouch_on_demand')
+ Config.set('graphics', 'window_state', 'normal')
+ Config.set('graphics', 'fullscreen', False)
+ Config.write()
MusicPlayer().run()
-
-# ps.playsound("/mnt/sda3/Music/Videos/Songs/Ancient.mp3")