Building Your Own Streaming Music Service
I listen to music whenever I have free time. The older I get, the more dependent I become on music. Whether it's on my way to work, while chopping vegetables, blocking out the noise from upstairs renovations, traveling, on the high-speed train, when I'm having insomnia late at night, or playing games, I almost always listen to something. There's a saying that music never betrays a person; it's a healing balm for the soul.
I used to use NetEase Cloud Music and even got a membership through a promotion, but I couldn't stand the constant splash screen ads, so I switched to Soda Music. The reason was that Soda Music made it easy to find all sorts of obscure songs from Douyin (TikTok), but recently it's also been bombarded with ads, even showing short drama ads while you're listening to music. Even worse, the recommendations are all repetitive and unreliable.
So the idea of creating my own streaming music service resurfaced. Before switching to Soda Music, I tried using Polaris + its accompanying iOS client, but the iOS client disappeared later.
Since things had come to this, I had to find another solution: Navidrome + Amperfy + yt-dlp, a clever combination to meet my budget-conscious needs.
Without further ado, let's get started:
1. Deploying Navidrome on a Raspberry Pi
Long-time readers might know that I've been using a Raspberry Pi to run Sing-box at home to bypass internet censorship. I maintain an automatic proxy, and it works easily on devices that support proxies, such as iPhones, iPads, and Firefox. It's much faster than using various VPNs, at least in my experience, trust me!
The Raspberry Pi is mounted next to the router, always on, consumes only a few watts, and has 10GB of storage, making it perfect for deploying Navidrome.
When installing Navidrome, be sure to choose the correct version. I used navidrome_0.58.5_linux_armv7.deb, note that it's armv7. Your Raspberry Pi is a Model B, so don't mix up the different architectures.
If you're running Debian on your Raspberry Pi like me, you'll get the following error:
1package architecture (armv7) does not match system (armhf)
Solution:
1sudo dpkg --add-architecture armv7
Then install:
1sudo apt install ./navidrome_0.58.5_linux_armv7.deb
I use the official default configuration, which I think is reasonable and standardized. Remember the music directory /opt/navidrome/music; put your music collection here.
1mephisto@raspberrypi:~ $ cat /etc/navidrome/navidrome.toml
2DataFolder = "/var/lib/navidrome"
3MusicFolder = "/opt/navidrome/music"
4
5mephisto@raspberrypi:~ $ systemctl cat navidrome.service
6# /etc/systemd/system/navidrome.service
7[Unit]
8Description=Your Personal Streaming Service
9ConditionFileIsExecutable=/usr/bin/navidrome
10
11After=remote-fs.target network.target
12
13[Service]
14StartLimitInterval=5
15StartLimitBurst=10
16ExecStart=/usr/bin/navidrome "service" "execute" "-c" "/etc/navidrome/navidrome.toml"
17WorkingDirectory=/var/lib/navidrome
18User=navidrome
19Restart=on-failure
20SuccessExitStatus=1 2 8 SIGKILL
21TimeoutStopSec=20
22RestartSec=120
23EnvironmentFile=-/etc/sysconfig/navidrome
24
25DevicePolicy=closed
26NoNewPrivileges=yes
27PrivateTmp=yes
28ProtectControlGroups=yes
29ProtectKernelModules=yes
30ProtectKernelTunables=yes
31RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
32RestrictNamespaces=yes
33RestrictRealtime=yes
34SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @setuid @swap
35ReadWritePaths=/var/lib/navidrome
36ProtectSystem=full
37
38[Install]
39
40WantedBy=multi-user.target
2. Music App Amperfy
Apple users can search and download it from the Apple Store; it's free (there are many more similar apps for Android, just choose one). I chose this one after comparing it with others and didn't find any bugs. The code is open source, and it's in no way inferior to some paid or personal apps.
The source code is here: https://github.com/BLeeEZ/amperfy. It's updated very frequently, much more active than Polaris, which I used before, and it shouldn't disappear. Of course, you can also choose other apps; it's a matter of personal preference.
3. How to Connect a Phone to a Streaming Service?
Both Navidrome and Amperfy are available. How do you connect them? It's very simple.
If you're on the same intranet, see the screenshot:
In the HTTP service field, enter something like: http://192.168.1.5:4533
The Navidrome service will listen on port 4533 after starting. The web page will guide you to create a username/password the first time you access it with your browser. It's very simple; try it and you'll understand.
Now everything is ready except for the final step. Actually, it can be optimized further. For example, how to access services on the Raspberry Pi when you're not at home or outside? We'll discuss that later.
4. Obtaining Music
This part is actually very sensitive, since music is now copyrighted. I can only say that everyone has their own methods. For example, if you have legal means to obtain it, I'm only verifying the technical solution and bear no legal responsibility.
This assumes you're downloading copyright-free music. Using the soundtrack from the game 0 A.D. as an example:
1➜ yt-dlp -x --cookies-from-browser firefox --proxy 192.168.1.5:1081 --no-check-certificate "https://www.youtube.com/watch?v=kUqhZTaxP50"
2Extracting cookies from firefox
3Extracted 1356 cookies from firefox
4[youtube] Extracting URL: https://www.youtube.com/watch?v=kUqhZTaxP50
5[youtube] kUqhZTaxP50: Downloading webpage
6[youtube] kUqhZTaxP50: Downloading tv downgraded player API JSON
7[youtube] kUqhZTaxP50: Downloading web safari player API JSON
8[youtube] kUqhZTaxP50: Downloading player b2515611-main
9[youtube] [jsc:deno] Solving JS challenges using deno
10WARNING: [youtube] [jsc] Remote components challenge solver script (deno) and NPM package (deno) were skipped. These may be required to solve JS challenges. You can enable these downloads with --remote-components ejs:github (recommended) or --remote-components ejs:npm , respectively. For more information and alternatives, refer to https://github.com/yt-dlp/yt-dlp/wiki/EJS
11WARNING: [youtube] kUqhZTaxP50: n challenge solving failed: Some formats may be missing. Ensure you have a supported JavaScript runtime and challenge solver script distribution installed. Review any warnings presented before this message. For more details, refer to https://github.com/yt-dlp/yt-dlp/wiki/EJS
12[youtube] kUqhZTaxP50: Downloading m3u8 information
13[info] kUqhZTaxP50: Downloading 1 format(s): 96
14[download] Sleeping 4.00 seconds as required by the site...
15[hlsnative] Downloading m3u8 manifest
16[hlsnative] Total fragments: 31
17[download] Destination: Ammon-Ra - 0 A.D Soundtrack [kUqhZTaxP50].mp4
18[download] 100% of 7.17MiB in 00:00:20 at 364.43KiB/s
19[FixupM3u8] Fixing MPEG-TS in MP4 container of "Ammon-Ra - 0 A.D Soundtrack [kUqhZTaxP50].mp4"
20[ExtractAudio] Destination: Ammon-Ra - 0 A.D Soundtrack [kUqhZTaxP50].m4a
21Deleting original file Ammon-Ra - 0 A.D Soundtrack [kUqhZTaxP50].mp4 (pass -k to keep)
22➜ ls -al Ammon-Ra\ -\ 0\ A.D\ Soundtrack\ \[kUqhZTaxP50\].m4a
23-rw-r--r-- 1 mephisto mephisto 2542396 Nov 21 19:32 'Ammon-Ra - 0 A.D Soundtrack [kUqhZTaxP50].m4a'
This will give you a music file with a .m4a extension. Other formats can also be obtained using parameters. The default m4a file sounds fine to me. If you insist on being able to distinguish between thermal power, hydroelectric power, and nuclear power, I admit you're better than me 😊.
Key component: yt-dlp -x --cookies-from-browser firefox --proxy 192.168.1.5:1081 --no-check-certificate
proxy 192.168.1.5:1081 is used for bypassing internet censorship. People in mainland China are lucky; they can learn technology there.
The other parameters were found online; otherwise, downloading wouldn't be possible. Getting cookies from the browser and ignoring the certificate took some time and experimentation.
With this, the music source issue is resolved. Again, I recommend only downloading copyright-free music! Another strong feeling is that yt-dlp is very powerful and easy to use.
5. How to Access from the Public Internet
Finally, some users may want to access the Navidrome service on their Raspberry Pi at home while out and about.
This is simply a network and resource issue. My solution is as follows, but it may not be suitable for everyone.
I have a domain name and a basic overseas web hosting plan, so I can easily solve the problem using frp. The traffic path is as follows:
Your hand, idly listening to music while out and about -> Phone 📱 -> Host with public domain name/IP (Frps) -> Raspberry Pi (Frpc) -> Navidrome -> Your saved songs
Frps server example (running on a host with public IP address):
1root@tokyo:~# cat /etc/frp/frps.toml
2bindPort = 8888
3vhostHTTPPort = 8088
4auth.method = "token"
5auth.token = "your_token"
Frpc client example (running on Raspberry Pi):
1mephisto@raspberrypi:~ $ cat /etc/frp/frpc.toml
2serverAddr = "your_vps_server_public_ip"
3serverPort = 8888
4auth.method = "token"
5auth.token = "your_token"
6[[proxies]]
7name = "navidrome"
8type = "http"
9localIP = "127.0.0.1"
10localPort = 4533
11customDomains = ["navidrome.xxx.com"]
I'm accessing it via a domain name here, https://navidrome.xxx.com is the address Amperfy uses. You can also use just a public IP address, since a domain name is easier to remember, and IP addresses change.
vhostHTTPPort = 8088 is for Caddy:
1navidrome.xxx.com {
2
3reverse_proxy localhost:8088
4
5}
This way, you don't need to fill in the port number on the client, making it faster and more convenient.
If you don't have a domain name, you can also use the public IP address:port method.
6. In Conclusion
This budget-friendly streaming music service offers a degree of flexibility, allowing you to listen to music anytime, anywhere with internet access. If you're only listening at home, there are virtually no costs (no domain name, public IP address, etc.), just a little time to organize your music.
Also, I downloaded the music to my computer, synced it to my Raspberry Pi using rsync, and connected my computer to a monitor for convenient operation.
Remember, when enabling public internet access, always be mindful of network security. Be aware of what you're doing, set strong passwords for Navidrome, and avoid storing important data on the Raspberry Pi—what if there are vulnerabilities? Adding protection to the Caddy layer is also an option, but I haven't tested whether Amperfy can still connect properly after adding protection; for now, that's it.
Copyright statement:
- All content that is not sourced is original., please do not reprint without authorization (because the typesetting is often disordered after reprinting, the content is uncontrollable, and cannot be continuously updated, etc.);
- For non-profit purposes, to deduce any content of this blog, please give the relevant webpage address of this site in the form of 'source of original text' or 'reference link' (for the convenience of readers).
See Also:
- Listen to offline music on your phone
- MangoHud Performance Monitoring
- Solution to the problem of screen recording failure under independent window manager
- How to Smoothly Connect to Bluetooth Devices in Arch Linux
- Manage Configuration Files with Git and Ansible
- Arch Linux SSL VPN Client Configuration
- How to install and use the iNode client under Arch linux
- Raspberry Pi Running Distribution Agent
- Solve the problem that network configuration cannot be changed and saved under Linux
- labwc environment enables wlogout