{"id":14965182,"url":"https://github.com/mikegoatly/resona","last_synced_at":"2025-10-25T11:31:06.726Z","repository":{"id":155504468,"uuid":"627513243","full_name":"mikegoatly/Resona","owner":"mikegoatly","description":"An audiobook/music/sleep tunes audio player designed to run on a Raspberry Pi","archived":false,"fork":false,"pushed_at":"2024-08-29T18:27:21.000Z","size":2373,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-02-08T19:51:44.238Z","etag":null,"topics":["audio-player","audiobooks","avalonia","avalonia-ui","avalonia11","avaloniaui","avaloniaui-app","csharp","dotnet","raspberry-pi"],"latest_commit_sha":null,"homepage":"","language":"C#","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/mikegoatly.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-04-13T16:12:08.000Z","updated_at":"2025-01-13T10:06:31.000Z","dependencies_parsed_at":"2024-08-28T18:59:48.810Z","dependency_job_id":"6e849475-a60f-4817-b526-0a5f9491abd9","html_url":"https://github.com/mikegoatly/Resona","commit_stats":{"total_commits":92,"total_committers":2,"mean_commits":46.0,"dds":"0.17391304347826086","last_synced_commit":"29c1de1a8afa7a06a624ab058cc4d8dce609ead0"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikegoatly%2FResona","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikegoatly%2FResona/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikegoatly%2FResona/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikegoatly%2FResona/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mikegoatly","download_url":"https://codeload.github.com/mikegoatly/Resona/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238128529,"owners_count":19421052,"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":["audio-player","audiobooks","avalonia","avalonia-ui","avalonia11","avaloniaui","avaloniaui-app","csharp","dotnet","raspberry-pi"],"created_at":"2024-09-24T13:34:20.131Z","updated_at":"2025-10-25T11:31:01.258Z","avatar_url":"https://github.com/mikegoatly.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Resona\nAn audiobook/music/sleep tunes audio player designed to run on a Raspberry Pi.\n\n![Screenshot of the player view in Resona](docs/player.png)\n\n## Motivation\n\nI wanted to have a single-use device for playing audio that my kids could safely use in their bedroom, without giving them a phone or tablet that also gave them other unhelpful distractions. \n\nThis is a rebuild of an old project which had an ASP.NET core backend with a Blazor client. This new\nversion relies on [Avalonia UI](https://www.avaloniaui.net/). Having all the logic and UI combined in a single executable has proven to be much more efficient and development has been much quicker.\nThis all came together as a spare time project over the course of a couple of weeks.\n\nYou can clone and run this repo locally to try it out, and deploy it to a Raspberry Pi using the dev notes below. I might look to streamline the installation process at some point if there's\ndemand for it - I'd also be happy to receive contributions.\n\n### Roadmap\n\nI've a couple of things I still want to do:\n\n* ~~Expose a web application from the device that parents can use to upload new content, rather than using `scp` 😊~~ In progress - see the experimental web host section below\n* ~~Allow for more configuration options to allow kids to personalize things a bit, including the main icons for the home screen.~~ Can be done using the web interface 😊\n\n# Features\n\n## Three sections for audio content\n\n* Audiobooks\n* Music\n* Sleep Tunes\n\n![Home screen](docs/home.png)\n\nFiles are added to the database by scanning a folder on the local filesystem. This is currently the well known location, `home/pi/audiobooks`, `home/pi/music` and `home/pi/sleep`.\n\n## Sleep timers\n\n* Sleep timer to stop playback after a set time\n* Auto-shutdown on lack of interactivity (2 hours by default)\n* Screen dimming to prevent glare at night (30 seconds by default)\n\n![Sleep timer optons](docs/sleep-timer.png)\n\n## Album art\n\nAlbum art is loaded from (in order of preference):\n\n* `image.jpg` or `image.png` in the album folder\n* The first `mp3` file in the album folder that contains an embedded image\n\n![Track selection](docs/track-selection.png)\n\n## Playback\n\n* Resona keeps track of the last played position of albums and will be ready to continue playing from the last played track when it restarts\n* Scrubbing supported\n* Volume control through the player in case your display doesn't have volume controls\n\n![Player screenshot](docs/player.png)\n\n## Audio output selection\n\nSelect the audio output channel through the UI:\n\n![Audio output selection](docs/audio-output-selection.png)\n\nScan for and pair bluetooth devices:\n\n![Bluetooth device scanning](docs/bluetooth-devices.png)\n\n# Dev notes\n\n## Raspberry Pi installation\n\n1. Install Raspberry Pi OS Lite. The easiest way to do this is with the [Raspberry Pi Imager](https://www.raspberrypi.com/software/), making sure you apply these settings before installing:\n  * Set the host name to something unique on your network, e.g. `dev`\n  * Enable SSH\n  * Configure the wireless LAN\n1. Install any dependencies for the touchscreen display attached to your Pi. \n1. Use `raspi-config` and change `System options \u003e Boot / Auto Login` to `Console Autologin`.\n1. From your dev computer run `copy-pi-scripts.ps1 -Server \u003cPiName\u003e` which will copy Resona scripts to your Pi.\n1. From your Pi (SSH or direct), run `./install-dependencies.sh` and use one of them to install the relevant dependencies\n1. (Optional) From your Pi, run `./configure-auto-run.sh` to configure Resona to auto run whenever your Pi starts up. If you don't do this you'll have to manually start Resona each time from \n   either your dev computer using SSH or the Pi itself by running `~/bin/Resona --drm`. You can temporarily disable the service using `./disable-auto-run.sh` and re-enable with \n   `./reenable-auto-run.sh`.\n\n## Build and deploy Resona to your Pi\n\nRun `publish.ps1 -Server \u003cPiName\u003e` to build and deploy the project to your Pi.\n\n`publish.ps1` options:\n\n* `-Server` - The name of the Pi to deploy to\n* `-DebugBuild` Builds in debug mode with no trimming\n* `-NoClean` Only makes sense when used when publishing with -DebugBuild. Only copies changes to the Resona assemblies, keeping the existing .NET framework and other dependencies. Can be used for a faster dev inner loop when testing code on the Pi.\n* `-NoBuild` Deploys without rebuilding the packaged artifacts\n\nPublishing will:\n\n* Rebuild the project\n* Stop and disable the service on the Pi (which will kill the app if it's running via the service)\n* Copy the updated artifacts\n* Re-enable and start the service on the Pi (if installed) - the app will auto run ready for you to play with it.\n\n## Experimental web host\n\nSome work has been done to expose a React-based web interface from the Pi. It's turned off by default but can be enabled from the advanced settings page.\n\nOnce enabled, you can access the web interface from any device on the same network as the Pi by navigating to `http://\u003cPiName\u003e:8080`.\n\nThe web interface allows you to view what's currently in the library:\n\n![Web interface library view](docs/web-library.png)\n\nAnd also upload new content:\n\n![Web interface upload view](docs/web-upload.png)\n\n### Additional configuration\n\nIf you want to add a splash screen and get rid of all the scrolling boot up text the Pi shows, follow these steps:\n\n1. Add the line `disable_splash=1` to `/boot/firmware/config.txt`.\n1. Add `logo.nologo consoleblank=0 loglevel=1 quiet splash` to `/boot/firmware/cmdline.txt`.\n1. Add a splashscreen\n\t1. Install `fbi` with `sudo apt install fbi`\n\t1. Create a splash screen image and save it as `/home/pi/splash.png`\n\t1. `sudo nano /etc/systemd/system/splashscreen.service` and enter\n\t\t```\n\t\t[Unit]\n\t\tDescription=Splash screen\n\t\tAfter=local-fs.target\n\n\t\t[Service]\n\t\tExecStart=/usr/bin/fbi -d /dev/fb0 --noverbose -a /home/pi/splash.png\n\t\tStandardInput=tty\n\t\tStandardOutput=tty\n\n\t\t[Install]\n\t\tWantedBy=sysinit.target\n\t\t```\n\t1. `sudo systemctl enable splashscreen.service`\n\n### Touchscreen installation\n\nThis section contains notes about the various touchscreens used during development.\n\n#### Wimaxit 7\" Capacitive with sound\n\nAdd this to the end of /boot/firmware/config.txt:\n\n```\nhdmi_force_edid_audio=1\nmax_usb_current=1\nhdmi_force_hotplug=1\nconfig_hdmi_boost=7\nhdmi_group=2\nhdmi_mode=87\nhdmi_drive=2\ndisplay_rotate=0\nhdmi_cvt 1024 600 60 6 0 0 0\n```\n\nEnable fkms to fix audio issues:\n\n```\nsudo sed -i 's/dtoverlay=vc4-kms-v3d/dtoverlay=vc4-fkms-v3d/g' /boot/firmware/config.txt\n```\n\n#### \n\n## Database\n\nWork on the core database structure is ongoing, so I'm just going to recreate the initial database structure every time I make a change using:\n\n``` powershell\ncd src\\Resona.Persistence\nrm -r Migrations\nmd Migrations\ndotnet ef migrations add InitialCreate --startup-project ..\\Resona.UI -o Migrations\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikegoatly%2Fresona","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmikegoatly%2Fresona","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikegoatly%2Fresona/lists"}