Project

General

Profile

Wiki » radio-mpd-pyg3.py

Programma per la gestione dell'interfaccia utente e l'invio del flusso audio alla scheda. - Andrea Belloni, 10/15/2015 05:49 PM

 
1
#!/usr/bin/env python
2
#
3
# FabLab Radio by HackLab Terni
4
#
5

    
6
import pygame
7
from pygame.locals import *
8
import time
9
from rotary_class import RotaryEncoder
10
import json
11
import mpd
12
import os
13
import math
14
from subprocess import call
15

    
16
os.environ["SDL_FBDEV"] = "/dev/fb1"
17

    
18
# Define GPIO inputs
19
PIN_A = 13 	# Pin 33
20
PIN_B = 26	# Pin 37
21
BUTTON = 6	# Pin 31
22

    
23
PIN_A_V = 16 	# Pin 36
24
PIN_B_V = 12	# Pin 32
25
BUTTON_V = 5	# Pin 29
26

    
27
index = 0
28
numSta = 16
29
volume = 0
30

    
31
changed = True
32
play = False
33
changedVol = True
34
mute = False
35

    
36
# This is the event callback routine to handle events
37
def switch_event(event):
38
	global index, numSta, changed, play
39

    
40
	if event == RotaryEncoder.CLOCKWISE:
41
		#print "Clockwise"
42
		changed = True
43
		index = index + 1
44
		if index > (numSta - 1):
45
			index = 0
46
	elif event == RotaryEncoder.ANTICLOCKWISE:
47
		#print "Anticlockwise"
48
		changed = True
49
		index = index - 1
50
		if index < 0:
51
			index = numSta - 1
52
	elif event == RotaryEncoder.BUTTONDOWN:
53
		#print "Button down"
54
		play = not play
55
		changed = True
56
	#elif event == RotaryEncoder.BUTTONUP:
57
	#	print "Button up"
58

    
59
	return
60

    
61
# This is the event callback routine to handle events
62
def volume_event(event):
63
	global changedVol, mute, volume
64

    
65
	if event == RotaryEncoder.CLOCKWISE:
66
		#print "Clockwise"
67
		changedVol = True
68
		volume = volume + 2
69
		if volume > 100:
70
			volume = 100
71
	elif event == RotaryEncoder.ANTICLOCKWISE:
72
		#print "Anticlockwise"
73
		changedVol = True
74
		volume = volume - 2
75
		if volume < 0:
76
			volume = 0
77
	elif event == RotaryEncoder.BUTTONDOWN:
78
		#print "Button down"
79
		mute = not mute
80
		changedVol = True
81
	#elif event == RotaryEncoder.BUTTONUP:
82
	#	print "Button up"
83

    
84
	return
85

    
86
# draw some text into an area of a surface
87
# automatically wraps words
88
# returns any text that didn't get blitted
89
def drawText(surface, text, color, rect, font, aa=False, bkg=None):
90
	rect = Rect(rect)
91
	y = rect.top
92
	lineSpacing = -2
93
 
94
	# get the height of the font
95
	fontHeight = font.size("Tg")[1]
96
 
97
	while text:
98
		i = 1
99
 
100
		# determine if the row of text will be outside our area
101
		if y + fontHeight > rect.bottom:
102
			break
103
 
104
		# determine maximum width of line
105
		while font.size(text[:i])[0] < rect.width and i < len(text):
106
			i += 1
107
 
108
		# if we've wrapped the text, then adjust the wrap to the last word	  
109
		if i < len(text): 
110
			i = text.rfind(" ", 0, i) + 1
111
 
112
		# render the line and blit it to the surface
113
		if bkg:
114
			image = font.render(text[:i], 1, color, bkg)
115
			image.set_colorkey(bkg)
116
		else:
117
			image = font.render(text[:i], aa, color)
118
 
119
		surface.blit(image, (rect.left, y))
120
		y += fontHeight + lineSpacing
121
 
122
		# remove the text we just blitted
123
		text = text[i:]
124
 
125
	return text
126

    
127
def load_stations():
128
	global stations
129

    
130
	fp = open('/var/www/html/stations.json', 'r')
131
	stations = json.load(fp)
132
	fp.close()
133

    
134
	client.clear()
135
	for ind in range(numSta):
136
		station = stations[ind]
137
		name = station['name']
138
		url = station['url']
139
		#print ind, name, url
140
		if url == "" or name == "":
141
			client.add("silence.mp3")
142
		else:
143
			client.add(url)
144

    
145
client = mpd.MPDClient()
146
client.connect("localhost", 6600)
147
#client.setvol(0)
148
call(["amixer", "sset",  "Master", str(0)])
149

    
150
load_stations()
151

    
152
print stations
153
print
154
pls = client.playlist()
155
for pl in pls:
156
	print pl
157
print
158

    
159
# Define the switch
160
rswitch = RotaryEncoder(PIN_A,PIN_B,BUTTON,switch_event)
161
volswitch = RotaryEncoder(PIN_A_V,PIN_B_V,BUTTON_V,volume_event)
162

    
163
# Initialise screen
164
pygame.display.init()
165
pygame.mixer.quit()
166
screen = pygame.display.set_mode((320, 240))
167
pygame.mouse.set_visible(False)
168

    
169
txtsurf1a = pygame.Surface((120, 32))
170
txtsurf1b = pygame.Surface((200, 32))
171
txtsurf1 = pygame.Surface((320, 32))
172
txtsurf2 = pygame.Surface((320, 64))
173

    
174
# Display some text
175
pygame.font.init()
176
font1 = pygame.font.Font(None, 48)
177
font2 = pygame.font.Font(None, 32)
178
text = font1.render("FabLab Radio", 1, (250, 50, 50))
179
textpos = text.get_rect()
180
textpos.centerx = 160
181
screen.blit(text, textpos)
182

    
183
while True:
184
	time.sleep(0.1)
185

    
186
	if changedVol:
187
		changedVol = False
188

    
189
		txtsurf1a.fill((0, 0, 0))
190
		if mute:
191
			#print "mute"
192
			#client.setvol(0)
193
                        call(["amixer", "sset",  "Master", str(0)])
194
			text = font2.render("Vol: mute", 1, (50, 250, 50))
195
		else:
196
			#print "volume",volume
197
			if (volume == 0):
198
				vol = 0
199
			else:
200
				vol = math.trunc(72*math.log10(volume))
201
			#client.setvol(vol)
202
                        call(["amixer", "sset",  "Master", str(vol)])
203
			text = font2.render("Vol: " + str(volume), 1, (50, 250, 50))
204

    
205
		txtsurf1a.blit(text, (10, 0))
206
		screen.blit(txtsurf1a, (200, 214))
207

    
208
	if changed:
209
		changed = False
210
		load_stations()
211
		station = stations[index]
212
		name = station['name']
213
		url = station['url']
214
		print index, name, url
215

    
216
		if play and url != "" and name != "":
217
			print "play"
218
			txtsurf1b.fill((0, 0, 0))
219
			text = font2.render("[play]", 1, (250, 50, 50))
220
			txtsurf1b.blit(text, (80, 0))
221
			text = font2.render("Sta: " + str(index+1), 1, (50, 250, 50))
222
			txtsurf1b.blit(text, (4, 0))
223
			screen.blit(txtsurf1b, (0, 214))
224

    
225
			txtsurf1.fill((0, 0, 0))
226
			text = font2.render(name, 1, (50, 250, 50))
227
			txtsurf1.blit(text, (4, 0))
228
			screen.blit(txtsurf1, (0, 32))
229

    
230
			client.play(index)
231
		else:
232
			print "stop"
233
			play = False
234
			txtsurf1b.fill((0, 0, 0))
235
			text = font2.render("[stop]", 1, (250, 50, 50))
236
			txtsurf1b.blit(text, (80, 0))
237
			text = font2.render("Sta: " + str(index+1), 1, (50, 250, 50))
238
			txtsurf1b.blit(text, (4, 0))
239
			screen.blit(txtsurf1b, (0, 214))
240

    
241
			txtsurf1.fill((0, 0, 0))
242
			text = font2.render(name, 1, (50, 250, 50))
243
			txtsurf1.blit(text, (4, 0))
244
			screen.blit(txtsurf1, (0, 32))
245

    
246
			client.stop()
247

    
248
	cs = client.currentsong()
249
	if play and cs:
250
		#print cs
251
		#print
252
		if 'title' in cs:
253
		        SongTitle = cs['title']
254
		elif 'file' in cs:
255
		 	SongTitle = cs['file']
256

    
257
		txtsurf2.fill((0, 0, 0))
258
		drawText(txtsurf2, SongTitle, (50, 50, 250), txtsurf2.get_rect(), font2, 1)
259
		screen.blit(txtsurf2, (0, 150))
260

    
261
		if 'name' in cs:
262
			txt = cs['name']
263
			txtsurf2.fill((0, 0, 0))
264
			drawText(txtsurf2, txt, (250, 250, 50), txtsurf2.get_rect(), font2, 1)
265
			screen.blit(txtsurf2, (0, 60))
266

    
267
			txtsurf1.fill((0, 0, 0))
268
			text = font2.render("genre", 1, (50, 250, 250))
269
			txtsurf1.blit(text, (4, 0))
270
			screen.blit(txtsurf1, (0, 120))
271
	else:
272
		txtsurf2.fill((0, 0, 0))
273
		screen.blit(txtsurf2, (0, 60))
274
		screen.blit(txtsurf2, (0, 150))
275
		txtsurf1.fill((0, 0, 0))
276
		screen.blit(txtsurf1, (0, 120))
277

    
278
	for event in pygame.event.get():
279
		if event.type == QUIT:
280
			exit()
281

    
282
	pygame.display.flip()
283

    
(1-1/4)