Make mp3 seekable PHP
I did this PHP script
$file_name = 'sample.mp3'; header('Content-Type: audio/mpeg'); $opts = array('http' => array( 'method' => 'GET', 'protocol_version' => 1.1, ) ); $context = stream_context_create($opts); $stream = fopen($file_name, 'rb', FALSE, $context); $metadata = stream_get_meta_data($stream); $data = stream_get_contents($stream); print($data); fclose($stream);
It could stream mp3 media successfully but I'm not able to seek the mp3 file that get played also in html5 video
tags are not able to extract metadata from it, please tell me where I'm doing wrong and how to make this process work, thanks
Solution 1:
Here try this, supports partial downloads and seeking for any filesize, also now correctly works in chrome:
<?php
$file_name = './sample.mp3';
stream($file_name, 'audio/mpeg');
/**
* Stream-able file handler
*
* @param String $file_location
* @param Header|String $content_type
* @return content
*/
function stream($file, $content_type = 'application/octet-stream') {
@error_reporting(0);
// Make sure the files exists, otherwise we are wasting our time
if (!file_exists($file)) {
header("HTTP/1.1 404 Not Found");
exit;
}
// Get file size
$filesize = sprintf("%u", filesize($file));
// Handle 'Range' header
if(isset($_SERVER['HTTP_RANGE'])){
$range = $_SERVER['HTTP_RANGE'];
}elseif($apache = apache_request_headers()){
$headers = array();
foreach ($apache as $header => $val){
$headers[strtolower($header)] = $val;
}
if(isset($headers['range'])){
$range = $headers['range'];
}
else $range = FALSE;
} else $range = FALSE;
//Is range
if($range){
$partial = true;
list($param, $range) = explode('=',$range);
// Bad request - range unit is not 'bytes'
if(strtolower(trim($param)) != 'bytes'){
header("HTTP/1.1 400 Invalid Request");
exit;
}
// Get range values
$range = explode(',',$range);
$range = explode('-',$range[0]);
// Deal with range values
if ($range[0] === ''){
$end = $filesize - 1;
$start = $end - intval($range[0]);
} else if ($range[1] === '') {
$start = intval($range[0]);
$end = $filesize - 1;
}else{
// Both numbers present, return specific range
$start = intval($range[0]);
$end = intval($range[1]);
if ($end >= $filesize || (!$start && (!$end || $end == ($filesize - 1)))) $partial = false; // Invalid range/whole file specified, return whole file
}
$length = $end - $start + 1;
}
// No range requested
else $partial = false;
// Send standard headers
header("Content-Type: $content_type");
header("Content-Length: " . ($partial ? $length : $filesize));
header('Accept-Ranges: bytes');
// send extra headers for range handling...
if ($partial) {
header('HTTP/1.1 206 Partial Content');
header("Content-Range: bytes $start-$end/$filesize");
if (!$fp = fopen($file, 'rb')) {
header("HTTP/1.1 500 Internal Server Error");
exit;
}
if ($start) fseek($fp,$start);
while($length){
set_time_limit(0);
$read = ($length > 8192) ? 8192 : $length;
$length -= $read;
print(fread($fp,$read));
}
fclose($fp);
}
//just send the whole file
else readfile($file);
exit;
}
?>