{"id":22057075,"url":"https://github.com/fspoettel/thirtytwopixels","last_synced_at":"2025-05-12T16:02:36.467Z","repository":{"id":42173839,"uuid":"296706126","full_name":"fspoettel/thirtytwopixels","owner":"fspoettel","description":"🖼️ wireless LED album art display for spotify, mpd+ncmpcpp and other players.","archived":false,"fork":false,"pushed_at":"2022-04-11T20:30:52.000Z","size":2362,"stargazers_count":49,"open_issues_count":0,"forks_count":1,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-04-13T16:12:31.167Z","etag":null,"topics":["led-matrix","mpd","ncmpcpp","raspberry-pi","spotify"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fspoettel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-09-18T18:56:52.000Z","updated_at":"2024-02-14T10:42:34.000Z","dependencies_parsed_at":"2022-08-12T08:40:37.105Z","dependency_job_id":null,"html_url":"https://github.com/fspoettel/thirtytwopixels","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fspoettel%2Fthirtytwopixels","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fspoettel%2Fthirtytwopixels/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fspoettel%2Fthirtytwopixels/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fspoettel%2Fthirtytwopixels/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fspoettel","download_url":"https://codeload.github.com/fspoettel/thirtytwopixels/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227370656,"owners_count":17770706,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["led-matrix","mpd","ncmpcpp","raspberry-pi","spotify"],"created_at":"2024-11-30T16:16:05.024Z","updated_at":"2025-05-12T16:02:36.438Z","avatar_url":"https://github.com/fspoettel.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# thirtytwopixels\n\n\u003cdiv\u003e\n    \u003cimg height=\"400\" src=\"./assets/build_dark.jpg\" alt=\"Finished build in a dark room\" /\u003e\n\u003c/div\u003e\n\n\u003e wireless LED album art display\n\nSupported players:\n- [mpd](https://www.musicpd.org/)+[ncmpcpp](https://wiki.archlinux.org/index.php/ncmpcpp)\n- spotify\n- [home assistant](https://www.home-assistant.io/)\n- other players via the command-line interface\n\n## Hardware\n\n- Raspberry Pi Zero WH\n- [Adafruit RGB Matrix Bonnet](https://www.adafruit.com/product/3211)\n- A 32x32 (or 64x64) LED matrix with a HUB75 connection (available on e.g. Adafruit, Pimoroni, Aliexpress). I used [this one](https://shop.pimoroni.com/products/rgb-led-matrix-panel?variant=35962488650).\n- A 5V 4A power adapter\n\nRefer to the [Adafruit instructions](https://learn.adafruit.com/adafruit-rgb-matrix-bonnet-for-raspberry-pi/) to set it up.\nI recommend to do [the PWM mod](https://github.com/hzeller/rpi-rgb-led-matrix#improving-flicker), it removed noticeable flicker for me. This requires minor soldering.\n\n## Setup\n\nThe project is split into two parts:\n\n- a `server` script that runs on a raspberry pi connected to the LED matrix\n- a client script that is invoked from `ncmpcpp`'s config hooks and a CLI. Communication between client and server is handled by a 0MQ TCP socket.\n\n### Client\n\nClone this repo:\n\n``` sh\ngit clone https://github.com/fspoettel/thirtytwopixels\n```\n\nInstall required modules:\n\n```sh\npip3 install -r requirements.txt\n```\n\n#### Command-line interface (CLI)\n\n- `python3 scripts/show.py \u003cpath_to_image\u003e` displays an arbitrary image\n- `python3 scripts/clear.py` clears the display\n\n#### MPD integration\n\nAdd the following lines to `~/.ncmpcpp/config`:\n\n```conf\n# errors and output is appended to syslog\nexecute_on_song_change=\"(path_to_repo/scripts/on_song_change.py \u0026\u003e /dev/null \u0026)\"\nexecute_on_player_state_change = \"(path_to_repo/scripts/on_player_state_change.py \u0026\u003e /dev/null \u0026)\"\n```\n\nMake sure that our hooks are executable:\n\n```sh\nchmod +x scripts/on_song_change.py\nchmod +x scripts/on_player_state_change.py\n```\n\nIf your pi is not using the host name `raspberrypi.local`, you will need to adjust `ZMQ_HOST` in `./client/matrix_connection.py`.\n\n\u003e ℹ️ It is assumed that `cover.{jpg,png}` files are stored in the album folders alongside music files. If that is not the case, you'll need to implement a module analogous to `./client/mpd.py` and call its `get_cover` method in `./scripts/on_song_change.py`. The method should return an absolute file system path to an image.\n\n### Server (Raspberry Pi)\n\nInstall raspbian on your pi and connect it to your network. ssh into it and make sure the following packages are installed:\n\n```sh\nsudo apt install python3 pip3 git libjpeg-dev\n```\n\nClone this repo **recursively** to include the [rpi-rgb-led-matrix](https://github.com/hzeller/rpi-rgb-led-matrix) submodule:\n\n```sh\ngit clone --recursive https://github.com/fspoettel/thirtytwopixels\n```\n\nInstall required modules. Note that the script **needs to use** sudo to interface with the hardware:\n\n```sh\ncd thirtytwopixels\nsudo pip3 install -r requirements.txt\n```\n\nSetup [rpi-rgb-led-matrix](https://github.com/hzeller/rpi-rgb-led-matrix). This may take a while to complete.\n\n```sh\ncd matrix\nmake build-python PYTHON=$(which python3)\nsudo make install-python PYTHON=$(which python3)\n```\n\nSet / adjust panel options in `server/matrix_factory.py`:\n\n```py\ndef matrix_factory(width):\n    options = RGBMatrixOptions()\n    # ...\n    panel = RGBMatrix(options=options)\n    return panel\n\n```\n\nRun the server:\n\n```sh\nsudo python3 server/server.py\n```\n\nYou can now send test images to the panel via the cli. Once you are happy with the panel config, you can add the server as a `systemd` service which is started at startup. To do that, create the following file at `/etc/systemd/system/thirtytwopixels.service`:\n\n```sh\n[Unit]\nDescription=thirtytwopixels tcp server\n\n[Service]\nExecStart=/usr/bin/python3 /usr/local/lib/thirtytwopixels/server/server.py\n\n[Install]\nWantedBy=default.target\n```\n\nand move the repo to `/usr/local/lib/`:\n\n```sh\nmv thirtytwopixels /usr/local/lib/\nsudo chown root:root /usr/local/lib/thirtytwopixels/server/server.py\nsudo chmod 644 /usr/local/lib/thirtytwopixels/server/server.py\n```\n\nYou can then enable the service via:\n\n```sh\nsudo systemctl enable thirtytwopixels.service\n```\n\n### Spotify\n\n\u003e Caution: the cli and socket interface currently will not work if you are using spotify. If this is an issue for you, please open a feature request.\n\nCreate a [spotify application](https://developer.spotify). As redirect_url, set `http://localhost:9090/callback`. (feel free to change, it doesn't matter)\nThen run:\n\n``` sh\nexport SPOTIPY_CLIENT_ID=\u003capp client id\u003e\nexport SPOTIPY_CLIENT_SECRET=\u003capp client secret\u003e\nexport SPOTIPY_REDIRECT_URI=\"http://localhost:9090/callback\"\n./scripts/spotify_login.py\n```\n\nOpen the displayed URL in your local browser and log into spotify. It redirects you to a non-existing `http://localhost:9090/callback` URL with some query params. Copy the URL and past it into the ssh terminal. If it worked, the message _Succesfully logged in as user {you}_ should be displayed and a file `.cache` should be added in the repository root.\n\nEdit the service to include spotify credentials. Run `sudo systemctl edit thirtytwopixels.service` and set enter the\n\n```\n[Service]\nWorkingDirectory=/usr/local/lib/thirtytwopixels\nEnvironment=\"SPOTIPY_CLIENT_ID=\u003capp client id\u003e\"\nEnvironment=\"SPOTIPY_CLIENT_SECRET=\u003capp client secret\u003e\"\nEnvironment=\"SPOTIPY_REDIRECT_URI=http://localhost:9090/callback\"\n```\n\nEdit `./server/server.py`, comment out the line `provider = SocketBinding(panel)` and uncomment the line `provider = SpotifyBinding(panel)`.\n\nRestart the server:\n\n```sh\nsudo systemctl restart thirtytwopixels.service\n```\n\n### Home Assistant\nIf you are using [Home Assistant](https://www.home-assistant.io/), and optionally [Music Assistant](https://music-assistant.io/), this can also be used to provide album art for your media.\n\nEdit the service to include HomeAssistant credentials. Run `sudo systemctl edit thirtytwopixels.service` and set\n\n```\n[Service]\nWorkingDirectory=/usr/local/lib/thirtytwopixels\nEnvironment=\"HA_BASE_URL=http://\u003cha_ip\u003e:8123\"\nEnvironment=\"HA_ENTITY_ID=media_player.\u003cname\u003e\"\nEnvironment=\"HA_TOKEN=\u003clong_lived_ha_token\u003e\"\n```\n\nEdit `./server/server.py`, comment out the line `provider = SocketBinding(panel)` and uncomment the line `provider = HomeAssistantBinding(panel)`.\n\nRestart the server:\n\n```sh\nsudo systemctl restart thirtytwopixels.service\n```\n\n## Pictures\n\n\u003cdiv align=\"center\"\u003e\n    \u003cimg src=\"./assets/build_light.jpg\" alt=\"Finished build in a light room\" /\u003e\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n    \u003cimg src=\"./assets/build_back.jpg\" alt=\"Back of finished build\" /\u003e\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n    \u003cimg src=\"./assets/64x64.jpg\" alt=\"64x64 led matrix\" /\u003e\n\u003c/div\u003e\n\n## In the wild\n\n- [Hackaday article](https://hackaday.com/2020/10/11/lo-fi-art-on-a-32x32-matrix/)\n- [flipflip's AlbumArtDisplay](https://github.com/phkehl/AlbumArtDisplay) using ESP32 and Arduino\n- Built something? [Add it!](https://github.com/fspoettel/thirtytwopixels/edit/master/README.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffspoettel%2Fthirtytwopixels","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffspoettel%2Fthirtytwopixels","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffspoettel%2Fthirtytwopixels/lists"}