Well, it stopped working again. Never worked very well anyways. Now it needs to be restarted more then once a day, or maybe it always did. Could be as often as 30 minutes now. No idea.
I do know, rtl_fm wasn’t working, because it was using the library that instaleld with rtl_fm_streamer, which was in /usr/local/lib.
I just deleted that entire folder, because that’s all that was in there, the crap for the broken rtl_fm_streamer. Perhaps recompiling it would fix it. But I’m not going to recompile it every time I update or it stops working as “good”.
So I made a Python script, it only does stereo, as I have no idea why you’d want just mono. Or the option for mono. Now, you can modify the the command(s) so it only does mono if you want.
Since I made it for myself, I’m not doing much else to it. Not tested much yet, so how well it works, I have no idea. But I can go to bed early tonight if I want.
Oh yeah, I need to make a systemd service file for it.
I just tested to make sure the audio actually plays still, and it does, so I assume it mostly works. Now will it crap out after a while? Perhaps, unless I somehow did it right, so it doesn’t just feel the RAM up.
You could make rtl_fm and/or sox save to a file, and stream that. That could use a lot of disk space though, depending on how long you stream it.
#!/usr/bin/env python3
import tornado.web
import tornado.httpserver
import tornado.ioloop
import asyncio
import os
import signal
class Runner():
def __init__(self, name, cmd):
read1, write1 = os.pipe()
self.name = name
self.reader = read1
self.writer = write1
self.cmd = cmd
self.cmd_run = None
class catch_all(tornado.web.RequestHandler):
def initialize(self):
self.ioloop = tornado.ioloop.IOLoop.current()
self.stop_event = asyncio.Event()
self.soxer_runit = None
self.rtlfm_runit = None
def on_connection_close(self):
print("disconnected")
if self.soxer_runit.cmd_run.returncode is None:
self.stop_event.set()
self.soxer_runit.cmd_run.terminate()
if self.rtlfm_runit.cmd_run.returncode is None:
self.rtlfm_runit.cmd_run.terminate()
async def get(self):
self.HZ = self.request.uri.replace("/","")
await self.rtlfm_runner()
async def rtlfm_runner(self):
cmd = '/usr/bin/rtl_fm -d 1 -p 55.153 -g35 -f ' + self.HZ + ' -M fm -l 0 -A std -p 0 -s 192k'
self.rtlfm_runit = Runner("rtlfm", cmd)
await self.run(self.rtlfm_runit)
await self.soxer_runner(self.rtlfm_runit)
async def soxer_runner(self, output):
while not self.stop_event.is_set():
if self.soxer_runit is None:
cmd = '/usr/bin/sox -t raw -r 192k -b 16 -es -c 1 - -t flac -c 2 -'
self.soxer_runit = Runner("soxer", cmd)
await self.run(self.soxer_runit, output.reader)
print("soxer made")
if self.soxer_runit:
stdout = await self.soxer_runit.cmd_run.stdout.readline()
if stdout:
self.write(stdout)
self.flush()
async def run(self, runner_it, readit=False):
if not readit:
runner_it.cmd_run = await asyncio.create_subprocess_shell("exec " + runner_it.cmd, stdout=runner_it.writer, stdin=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT)
else:
runner_it.cmd_run = await asyncio.create_subprocess_shell("exec " + runner_it.cmd, stdout=asyncio.subprocess.PIPE, stdin=readit, stderr=asyncio.subprocess.STDOUT)
return runner_it.cmd_run
async def main():
app = tornado.web.Application(
[
(r'/\d{8,}\Z', catch_all),
],
debug=True,
)
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(8001, address='xxxxx')
await asyncio.Event().wait()
if __name__ == "__main__":
loop = asyncio.new_event_loop()
try:
loop.run_until_complete(main())
except KeyboardInterrupt:
print("Received exit, exiting")
You obviously need to change the address to your IP. Maybe change the port as well.
Also, if you can’t write any Python scripts yourself, you probably shouldn’t bother using it. There’s a good chance it has some kind of issues. Took a long ass time to get it working right, you can blame search engines for that, and me for not knowing shit about async.
Probably doesn’t need to use Tornado, but I didn’t want to rewrite it again. Started out with Flask or whatever it’s called, then found Tornado, and it seemed like the better one to use.
But you might be able to do it all with asyncio and no Tornado crap.
All you do to listen, is put in http://IP:8001/000000000 replace the “000000000” with the radio station in HZ.
There was some problem with just using one create_subprocess_shell process, using | in the command to pipe it to sox. Can’t remember anymore what the problem was.
Well, I know how to use my own pipes with create_subprocess_shell now, use os.pipe. I tried that without looking it up or finding the specific post, but it didn’t work. And using the subprocess.stdout didn’t work either.
And manually writing the stdout didn’t work either. If you print what it’s writing, you’d see some error or something. Using the os.pipe method is way easier.
Another benefit to making this, is now I know how to use classes, way less typing if you use a class for some stuff.
Does anyone really want to type var1, var2, var3, and so on? If you are running processes, and want to store variables, then it’s less typing/work to use a class,. They sort of have the same var name as well, you don’t actually call the same thing though, so not exactly. Just put the class in a variable, then to get something you use var_class.whatever.
You might want to change Debug to False as well, or maybe not, since it may have issues.
Works with Python 3.13.5. That’s another problem with writing a fucking Python script, you find very old info when searching, even for Python 2, that obviously isn’t going to work.
DuckDuckGo loves giving me old stuff. Sometimes when searching, I get an error message, or the site doesn’t even work or exist anymore. I guess search engines are too fucking lazy to remove broken links from their results, or they are intentionally doing it, because of the browser I’m using.
Not sure why they decided to make versions of Python very different. Maybe from 2 to 3, but I’m not sure every 3x version supports older 3x versions. A real pain in the ass.
I tried writing a bash script at first, but that didn’t look like a good solution, as the “server” would restart when going to the URL, then you’d have to go into VLC and open the URL again. Might be even more of a pain to detect when somebody disconnects, so it can stop the rtl_fm and sox process. I’m only one person, and don’t need those running when I’m not listening.
But if you have more then one tuner, and somebody else wants to listen to something else, you could probably easily modify it to do that too. Or maybe some people can listen to two things at once.
And recording with that script would be pointless, just make a bash script, and no HTTP. Unless you want a web interface, not sure I’d use Python for something with an actual web interface.
The only reason I want HTTP, is I’m too lazy to login using SSH and running the command, and don’t want rtl_fm + sox running 24/7. Also, if I decide to listen on say my phone, I really don’t want to run SSH to connect, typing on phones sucks.
No I don’t want icecast or whatever either, seems overkill for what I want.
Look how long that Python script is, not very long. I suppose the crap it’s using is probably way longer, the reason not using Tornado might be better.
You might need async of some kind, to make it work without restarting the HTTP server though. But if you want a smaller library, you may have to not use Python. Would it take a ton of code in Ruby to do? Too much work for me, I’ll only do that if it has major issues, and I don’t feel like fucking with Python anymore.
You could use something else entirely as well. That you need to compile. But I don’t want to ever have to recompile anything, so I’ll pass. I’d rather just fix the script if Python upgrades and it breaks.
But there’s a solution, don’t use the system Python. Just install an old Python for it, and the modules, and never update it.
It’s not accessible using the internet, and security doesn’t exist. If somebody wants to hack you, they’ll hack you.
Just watch the Pegasus scandal on PBS or whatever it was on.
And then, watch Skinwalker Ranch, and tell me that cracking Quantum resistance encryption isn’t possible.
Clearly, being born in the Amazon Rain Forest, would have been safer. Unless World War 3 happens, and nukes come falling down. Don’t forget global warming either.
In other words, a group of humans, or probably even one human, doing bad shit, means everybody will be affected. And the animals. Some animals in the deep ocean could survive maybe.
At this point, the internet isn’t really worth having or using. It could have been an awesome thing.
Thought the script was broken, when running with systemd, it was only killing the rtl_fm process, thought I fixed that. Just use Type=simple in the service file.
Also, slightly changed the script, added self.HZ = “” in the initialize, and just realized, you could probably put the actual value in it. Well too lazy to do that right now. Something I read said something about making sure you make the variable in the init, or maybe that only applies to classes. Cause it was working without it in initialize. And I just added that today as well. I had lots of self.vars, and no initialize, and the variables were most likely working.