diff --git a/examples/labs/miniscreen_radio/icons/BBC Asian Network.bmp b/examples/labs/miniscreen_radio/icons/BBC Asian Network.bmp new file mode 100644 index 000000000..5b9a4bddd Binary files /dev/null and b/examples/labs/miniscreen_radio/icons/BBC Asian Network.bmp differ diff --git a/examples/labs/miniscreen_radio/icons/BBC Radio 1 Xtra.bmp b/examples/labs/miniscreen_radio/icons/BBC Radio 1 Xtra.bmp new file mode 100644 index 000000000..f20fd216d Binary files /dev/null and b/examples/labs/miniscreen_radio/icons/BBC Radio 1 Xtra.bmp differ diff --git a/examples/labs/miniscreen_radio/icons/BBC Radio 1.bmp b/examples/labs/miniscreen_radio/icons/BBC Radio 1.bmp new file mode 100644 index 000000000..b650ddb75 Binary files /dev/null and b/examples/labs/miniscreen_radio/icons/BBC Radio 1.bmp differ diff --git a/examples/labs/miniscreen_radio/icons/BBC Radio 2.bmp b/examples/labs/miniscreen_radio/icons/BBC Radio 2.bmp new file mode 100644 index 000000000..d11972739 Binary files /dev/null and b/examples/labs/miniscreen_radio/icons/BBC Radio 2.bmp differ diff --git a/examples/labs/miniscreen_radio/icons/BBC Radio 3.bmp b/examples/labs/miniscreen_radio/icons/BBC Radio 3.bmp new file mode 100644 index 000000000..09a5a1ba3 Binary files /dev/null and b/examples/labs/miniscreen_radio/icons/BBC Radio 3.bmp differ diff --git a/examples/labs/miniscreen_radio/icons/BBC Radio 4 FM.bmp b/examples/labs/miniscreen_radio/icons/BBC Radio 4 FM.bmp new file mode 100644 index 000000000..7147b96e5 Binary files /dev/null and b/examples/labs/miniscreen_radio/icons/BBC Radio 4 FM.bmp differ diff --git a/examples/labs/miniscreen_radio/icons/BBC Radio 5 Live.bmp b/examples/labs/miniscreen_radio/icons/BBC Radio 5 Live.bmp new file mode 100644 index 000000000..8e473aa1e Binary files /dev/null and b/examples/labs/miniscreen_radio/icons/BBC Radio 5 Live.bmp differ diff --git a/examples/labs/miniscreen_radio/icons/BBC Radio 6.bmp b/examples/labs/miniscreen_radio/icons/BBC Radio 6.bmp new file mode 100644 index 000000000..8f37c6836 Binary files /dev/null and b/examples/labs/miniscreen_radio/icons/BBC Radio 6.bmp differ diff --git a/examples/labs/miniscreen_radio/icons/BBC Radio Scotland FM.bmp b/examples/labs/miniscreen_radio/icons/BBC Radio Scotland FM.bmp new file mode 100644 index 000000000..af324c767 Binary files /dev/null and b/examples/labs/miniscreen_radio/icons/BBC Radio Scotland FM.bmp differ diff --git a/examples/labs/miniscreen_radio/icons/BBC Radio Wales FM.bmp b/examples/labs/miniscreen_radio/icons/BBC Radio Wales FM.bmp new file mode 100644 index 000000000..29acd3cd6 Binary files /dev/null and b/examples/labs/miniscreen_radio/icons/BBC Radio Wales FM.bmp differ diff --git a/examples/labs/miniscreen_radio/icons/BBC World Service.bmp b/examples/labs/miniscreen_radio/icons/BBC World Service.bmp new file mode 100644 index 000000000..e70988d66 Binary files /dev/null and b/examples/labs/miniscreen_radio/icons/BBC World Service.bmp differ diff --git a/examples/labs/miniscreen_radio/icons/Pause.bmp b/examples/labs/miniscreen_radio/icons/Pause.bmp new file mode 100644 index 000000000..45a4e1514 Binary files /dev/null and b/examples/labs/miniscreen_radio/icons/Pause.bmp differ diff --git a/examples/labs/miniscreen_radio/icons/Unknown.bmp b/examples/labs/miniscreen_radio/icons/Unknown.bmp new file mode 100644 index 000000000..da9d9616b Binary files /dev/null and b/examples/labs/miniscreen_radio/icons/Unknown.bmp differ diff --git a/examples/labs/miniscreen_radio/icons/Unknown_BlackShaded.bmp b/examples/labs/miniscreen_radio/icons/Unknown_BlackShaded.bmp new file mode 100644 index 000000000..d589be4b6 Binary files /dev/null and b/examples/labs/miniscreen_radio/icons/Unknown_BlackShaded.bmp differ diff --git a/examples/labs/miniscreen_radio/icons/Unknown_WhiteShaded.bmp b/examples/labs/miniscreen_radio/icons/Unknown_WhiteShaded.bmp new file mode 100644 index 000000000..19e614560 Binary files /dev/null and b/examples/labs/miniscreen_radio/icons/Unknown_WhiteShaded.bmp differ diff --git a/examples/labs/miniscreen_radio/notes.txt b/examples/labs/miniscreen_radio/notes.txt new file mode 100644 index 000000000..15694ba16 --- /dev/null +++ b/examples/labs/miniscreen_radio/notes.txt @@ -0,0 +1,34 @@ + +Full Installation Instructions: + +Run the following terminal commands +sudo apt-get update +sudo apt-get install mpd mpc +pip3 install python-mpd2 + +In this file + sudo nano /etc/mpd.conf +Find the audio_output section, and change it to look like this: + +audio_output { + type "alsa" + name "My ALSA Device" + device "hw:1" # optional +# mixer_type "hardware" # optional +# mixer_device "default" # optional +# mixer_control "PCM" # optional +# mixer_index "0" # optional +} + + +Useful terminal commands: +Check on the general status of the media player client with’ mpc status’ +And in the (currently very likely) event that you can’t stop the music after killing python script, use ‘mpc stop’ +If you fuck up the OLED in code, you can fix things by restarting first the device manager service, and then the OLED service: +sudo systemctl restart pt-device-manager.service +sudo systemctl restart pt-sys-oled.service + +Other notes: +Find new m3u (or m3u8) feeds at http://www.radiofeeds.co.uk/default.asp +Streams in AAC/AAC+ (HLS) format seem to work well +Click on the station you want, then copy the link for e.g. the BBC asian network on the page (http://lsn.to/BAN), right click on quality you want e.g. ‘96K Stereo’ and paste link into radio_stations list in pi-topRadio.py diff --git a/examples/labs/miniscreen_radio/pi-topRadio.py b/examples/labs/miniscreen_radio/pi-topRadio.py new file mode 100644 index 000000000..cdc2365f2 --- /dev/null +++ b/examples/labs/miniscreen_radio/pi-topRadio.py @@ -0,0 +1,192 @@ +from mpd import MPDClient +from mpd.base import ConnectionError +from pitop.miniscreen import Miniscreen +from signal import pause +from time import sleep +import os +import sys + + +class StationManager: + def __init__(self): + self._client = MPDClient() + self._client.timeout = 10 # network timeout in seconds (floats allowed), default: None + self._client.idle_timeout = None + + self.playlist_id = None + + # List of Radio Stations. Note that in this dictionary Keys are used to find bitmap names (name + .bmp), + # and Values are stream URL + self.radio_stations = { + "BBC Radio 1": "http://a.files.bbci.co.uk/media/live/manifesto/audio/simulcast/hls/nonuk/sbr_low/ak/bbc_radio_one.m3u8", + "BBC Radio 1 Xtra": "http://a.files.bbci.co.uk/media/live/manifesto/audio/simulcast/hls/nonuk/sbr_low/ak/bbc_1xtra.m3u8", + "BBC Radio 2": "http://a.files.bbci.co.uk/media/live/manifesto/audio/simulcast/hls/nonuk/sbr_low/ak/bbc_radio_two.m3u8", + "BBC Radio 3": "http://a.files.bbci.co.uk/media/live/manifesto/audio/simulcast/hls/nonuk/sbr_low/ak/bbc_radio_three.m3u8", + "BBC Radio 4 FM": "http://a.files.bbci.co.uk/media/live/manifesto/audio/simulcast/hls/nonuk/sbr_low/ak/bbc_radio_fourfm.m3u8", + "BBC Radio 5 Live": "http://a.files.bbci.co.uk/media/live/manifesto/audio/simulcast/hls/nonuk/sbr_low/ak/bbc_radio_five_live.m3u8", + "BBC Radio 6": "http://a.files.bbci.co.uk/media/live/manifesto/audio/simulcast/hls/nonuk/sbr_low/ak/bbc_6music.m3u8", + "BBC Asian Network": "http://a.files.bbci.co.uk/media/live/manifesto/audio/simulcast/hls/nonuk/sbr_low/ak/bbc_asian_network.m3u8", + "BBC World Service": "http://a.files.bbci.co.uk/media/live/manifesto/audio/simulcast/hls/nonuk/sbr_low/ak/bbc_world_service.m3u8", + "BBC Radio Scotland FM": "http://a.files.bbci.co.uk/media/live/manifesto/audio/simulcast/hls/nonuk/sbr_low/ak/bbc_radio_scotland_fm.m3u8", + "BBC Radio Wales FM": "http://a.files.bbci.co.uk/media/live/manifesto/audio/simulcast/hls/nonuk/sbr_low/ak/bbc_radio_wales_fm.m3u8", + } + + # Add radio streams + self.client.clear() + for radio in self.radio_stations.values(): + self.client.add(radio) + + @staticmethod + def _get_data_from_client(client_function): + attempts = 0 + + thing = None + while thing is None and attempts < 6: + try: + thing = client_function() + except (ConnectionError, KeyError): + attempts += 1 + sleep(0.5) + + if attempts != 0: + print(f"Took {attempts + 1} attempts to get thing") + + return thing + + def get_client_current_song(self): + return self._get_data_from_client(self.client.currentsong) + + def get_client_status(self): + return self._get_data_from_client(self.client.status) + + def get_client_stats(self): + return self._get_data_from_client(self.client.stats) + + def get_client_playlist_id(self): + return self._get_data_from_client(self.client.playlistid) + + def debug(self): + print(f"currentsong: {self.get_client_current_song()}") + print(f"status: {self.get_client_status()}") + print(f"stats: {self.get_client_stats()}") + print(f"playlistid: {self.get_client_playlist_id()}") + + @property + def current_station_name(self): + radio_names_list = list(self.radio_stations) # create indexed list of all keys from radio_stations dict + return radio_names_list[int(self.get_client_current_song()['pos'])] + + @property + def current_station_number(self): + return int(self.get_client_status()["song"]) + + @property + def number_of_stations(self): + return int(self.get_client_status()["playlistlength"]) + + def next(self): + if self.current_station_number == self.number_of_stations - 1: + print("End of playlist - going to start") + self.client.play(0) + else: + self.client.next() + + def previous(self): + if self.current_station_number == 0: + print("Start of playlist - going to end") + self.client.play(self.number_of_stations - 1) + else: + self.client.previous() + + def toggle_play(self): + if self.get_client_status()["state"] == "pause": + print("Starting playback...") + play_pause_state = "playing" + else: + print("Stopping playback...") + play_pause_state = "stopped" + + self.client.pause() # This client function actually toggles + return play_pause_state + + def play(self): + try: + self.client.play(self.current_station_number) + except KeyError: + self.client.play(0) + + def exit(self): + self.client.stop() + self.client.close() + self.client.disconnect() + + @property + def client(self): + try: + self._client.connect("localhost", 6600) + except ConnectionError as e: + pass + + return self._client + + +def display_station(): + print(f"Playing station: {station_manager.current_station_name}") + image_file_path = os.path.join(os.path.dirname(__file__), + "icons/") + station_manager.current_station_name + ".bmp" + try: + miniscreen.display_image_file(image_file_path) + except: + print("Couldn't find image file for '" + image_file_path + "'") + miniscreen.display_multiline_text(station_manager.current_station_name, font_size=15) + + +def prev_station(): + miniscreen.display_multiline_text("Loading...", font_size=15) + station_manager.previous() + display_station() + + +def next_station(): + miniscreen.display_multiline_text("Loading...", font_size=15) + station_manager.next() + display_station() + + +def toggle_play(): + if station_manager.toggle_play() == "stopped": + image_file_path = os.path.join(os.path.dirname(__file__), "icons/") + "Pause.bmp" + try: + miniscreen.display_image_file(image_file_path) + except: + print("Couldn't find image file for '" + image_file_path + "'") + miniscreen.display_multiline_text("Paused", font_size=15) + else: + display_station() + + +def exit_radio(): + print("Exiting") + miniscreen.display_multiline_text("Exiting...", font_size=15) + station_manager.exit() + sys.exit() + + +def main(): + miniscreen.display_multiline_text("Loading...", font_size=15) + + miniscreen.up_button.when_pressed = prev_station + miniscreen.down_button.when_pressed = next_station + miniscreen.select_button.when_pressed = toggle_play + miniscreen.cancel_button.when_pressed = exit_radio + + station_manager.play() + display_station() + + pause() + + +if __name__ == "__main__": + miniscreen = Miniscreen() + station_manager = StationManager() + main()