Project

General

Profile

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