Live audio stream valid HTTP resource - php

Shoutcast servers not generate valid HTTP resource. Our mobile player link (Android) requires a valid HTTP resource. How can i use php script for shoutcast stream? This script provide valid http resource? Any one knows?
<?php
$track = "shoutcaststream.mp3";
if (file_exists($track)) {
header("Content-Type: audio/mpeg");
header('Content-Length: ' . filesize($track));
header('Content-Disposition: inline; filename="shoutcaststream.mp3"');
header('X-Pad: avoid browser bug');
header('Cache-Control: no-cache');
readfile($track);
exit;
} else {
header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found', true, 404);
echo "no file";
}
Update 2
Everything now fine asper "Brad" instructions. We use set_time_limit(0) But still my stream closed after 3 mins to 5 mins? How to fix? Kindly help me.. :)

Yes, what you have is valid.
The invalid part about SHOUTcast streams is that they return ICY 200 OK instead of HTTP/1.0 200 OK in their responses. If you wish to change your script to proxy the SHOUTcast request, you will likely need to connect to your SHOUTcast server via a normal TCP connection (see fsockopen()), and send the raw request data.
Once you have a connection and are receiving data, echo this data out to your client.
Also note that you will want to call set_time_limit(0) so that your script doesn't time out in 30 seconds or so. Also make sure to not send a Content-Length header, and set your response to be HTTP/1.0 so that you don't have to send the data as chunked. (Chunked encoding playback only works on Android 2.3 or later.)
Finally, if you find that hacking something in place with PHP is too much of a hassle, I have a stream hosting service available for testing that does exactly what you are asking, which works fine for the built-in audio player on Android.

Related

How to execute a function after response send in PHP

I am trying to execute a callback function after response send in php.
For example in JAVA i made that using Threads. But in php after response it finish the process of script.Besides I try to implement pthreads but its too much complicated.
In my code:
if(isset($_REQUEST['x']) && $_REQUEST['x'] == "x") {
header('Content-type: application/json');
$data = json_decode(file_get_contents('php://input'), TRUE);
if (!empty($data)) {
$request = new XRequest($data['params']);
$customParams = unserialize(file_get_contents('customParams'));
$customParams->callCallback($request); //Calling from another PHP class
echo(json_encode(array('status' => 'OK')));
}
}
The request come from different server. I want to start first php echo response when response send i want to call $customParams->callCallback($request);
How can I do that? Any ideas?
In php i solved my problem using bottom code. But pay attention to fastcgi_finish_request . With out this my server can not stop the first response and start callback.
Thanks.
ob_start();
// Send your response.
echo json_encode(array('status' => 'ok')) ;
// Get the size of the output.
$size = ob_get_length();
// Disable compression (in case content length is compressed).
header("Content-Encoding: none");
header($_SERVER["SERVER_PROTOCOL"] . " 202 Accepted");
header("Status: 202 Accepted");
// Set the content length of the response.
header("Content-Length: {$size}");
// Close the connection.
header("Connection: close");
ignore_user_abort(true);
set_time_limit(0);
// Flush all output.
ob_end_flush();
ob_flush();
flush();
session_write_close();
fastcgi_finish_request();
// Do processing here
sleep(5);
callBackAfterResponse();
PHP's concurrency model is simple and based around the fact that multiple PHP scripts can be executed simultaneously by a Web server. So typically, the way you'd implement this is by
Placing the body of your callback function in its own, separate script; and
Invoking it from the parent script through an outgoing Web request (using cURL or similar).
That is, have the first PHP script request the second at a URL on (presumably) the same Web server, just as though a user had opened the two URLs sequentially in their Web browser. This way, the second script can continue to run after the first has completed its response and terminated.
More sophisticated approaches are possible, involving message queues or remote-procedure call mechanisms like XML-RPC and Apache Thrift, if the second PHP script is made to run separately and continuously in its own process. But I think this will be enough for what you're trying to do.

PHP response to HEAD request

I have a PHP script that serves portions of a PDF file by byte ranges.
If an HTTP HEAD request is received, it should send back headers (including the PDF file size) but not the actual file contents. I have tried this:
header('HTTP/1.1 200 OK');
header('Content-Type: application/pdf');
header('Accept-Ranges: bytes');
header('Content-Length: '.filesize($Pathname));
die;
The problem is that something (I assume the web server == LiteSpeed) replaces the Content-Length header with Content-Length: 0 - which defeats the whole purpose.
Can anyone suggest what I should be doing? Thanks
From w3c Hypertext Transfer Protocol -- HTTP/1.1:
When a Content-Length is given in a message where a message-body is
allowed, its field value MUST exactly match the number of OCTETs in
the message-body. HTTP/1.1 user agents MUST notify the user when an
invalid length is received and detected.
And:
The Content-Length entity-header field indicates the size of the
entity-body, in decimal number of OCTETs, sent to the recipient or, in
the case of the HEAD method, the size of the entity-body that would
have been sent had the request been a GET.
So, I suppose, your code will properly work if you send real HEAD request to your server.
It's the webserver job, not yours.
In my case I left everything to the Apache webserver and nothing changed in my php code except of how the requests is being parsed
For example things like
if($_SERVER['REQUEST_METHOD'] === "GET"){
//ok
}else{
//send 400 Bad Request
}
are changed to
if($_SERVER['REQUEST_METHOD'] === "GET" || $_SERVER['REQUEST_METHOD'] === "HEAD"){
//ok
}else{
//send 400 Bad Request
}
and Apache did all the heavy lifting (striped the response body).
(don't try to ob_clean() or die("") or things like this).
related resources:
http://hc.apache.org/httpclient-3.x/methods/head.html
https://security.stackexchange.com/questions/62811/should-i-disable-http-head-requests
Apache 2.2.2 response on HEAD requests
As Lurii mentioned, the content length is affected by your request type.
With GET requests, a non-matching content length may result in a hanging client, so LiteSpeed will verify the content length before sending the header to the client.
Using a HEAD request should return the content length as expected.

Redirecting MP3 requests to Libsyn without iTunes' "byte-range" error?

I use Libsyn for several podcasts, and this is a new issue that I've never had before. I publish my own RSS feed, and redirect the audio file requests through my own server so I can do my own logging. iTunes is rejecting my submission of the feed with the message "There is a problem with your feed. Your episode are hosted on a server which doesn't support byte-range requests. Enable byte-range requests and try your submission again."
Obviously, Libsyn DOES support byte-range requests, so the problem appears to be in the way I'm redirecting the requests. This is what has always worked on my existing podcasts:
$id = 12345; // (the episode number)
$url = 'http://traffic.libsyn.com/myshow/myfile-'.$id.'.mp3';
header("Location: $url");
So I've tried adding some headers to convince iTunes that I actually do support byte-range requests. I've tried just about every combination of these that I can think of:
$id = 12345; // (the episode number)
$filesize = 12345678; // (the size of my file on Libsyn)
$url = 'http://traffic.libsyn.com/myshow/myfile-'.$id.'.mp3';
header('HTTP/1.1 206 Partial Content');
header('Content-Type: audio/x-mp3');
header('Accept-Ranges: bytes');
header("Content-Length: $filesize");
header("Location: $url");
I still get the error trying to submit the show to iTunes, and am out of ideas. Any suggestions?
You can't return make a single HTTP response be both a success (206) and a redirect (Location header, implying a 30x). You'll need to either serve the content yourself, or give up on logging.
I encourage the many others who have posted about this question to look for unrelated typos and something silly like my problem was. The error returned by iTunes does not necessarily mean what it says.

How to generate Chunked response with a Trailer in Apache/PHP?

I know I can generate chunked response in PHP simply by introducing a sleep() in the output.
But is it possible to also generate a Trailer HTTP section in PHP? If not, is it possible in general in Apache 2.2?
I need it for testing purposes.
PHP will send a chunked response by default if headers are sent and no Content-Length header was specified. If you're familiar with the HTTP spec, this is the only logical thing to do since the client on the other end needs to know when the HTTP message you're sending ends so it can stop reading.
If you want to do this manually, you need to ...
Send the appropriate headers yourself and call flush()
Manually output the chunked HTTP message
So you might do something like the following. The idea is that you need to manually send your own headers and manually chunk your own message. If you simply don't send a Content-Length header, however, PHP will send a chunked message for you by default.
header("Transfer-encoding: chunked");
header("Trailer: X-My-Trailer-Header");
flush();
echo dechex(strlen($myChunk)) . "\r\n";
echo $myChunk;
echo "\r\n";
flush();
echo "0\r\n";
flush();
echo "X-My-Trailer-Header: some-value\r\n";
flush();

How do I display a message after a file has been downloaded?

I have this PHP code and it works fine.
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="WTBak.zip"');
readfile($ArchiveFileName);
echo $ArchiveFileName;
unlink($ArchiveFileName);
My issue is, how do I give out a message after the last line (unlink) has been executed?
Thanks!
Assumptions:
The client user should receive a message, this is kind of message sent to the client
The response is binary
Abstract:
sending binary information to the client along with text response would be possible if it is mhtml format, used in mails and each browser has (some do nto have) the support for multipart response. Let us not chose this way
sending binary information to respond one request (download file) and another response to another request (status of download) - this is a popular practice.
Solution:
on server: persist the status of download
// pseudocode: log_download_event(seessionid, status='started')
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="WTBak.zip"');
readfile($ArchiveFileName);
echo $ArchiveFileName;
unlink($ArchiveFileName);
// pseudocode: log_download_event(seessionid, status='done')
on server: implement a php that will respond with a status of download
// pseudocode: $DownloadStatus=get_download_status(sessionid)
echo '{staus:' + $DownloadStatus + '}'
on client: on some event trigger the download
window.open("http://nowhere.com/download.php?resuorce=archive-file.zip");
window.theTrackInterval = window.setInterval(trackDownload, 1000);
var trackInterval = function(){
$.get('ajax/test.html', function(data) {
id(data.status=='ready'){
cleanInterval(window.theTrackInterval);
alert('download is done');
}
});
}
This solution will start sending the ajax requests to the server every one second asking "is download done" and when it will receive confirmation "yest it is done" client will stop tracking and alert a message
What is missed:
the implementation of status persistence. i am not PHP guy - forgive me this gap
Look, if you give a message, it will be sent in the file and not shown to the user corrupting / changing the contents of the file. You cannot modify the headers as they've already been sent!
So, I feel, there is now way!
Cheers
I had a similar requirement from client. So I created a tool to show message after a file gets downloaded.
You can see at http://www.iamkumaran.com/xdownloader-a-flash-javascript-library/ and look for demo link.

Categories