Using php to opening live audio stream on android

2019-01-24 21:51发布

问题:

We have shoutcast/icecast audio streams. I'd like to be able to provide a link such as mobiledroid.php on our web site that will open using default player. I've seen this done on another site so I do know it's possible.

I assume it uses php headers and streams via the php file as a stream?


Using Brad's instructions, the android actually gives the option to open with sound player. Nice one.

It also plays on WMP through PC but not on the android how the above link plays

header("Content-type: audio/mpeg"); 
header("Transfer-Encoding: chunked"); 
header("Connection: close");

$sock = fsockopen($streamname,$port); //$streamname is the IP

fputs($sock, "GET $path HTTP/1.0\r\n"); //path in my case is /;stream.mp3
fputs($sock, "Host: $ip\r\n"); 
fputs($sock, "User-Agent: WinampMPEG/2.8\r\n"); 
fputs($sock, "Accept: */*\r\n"); 
fputs($sock, "Icy-MetaData:1\r\n"); 
fputs($sock, "Connection: close\r\n\r\n"); 


fpassthru($sock); 

fclose($sock);

On the android, it says "Sorry, this player does not support this type of audio file"


Update 2:

Removing "Transfer-Encoding" will play on android but as usual will take a long time to begin stream with "Preparing" status due to a live stream not having "Content-Length"

header("Transfer-Encoding: none"); also removed from above code:

Quoting Brad:

Android 2.3 and later has an issue with Transfer-Encoding set to "none". Removing that hard-set header puts the stream back to chunked Transfer-Encoding. This works great for Android 2.3+. Originally I had disabled chunked encoding as VLC doesn't support it. It also seems that Android 2.2 and older does not support chunked encoding.

Noting here that although it works on android, most live streams will take an awful amount of time to begin.

回答1:

Problem

Traditionally, you would serve a playlist file which would be saved by your browser, and then opened in whatever player software was configured to open such playlists. The player would then read the URL of the stream, connect to it, and begin streaming.

On Android, they (for some crazy reason) chose not to support playlist files as supported media. Because of this, there is no direct way to launch the player using the traditional method.

Solution

On Android it seems that if you link directly to an MP3 file/stream, instead of downloading the file the default action is to open up a media player and try to stream it. This means that you can easily link directly to the URL of your stream (bypassing the playlist step entirely).

There is a catch... streams served with SHOUTcast aren't exactly HTTP compliant. They are close, but not perfect. The real hangup here seems to be one of content length. Typically, HTTP servers send a Content-Length response header. With streaming media, the length is unknown. There are two ways around the problem:

  1. Use chunked transfer encoding. You can do this by setting the following headers:
    Transfer-Encoding: chunked
    Then, use chunked encoding for the stream, and you're good to go.
  2. Use no transfer encoding, and specify that the connection will be closed when the resource is finished transferring, with these headers:
    Transfer-Encoding: none
    Connection: close

Your example link uses method one. I'm using method two successfully as well.

Once your server is talking valid HTTP, playback on Android seems to be a breeze.

Implementation

There are a handful of ways to go about implementing this fix. You have mentioned a PHP solution. If cURL won't work, you can always fsockopen() or stream_socket_client() to make a direct TCP connection, and handle the incoming stream data yourself. From there, you simply need to send the correct response headers and relay the data as it comes in. Keep in mind that a PHP instance will be running for each connected client, and each instance will make a connection to your server as well. This isn't ideal, but depending on what you have available, might be the only method for you.