1

I need to somehow restream the Shoutcast/Icecast stream using the PHP.

Why?

Because Shoutcast/Icecast streams are non https. And it's sent through not 80 and 443 port, but some different strange ports. And I need the https links on normal/standard ports like 80 or 443. This is the biggest reason, although there are some more but less important I think.

These links are like http://hostname.com:5921/stream, and I need links like https://hostname.com/stream?user=x instead.

I made deep research and did not found much.

I found things like:

https://stackoverflow.com/questions/7998773/is-it-possible-to-restream-an-internet-radio-using-php-php-guru-needed
https://www.svnlabs.com/blogs/radio-icecast-shoutcast-php-proxy-to-re-stream-radio-stream-on-https/
https://stackoverflow.com/questions/36306457/read-mp3-stream-and-echo-back-to-client-in-php

The best code I have collected for now from all resources and my own tries is:

$link = 'http://shoutStreame.streamland.com/proxy/radioGame?mp=/1'; //example link to a Shoutcast stream (not working, only example)

ob_start();
header("Content-Transfer-Encoding: binary");
header("Content-Type: audio/mpeg, audio/x-mpeg, audio/x-mpeg-3, audio/mpeg3");
header('Content-Disposition: attachment; filename="stream.mp3"');
header('X-Pad: avoid browser bug');
header('Cache-Control: no-cache');
$handle = fopen($link, 'r');

while (($data = fread($handle, 1024))) {
    echo $data;
    ob_flush();
    flush();
}

And this code doesn't seems to be... good? excellent?

I just feel like I am doing it wrong way with this code, and it's not efficent and may lead to problems.

My main concerns are:

  • efficency, especially under many requests
  • legal problems? are there any real problems when doing things this way? restreaming using php?
  • crash problems? like crash of the whole php, nginx or even machine?
  • losing the connection, like this php script will keep dying after a while or something

And there could be maybe more.

It is really hard for me to find any more resources, data and information regarding this particular topic of restreaming the audio stream using the PHP.

For now I do not really know what to do. I am just researching and thinking but as I said, it is really hard to find something more about this topic. And this is the only code I have for now and I do not know if it is good to use it... :)

Brad
  • 159,648
  • 54
  • 349
  • 530
  • Have any of these concerns been proven by testing, or are they just theoretical worries? P.S. Most if not all of us are probably not qualified to advise you on the legal aspect – ADyson Jan 14 '20 at 15:45
  • @ADyson there are just my own theoretical worries and feelings – Krystian Walicki Jan 14 '20 at 15:47
  • P.S. In the question you mention you needed this code because the streams you want to access are non-HTTP and served over ports which are not the standard HTTP/HTTPS ones (I assume you want to stream through a corporate firewall or something). Yet in the example code, you seem to be getting the data from a HTTP URL...so it's a little unclear what the issue is, to be honest. Are there other links you'll be wanting to download from which are not HTTP-based? If so it might make sense to demo those instead. – ADyson Jan 14 '20 at 15:54
  • Regarding the worries, you really need to do some concrete load testing to see how it behaves under heavier use, to see if any of these concerns are likely to be real. We know nothing about the deployed server environment or expected usage levels, or the capacity of the sites you're streaming from, nor the capacity of the network connection between these sites and yours, so it's hard to predict much. – ADyson Jan 14 '20 at 15:57
  • @ADyson These shoutcast/icecast links are like: http://hostname.com:5921/stream and as u can see port 5921 + not https. I need to have links more like: https://hostname.com/stream?user=x – Krystian Walicki Jan 14 '20 at 16:04
  • yes I can see from those links they're not HTTP, but that's not what you're using in your code - in your code the example link is clearly HTTP-based. So are you saying you need to support different types of protocol? – ADyson Jan 14 '20 at 21:52
  • @ADyson Yes, because I get the http stream, but this script/my page is server in https. So I restream a http stream from my https endpoint – Krystian Walicki Jan 15 '20 at 17:17
  • yeah ok but then why not just load the http stream directly in your client? That was my point. Why re-stream something which is already http. – ADyson Jan 15 '20 at 17:34
  • @ADyson loading from http creates Mixed content + one other specific input in my system needs link on standard port, like normal www link – Krystian Walicki Jan 15 '20 at 17:52

1 Answers1

3

Because Shoutcast/Icecast streams are non https.

False! Icecast supports HTTPS just fine. See the <ssl-certificate> tag in the config file. http://www.icecast.org/docs/icecast-2.4.1/config-file.html

And it's sent through not 80 and 443 port, but some different strange ports.

Also false! Both SHOUTcast and Icecast can be configured to run on whatever port you desire. Most stations use standard ports, and you can as well.

These links are like http://hostname.com:5921/stream, and I need links like https://hostname.com/stream?user=x instead.

Why do you need to do this? Probably the easiest thing to do is redirect to the stream URL from your script at /stream. That will meet most needs.

All of your technical concerns are valid. I would definitely not recommend relaying a stream via PHP. With what you're doing, you're causing an upstream connection to be made every time, and for really no benefit. Additionally, there are some client compatibility hacks in place in Icecast that you lose if you proxy the connection.

Brad
  • 159,648
  • 54
  • 349
  • 530
  • False! Icecast supports HTTPS just fine. -but its about shoutcast too, both of them Also false! Both SHOUTcast and Icecast can be configured to run on whatever port you desire. -I do not know if it is possible to handle with about 1000+ stations – Krystian Walicki Jan 15 '20 at 17:19
  • Why do you need to do this? Probably the easiest thing to do is redirect to the stream URL from your script at /stream. That will meet most needs. -I do not think it will do the work, because it is just redirection, and the final link behind the redirect is like `http://hostname.com:5921/stream`. – Krystian Walicki Jan 15 '20 at 17:21
  • @KrystianWalicki Why can you not use Icecast exclusively? Why can't you configure your servers to use the ports you want? And why doesn't redirection work for you? Can you elaborate more on your specific use case? – Brad Jan 15 '20 at 17:40
  • 1.I have users, many users, a lot of them. And some of them use Icecast and some Shoutcast. 2.These are on panels like centovacast and everestcast, and each account has its own specific ports to their icecast/shoutcast servers, links to stream with different and strange ports. And I need normal https links to these streams and on normal ports. 3.Redirection just redirect, final link behind redirection is still on strange port and without https – Krystian Walicki Jan 15 '20 at 17:55
  • These panels serve proxy links too (on normal ports, more like www looking links) - do not really know how, but they have proxy links like I wanna create. But without the https. – Krystian Walicki Jan 15 '20 at 17:59
  • Oh! I think I understand now... you are not in control of the servers and streams. Yes, you'll have to proxy the requests in this case. You can either do it by explicitly configuring Icecast, or you can write your own system. In the past, I've written my own Node.js servers for this. There's a lot more to it than the scope of a single Stack Overflow question. If you're interested in licensing this project, please contact me at brad@audiopump.co. – Brad Jan 15 '20 at 18:05
  • But I have Shoutcast too. Icecast + Shoutcast. So do you think my PHP code in this question is ok? And using php in general to this problem is ok? And is this code not enough? Its a lot more code to write for it to work good? – Krystian Walicki Jan 15 '20 at 18:13
  • @KrystianWalicki Definitely the code you have in place is going to be problematic. For starters, almost all of the headers are incorrect. The reading buffer should be larger. If you were going this route, you could simply configure your web server to handle the proxying, rather than hitting the application layer. I'm not saying that you couldn't do it in PHP, but it's certainly not the tool I'd reach for in this case. – Brad Jan 15 '20 at 18:16
  • But I guess it is not only the problems of headers and small buffer right? I just do not really know what to add to this code to be a good code for this problem and do not know how much work there is left when doing it in php this way – Krystian Walicki Jan 15 '20 at 18:54
  • You need to handle the ICY metadata. You need to add an `X-Forwarded-For` on the request. You'll need to configure PHP to allow this script to run indefinitely. You need to add code to bail if the downstream buffers get too large (slow clients). Probably some other things as well. – Brad Jan 15 '20 at 18:56
  • I see. But even then, after all this adds and changes to the code... it won't be good? especially under load about 10k-100k requests at minimum I think – Krystian Walicki Jan 15 '20 at 22:07
  • No. Icecast supports SSL ONLY under LINUX (till version 2.4.4) They say PROBABLY from version 2.5.0 it will be also under Windows. – Tormy Van Cool Nov 12 '20 at 09:27
  • @TormyVanCool No, that's outright wrong. I have several instances of Icecast running with SSL on Windows. – Brad Nov 12 '20 at 19:11
  • @Krystian Walicki Icecast under Windows doesn't support the SSL. It's what they are saying. It will be implemented (they say) from 2.5.0 Which is the version I'm watiing for. – Tormy Van Cool Nov 18 '20 at 11:14
  • @Brad Icecast team itself declared that the 2.4.4 doesn't support yet the SSL under windows. Thus if you got something else: posts here the settings please and make use able to replicate this. Or, unfortunately, it has not any meaning. If you compile with it: it works but I'm talking about: just using the package they offer pre-compiled. As it is. If you use it behind proxy: it does. But's the Proxy that uses SSL not Icecast itself P.S. it will really great,because it is what I'm waiting for on Icecast ;-) – Tormy Van Cool Nov 18 '20 at 11:23
  • @TormyVanCool 2.4.4 is the version I'm running, and I downloaded it from https://ftp.osuosl.org/pub/xiph/releases/icecast/icecast_win32_2.4.4.exe. I don't know what else to tell you. – Brad Nov 18 '20 at 19:13
  • @Brad which is not the official site (perhaps recompiled with SSL support?), however. Here the one I'm referring to, and for which, the only one reference about Windows SSL implementation I found, was on a dedicated forum. In 2019 it stated that the 2.44 doesn't support SSL. But it will have from 2.5.0 on. And I was looking for a solution, because my installation won't work under SSL. This is how I did discover it. http://downloads.xiph.org/releases/icecast/icecast_win32_2.4.4.exe – Tormy Van Cool Nov 22 '20 at 19:05
  • @TormyVanCool It *is* the official site. It's a mirror. If you don't believe me... hash them. CRC32 is `735CAF36`. – Brad Nov 22 '20 at 19:26