Add dummy streaming server to collect # of listeners from external source

Hello,

I’m using Live365.com to stream, and their Icecast2 instances do not accurately report the actual number of listeners as they feed the stream through an internal process and relay it to a different URL in order to replace ads.

I would like to implement a solution where I use a headless Chrome instance on my web server to log into my Live365.com admin panel, retrieve the actual number of listeners and provide that in a machine-readable format that e.g. mAirList could use to retrieve the number of listeners.

All I would need mAirList to do is read a file from a remote location and log the number of listeners contained in that file as if it had retrieved it from an actual Icecast/Shoutcast server. The file retrieved could be plain text and just contain an integer, or be provided in some other format, e.g. JSON (but plain text would probably do just fine).

If this is not an option, I would have to somehow implement the Icecast/Shoutcast protocols to set up some sort of fake server that reports the number of listeners, but the solution above would come with less overhead & be much more elegant.

Thanks for consideration :slight_smile:

Well it depends on where you want to display the number, within mAirlist.
If you require that number displayed within the Encoder, you need to run it as a fake stream server to feed the information.

If you could do the display with a seperated GUI object, you could read a plain text file with a script and push that update to this screen object.

I probably would prefere the 2nd option.

@shorty.xs Sorry, my intention is not to display that information anywhere. I need it logged in the database so that the log entries for each item played are correct. Right now the number of listeners reported from the actual Icecast instance is always “2”, no matter how many listeners are actually listening to the stream. That’s because Live365.com does not reveal the actual number of listeners via their Icecast instances, hence the need for mAirList to retrieve the number of listeners from a different source.

Than your only option is to replicate a dummy stream Server to serve this information.

Yes, I’m aware that this is not an existing feature, which is why I’ve requested it under “Feature Requests” :slight_smile:

In the Encoder section you can setup one only to count listeners from this special IP. :wink:

@UliNobbe Their Icecast server does not report the correct number of listeners… it always returns “2”. There’s no server to connect to in order to obtain the correct amount of listeners, neither while streaming to it nor while in “retrieve listener count” & “only count listeners” mode.

I know. I meant a separate encoder for your dummy server, only counting listeners.
The dummy server @shorty.xs proposed in #4.

@UliNobbe I’m aware of that option (see the first post in this thread, I mention that in the last paragraph), but it’s not very elegant and requires running a whole separate server (with security implications) to pretend to be Icecast or Shoutcast, implement a version of their protocol and report the number of listeners. Hence my feature request.

Actually that fake server would only need to implement that single endpoint of the Shoutcast or Icecast web API that returns the current listeners as XML. No big deal if you are already running a web server.

Thanks for responding, Torben.

That’s what I thought, too, which is why I tried that before I opened this topic. Since the protocol is more or less HTTP, I thought that shouldn’t be a big deal.

I first wanted to see what request mAirList sends when in “do not stream, just collect listeners” mode, so I set up a new sub domain to capture any and all requests made to it at the root level. I entered the host and selected port 80 as the port. I set up the vhost to redirect all requests & request methods (GET, POST, PUT etc.) and then waited for a bit while mAirList was playing in AUTO while “connected” to see what would happen.

Well, nothing did. I didn’t see a single connection, neither in the script nor in the access logs.

BASS simply reported a timeout when trying to connect.

One guess is that it resolves the host name to an IP before making a connection, without actually using the host name, thus never touching the vhost.
I have yet to try getting another IP to run a separate process just for this purpose and negating the need for a vhost. But it’s a bit excessive…

You were getting a BASS error? At which stage? It’s strange, because in “do not stream” mode, BASS isn’t even involved.

For the listener count retrieval, mAirList is doing an HTTP request to one

  • For Icecast: http://<ip>:<port>/admin/listclients?mount=<mountpoint> (with username “source” and password passed by HTTP Basic auth)
  • For Shoutcast http://<ip>:<port>/admin.cgi?pass=<password>&mode=viewxml

Then it tries to extract the listener count from the XML returned (for Icecast, it’s in <Listeners>...</Listeners>, and for Shoutcast it’s in <CURRENTLISTENERS>...</CURRENTLISTENERS>).

As long as your fake server returns some XML that looks similar to the original XML returned by Icecast/Shoutcast, it should just work.

Thanks, Torben.

Sorry, I thought it would be BASS reporting the error, and there was one in the system log, but not related to this experiment.

The message I’m getting is 3/2/2020 8:42:54 AM Warning Error fetching listener data for listen.***.com:80/dummy: Socket Error # 10060 Connection timed out.

… and it looks like the culprit is actually an odd DNS issue on the computer that mAirList is running on. I’ll try to resolve that and try again.

If all it takes is a simple GET request to the web server, this should indeed be a very easy fix for my problem.

Update @Torben: Works like a charm. Thank you.

The issue was that the user agent used for this request is blacklisted by one of the most popular rulesets for ModSecurity. After a few requests, the broadcasting computer’s IP address was banned and all following connections rejected, hence the timeout.

mAirList only expects the minimum of the XML tree to be present and then accepts the value submitted. I’m simply sending an XML header followed by:

<?xml version="1.0"?>
<icestats>
  <source mount="/dummy">
    <listeners>233</listeners>
  </source>
</icestats>

Now I’ll get to work on the most ridicolous part, a headless browser instance that logs into the site, requests the number of listeners, and writes that into a file for my fake Icecast server to find. I’ve opened a feature request with Live365 to enable some sort of API to let people get the number of listeners. Can’t believe that’s not a thing there yet…

Anyhow, thanks for your help with this. :slight_smile:

1 Like

Could you elaborate?

“indy library” is the user agent, and it’s blocked as “suspicious user agent” under rule # 330036 of the Atomicorp.com WAF ruleset. That’s a ruleset for the ModSecurity web application firewall, which is pre-installed on servers managed with Plesk or cPanel. The connection is rejected with code 403 & the source IP banned. The solution is to disable rule 330036 for the host in question & white-list the IP (or just remove it from the banned list).

If anyone else is looking for a way to get Live365 listener stats into mAirList, I’m happy to share the server-side code & mAirList settings. Just ping me. :slight_smile:

1 Like