0

I am trying to play a radio station WETA FM from a systemd service. I think the problem is that the URL source goes through port 80 and therefore the radio doesn't play after reboot.

It plays fine with systemctl commands below, but not after reboot:

sudo systemctl daemon-reload
sudo systemctl enable weta_stream.service
sudo systemctl start weta_stream.service

Here is the basic command:

ffplay -hide_banner -loglevel error http://26283.live.streamtheworld.com:80/WETAFMAAC  -autoexit -nodisp

Here is my calling python script, works fine <streamweta.py>:

import os
import sys
cmdline = 'ffplay -hide_banner -loglevel error http://26283.live.streamtheworld.com:80/WETAFMAAC  -autoexit -nodisp'
os.system(cmdline)

Here is my <weta_stream.service>

[Unit]
Description=WETA Stream
Wants=network-online.target
After=network-online.target nss-lookup.target
After=multi-user.target

[Service]
ExecStart=/usr/bin/python3 /home/larry/pi/aetv/weta/streamweta.py
User=larry

[Install]
WantedBy=multi-user.target

What am I missing? I tried various things based on searches but none worked and all were related to a Pi web server listening to port 80 which is not applicable.

2
  • 1
    Please edit in the output from systemctl status weta_stream after a reboot and before you try to run it manually.
    – goldilocks
    Commented Sep 20, 2022 at 19:47
  • Thank you Goldilocks, that confirmed that tcp port 80 was not open yet and a delay to wait for port 80 on streamtheworld.com:80 to open before ExecStart is executed. I did this by adding an ExecStartPre= line to the service group that runs a bash script for the delay. Commented Sep 21, 2022 at 2:57

1 Answer 1

2

Thanks to Goldilocks I was able to track down the problem. Here is the resulting error that a status check revealed:

systemctl status weta_stream

    ● weta_stream.service - WETA Stream
     Loaded: loaded (/lib/systemd/system/weta_stream.service; enabled; vendor preset: enabled)
     Active: inactive (dead) since Tue 2022-09-20 22:47:12 EDT; 1min 30s ago
    Process: 740 ExecStart=/usr/bin/python3 /home/larry/pi/aetv/weta/streamweta.py (code=exited, status=0/SUCCESS)
   Main PID: 740 (code=exited, status=0/SUCCESS)
        CPU: 411ms

Sep 20 22:47:11 raspberrypi systemd[1]: Started WETA Stream.
Sep 20 22:47:12 raspberrypi python3[742]: [tcp @ 0xaa003a30] Failed to resolve hostname 26283.live.streamtheworld.com: Temporary failure in name resolution
Sep 20 22:47:12 raspberrypi python3[742]: http://26283.live.streamtheworld.com:80/WETAFMAAC: Input/output error
Sep 20 22:47:12 raspberrypi systemd[1]: weta_stream.service: Succeeded.

Result: [tcp @ 0xaa003a30] Failed to resolve hostname 26283.live.streamtheworld.com: Temporary failure in name resolution

This suggests that TCP port 80 was not open yet.

To solve the problem I added a pre-execution line to the [Service] group which worked! The bash script contains the server name and port from the python script's ffplay command -i http://26283.live.streamtheworld.com:80/WETAFMAAC

[Service]
ExecStartPre=/usr/bin/timeout 22 /usr/bin/bash -c 'until printf "" 2>>/dev/null >>/dev/tcp/$0/$1; do sleep 1; done' 26283.live.streamtheworld.com 80
ExecStart=/usr/bin/python3 /home/larry/pi/aetv/weta/streamweta.py
User=larry
5
  • Thank you for posting your solution. "This suggests that TCP port 80 was not open yet." -> To nitpick technically a bit, presuming streamtheworld.com does not refer to the local host, there is never a port 80 opened on your end (unless you are also running a web server, but this would be unrelated). Port 80 is the port the remote server is listening on. When an http client (web browser or in this case python script) connects to a remote http server, a random, high number (probably 5 digits) port is opened on your system and that is used to connect to port 80 on the remote host...
    – goldilocks
    Commented Sep 21, 2022 at 11:42
  • ...Port numbers need not and generally do not match client to host (client port numbers don't matter to anything). Anyway, what "failure in name resolution" means literally is that the system does not yet have access to a DNS server to resolve the name "streamtheworld.com" into an IP address. When networking starts up, a DHCP client on your machine negotiates with a DHCP server on your router. In addition to receiving your local IP address, you get the address of a remote DNS server or two (this may or may not be true in your case if you are making special use of NSS).
    – goldilocks
    Commented Sep 21, 2022 at 11:51
  • ...Before you can do anything online requiring a DNS lookup, this process needs to be completed. Of course, you have nss-lookup.service as a dependency; whether or not that includes DNS depends on the NSS configuration, but systemd dependency targets are on when a service starts, and what "starts" means depends on details of the service itself. Eg., networking targets are usually passed before you are fully online (as here), making it difficult to have a hard dependency on fully functioning, normative IP level networking.
    – goldilocks
    Commented Sep 21, 2022 at 11:51
  • Yes I fully agree and I should have clarified that when I provided ffplay with an audio URL from another server that I have personally not using a port specification the service ran fine with no DNS lookup issue. This is how I assumed the problem was likely a TCP port 80 issue, that combined with TCP being mentioned in the error message provided by systemctl status weta_stream command. Commented Sep 21, 2022 at 12:36
  • The bash script that polls port 80 on streamtheworld.com until the port is recognized and then breaks out of the loop works perfectly compared to my previous attempts trying to guess how many seconds to delay which would work sometimes but inconsistent. Commented Sep 21, 2022 at 12:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.