Skip to content

Commit e13a7d2

Browse files
authored
Add files via upload
1 parent aae306d commit e13a7d2

File tree

1 file changed

+248
-0
lines changed

1 file changed

+248
-0
lines changed

releases/v1.4.3_hotfix3.py

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
# A runatboot file
2+
import vlc #play music
3+
import time #control time
4+
import discid #read discid
5+
import musicbrainzngs #fetch data
6+
import sys
7+
import cdio, pycdio #cdtxt & trackcount
8+
from multiprocessing import Process, Pipe
9+
import threading #scheduling
10+
from math import floor#round down
11+
import signal#last 4 is for LCD
12+
import board
13+
from digitalio import DigitalInOut
14+
from adafruit_character_lcd.character_lcd import Character_LCD_Mono
15+
import RPi.GPIO as GPIO#buttons
16+
import os
17+
os.environ['LAST_FM_API_SECRET'] = ''
18+
import pylast
19+
API_KEY = ""#Lastfm login data
20+
API_SECRET = ""
21+
username = ""
22+
password_hash = pylast.md5(b"")
23+
24+
lcd_columns = 16
25+
lcd_rows = 2
26+
27+
lcd_rs = DigitalInOut(board.D26)
28+
lcd_en = DigitalInOut(board.D25)
29+
lcd_d4 = DigitalInOut(board.D10)
30+
lcd_d5 = DigitalInOut(board.D9)
31+
lcd_d6 = DigitalInOut(board.D11)
32+
lcd_d7 = DigitalInOut(board.D0)
33+
# Initialise the LCD class
34+
lcd = Character_LCD_Mono(
35+
lcd_rs, lcd_en, lcd_d4, lcd_d5, lcd_d6, lcd_d7, lcd_columns, lcd_rows)
36+
lcd.clear()
37+
lcd.cursor = False
38+
lcd.blink = False
39+
40+
GPIO.setmode(GPIO.BCM) #przyciski
41+
BUTTONS = [5, 6, 22, 23, 24, 12]
42+
GPIO.setup(BUTTONS, GPIO.IN, pull_up_down=GPIO.PUD_UP)
43+
44+
command = 0 # 0-nothing 1-play 2-pause 3-stop 4-next 5-prev
45+
textb = 15
46+
47+
playchar = [
48+
0b01000,
49+
0b01100,
50+
0b01110,
51+
0b01111,
52+
0b01110,
53+
0b01100,
54+
0b01000,
55+
0b00000]
56+
pausechar = [
57+
0b00000,
58+
0b10010,
59+
0b10010,
60+
0b10010,
61+
0b10010,
62+
0b10010,
63+
0b10010,
64+
0b00000]
65+
stopchar = [
66+
0b00000,
67+
0b11111,
68+
0b11111,
69+
0b11111,
70+
0b11111,
71+
0b11111,
72+
0b00000,
73+
0b00000]
74+
lcd.create_char(0, playchar)
75+
lcd.create_char(1, pausechar)
76+
lcd.create_char(2, stopchar)
77+
78+
def search_exact_tracklist(data): #function to find exalctly wchich cd was inserted
79+
for x in range(0,len(data["disc"]["release-list"])):
80+
for y in range(0,len(data["disc"]["release-list"][x]["medium-list"])):
81+
for z in range(0,len(data["disc"]["release-list"][x]["medium-list"][y]["disc-list"])):
82+
if data["disc"]["release-list"][x]["medium-list"][y]["disc-list"][z]["id"] == data["disc"]["id"]:
83+
return x, y
84+
def fetchdata():
85+
try:
86+
d = cdio.Device(driver_id=pycdio.DRIVER_UNKNOWN)
87+
drive_name = d.get_device()
88+
i_tracks = d.get_num_tracks()#ilosc trackow
89+
artists = [None] * i_tracks
90+
track_list = [None] * i_tracks
91+
album = "Unknown"
92+
except IOError:
93+
print("Problem finding a CD-ROM")
94+
sys.exit(1) #if no drive exit
95+
96+
musicbrainzngs.set_useragent("Small_diy_cd_player", "0.1")
97+
disc = discid.read()#id read
98+
try:
99+
result = musicbrainzngs.get_releases_by_discid(disc.id,includes=["artists", "recordings"]) #get data from Musicbrainz
100+
except musicbrainzngs.ResponseError:
101+
print("disc not found or bad response, using cdtxt instead") #if not available search for cdtext
102+
cdt = d.get_cdtext()
103+
i_first_track = pycdio.get_first_track_num(d.cd)
104+
105+
for t in range(i_first_track, i_tracks + i_first_track):
106+
for i in range(pycdio.MIN_CDTEXT_FIELD, pycdio.MAX_CDTEXT_FIELDS):
107+
#print(pycdio.cdtext_field2str(i)) ##0-TITLE 1-PERFORMER 2-SONGWRITER 3-COMPOSER 4-MESSAGE 5-ARRANGER 6-ISRC 7-UPC_EAN 8-GENERE 9-DISC_ID
108+
value = cdt.get(i, t)
109+
if value is not None:
110+
if i == 0:
111+
track_list[t-1] = value
112+
pass
113+
elif i == 1:
114+
artists[t-1] = value
115+
pass
116+
pass
117+
pass
118+
if(track_list[t-1] == None):
119+
track_list[t-1] = "Untitled-" + str(t)
120+
artists[t-1] = "Unknown"
121+
else: #Artist and album info
122+
a, b=search_exact_tracklist(result)
123+
if result.get("disc"):
124+
artists = [result["disc"]["release-list"][a]["artist-credit-phrase"]] * i_tracks
125+
album = result["disc"]["release-list"][a]["title"]
126+
elif result.get("cdstub"):
127+
artists = [result["cdstub"]["artist"]] * i_tracks
128+
album = result["cdstub"]["title"]
129+
for t in range(0,i_tracks):
130+
track_list[t]=(result["disc"]["release-list"][a]["medium-list"][b]["track-list"][t]["recording"]["title"]) #uzupelnij tracklist
131+
if(artists[0] =="Various Artists"):
132+
cdt = d.get_cdtext()
133+
i_first_track = pycdio.get_first_track_num(d.cd)
134+
for t in range(i_first_track, i_tracks + i_first_track):
135+
value = cdt.get(1, t)
136+
if value is not None:
137+
artists[t-1] = value
138+
pass
139+
#print(artists, '\n', track_list, '\n', album, '\n', i_tracks)
140+
return artists, track_list, album, i_tracks
141+
def playcd(conn):
142+
artists, track_list, album, i_tracks = fetchdata()
143+
144+
instance = vlc.Instance() #uruchom vlc
145+
player = instance.media_player_new()
146+
medialist = instance.media_list_new()
147+
listplayer = instance.media_list_player_new()
148+
listplayer.set_media_player(player)
149+
for i in (range(1,i_tracks+1)): #second option
150+
track = instance.media_new("cdda:///dev/cdrom", (":cdda-track=" + str(i)))
151+
medialist.add_media(track)
152+
listplayer.set_media_list(medialist)
153+
154+
listplayer.play()
155+
time.sleep(5)#wait to spin
156+
157+
last_scrobble=""
158+
network = pylast.LastFMNetwork(api_key=API_KEY, api_secret=API_SECRET, username=username, password_hash=password_hash)
159+
while True:
160+
dump = conn.recv()
161+
index = medialist.index_of_item(listplayer.get_media_player().get_media())
162+
now_secs= '0' + str(floor((player.get_time()/1000)%60)) if floor((player.get_time()/1000)%60) < 10 else str(floor((player.get_time()/1000)%60))
163+
now_min= '0' + str(floor((player.get_time()/1000)/60)) if floor((player.get_time()/1000)/60) < 10 else str(floor((player.get_time()/1000)/60))
164+
end_secs= '0' + str(floor((player.get_length()/1000)%60)) if floor((player.get_length()/1000)%60) < 10 else str(floor((player.get_length()/1000)%60))
165+
end_min= '0' + str(floor((player.get_length()/1000)/60)) if floor((player.get_length()/1000)/60) < 10 else str(floor((player.get_length()/1000)/60))
166+
Timer= now_min + ":" + now_secs + " - " + end_min + ":" + end_secs
167+
conn.send([index+1, i_tracks, track_list[index], artists[index], album, Timer, player.get_state()])
168+
match dump:
169+
case 0:
170+
pass
171+
case 1:
172+
listplayer.play()
173+
case 2:
174+
listplayer.pause()
175+
case 3:
176+
listplayer.stop()
177+
last_scrobble=""
178+
case 4:
179+
listplayer.next()
180+
last_scrobble=""
181+
case 5:
182+
listplayer.previous()
183+
last_scrobble=""
184+
if((player.get_position()*100 > 50) and last_scrobble != track_list[index]):
185+
last_scrobble= track_list[index]
186+
if album != "Unknown":
187+
network.scrobble(artist=artists[index], title=track_list[index], timestamp=int(time.time()), album=album)
188+
elif track_list[index] != "Unknown" and artists[index] != "Unknown":
189+
network.scrobble(artist=artists[index], title=track_list[index], timestamp=int(time.time()))
190+
191+
def PlayerGlobalSync():
192+
global command, cdplayer, textb
193+
if command == -1:
194+
if cdplayer.is_alive():
195+
cdplayer.kill()
196+
cdplayer.join()
197+
lcd.clear()
198+
lcd.message = "Change\nmedium"
199+
else:
200+
cdplayer = Process(target=playcd, args=(child_conn,))
201+
cdplayer.start()
202+
elif cdplayer.is_alive():
203+
parent_conn.send(command)
204+
time.sleep(0.1)
205+
dump=parent_conn.recv()
206+
#print(dump)
207+
lcd.clear()
208+
if(dump[6] == vlc.State.Ended):
209+
cdplayer.kill()
210+
cdplayer.join()
211+
lcd.clear()
212+
lcd.message = "CD ended\nChange medium"
213+
else:
214+
if(len(dump[2])>16):
215+
if textb >= len(dump[2])+1:
216+
textb = 16
217+
TrimMessage=dump[2][textb-16:textb]
218+
textb+=1
219+
else:
220+
TrimMessage=dump[2]
221+
lcd.message=TrimMessage #title
222+
lcd.cursor_position(0,1)
223+
lcd.message=dump[5] # time
224+
lcd.cursor_position(15,1)
225+
match dump[6]:
226+
case vlc.State.Playing:
227+
lcd.message='\x00'
228+
case vlc.State.Paused:
229+
lcd.message='\x01'
230+
case vlc.State.Stopped:
231+
lcd.message='\x02'
232+
command=0
233+
P=threading.Timer(1, PlayerGlobalSync)
234+
P.start()
235+
236+
GPIO.add_event_detect(BUTTONS[0], GPIO.FALLING, callback=lambda event: globals().update(command = 4), bouncetime=1000)
237+
GPIO.add_event_detect(BUTTONS[1], GPIO.FALLING, callback=lambda event: globals().update(command = 5), bouncetime=1000)
238+
GPIO.add_event_detect(BUTTONS[3], GPIO.FALLING, callback=lambda event: globals().update(command = 3), bouncetime=1000)
239+
GPIO.add_event_detect(BUTTONS[2], GPIO.FALLING, callback=lambda event: globals().update(command = 2), bouncetime=1000)
240+
GPIO.add_event_detect(BUTTONS[4], GPIO.FALLING, callback=lambda event: globals().update(command = 1), bouncetime=1000)
241+
GPIO.add_event_detect(BUTTONS[5], GPIO.FALLING, callback=lambda event: globals().update(command = -1), bouncetime=1000)
242+
243+
parent_conn, child_conn = Pipe()
244+
cdplayer = Process(target=playcd, args=(child_conn,))
245+
246+
cdplayer.start()
247+
PlayerGlobalSync()
248+

0 commit comments

Comments
 (0)