Skip to content

Instantly share code, notes, and snippets.

@benrolfe
Last active July 10, 2018 21:40
iTunes have recently requested that podcast downloads accept "byte range requests". This PHP code below will set the correct headers and serve up the MP3 file. Set $file_path to the path of the MP3 file. See http://blog.unit6websites.com/post/48778214025/byte-range-requests
<?php
$fp = @fopen( $file_path, 'rb' );
$size = filesize( $file_path );
$length = $size;
$start = 0;
$end = $size - 1;
header( "Accept-Ranges: 0-$length" );
$c_start = $start;
$c_end = $end;
// Extract the range string
list(, $range) = explode( '=', $_SERVER['HTTP_RANGE'], 2 );
// If the range starts with an '-' we start from the beginning
// If not, we forward the file pointer
if ( $range{0} == '-' )
{
// The n-number of the last bytes is requested
$c_start = $size - substr($range, 1);
}
else
{
$range = explode( '-', $range );
$c_start = $range[0];
$c_end = ( ( isset( $range[1] ) && is_numeric( $range[1] ) ) ? $range[1] : $size );
};
// End bytes can not be larger than $end.
$c_end = ($c_end > $end) ? $end : $c_end;
$start = $c_start;
$end = $c_end;
$length = $end - $start + 1;
fseek( $fp, $start );
header( 'HTTP/1.1 206 Partial Content' );
header( "Content-Range: bytes $start-$end/$size" );
header( "Content-Length: $length" );
// Start buffered download
$buffer = 1024 * 8;
while ( ! feof( $fp ) && ( $p = ftell($fp) ) <= $end )
{
if ( $p + $buffer > $end )
{
$buffer = $end - $p + 1;
};
set_time_limit( 0 );
echo fread( $fp, $buffer );
flush();
};
fclose( $fp );
?>
@benbyford
Copy link

HELLO! Can't seem to get the partial content to work still, I'm using the below run on nginx.
`$file_path = $page->mp3->filename;

$fp = @fopen( $file_path, 'rb' );
$size = filesize( $file_path );
$length = $size;
$start = 0;
$end = $size - 1;

header("Content-type: audio/{$page->mp3->ext}");
header( "Accept-Ranges: 0-$length" );

// find request headers for partial content
if ( isset($_SERVER['HTTP_RANGE']) ) {
// if the HTTP_RANGE header is set we're dealing with partial content
$partialContent = true;
} else {
$partialContent = false;
}

// Extract the range string
list(, $range) = explode( '=', $_SERVER['HTTP_RANGE'], 2 );

if($range{0}){
$partialContent = true;
}

if ( $partialContent ) {

$c_start = $start;
$c_end   = $end;

// If the range starts with an '-' we start from the beginning
// If not, we forward the file pointer
if ( $range{0} == '-' )
{
	// The n-number of the last bytes is requested
	$c_start = $size - substr($range, 1);
}
else
{
	$range  = explode( '-', $range );
	$c_start = $range[0];
	$c_end   = ( ( isset( $range[1] ) && is_numeric( $range[1] ) ) ? $range[1] : $size );
};
// End bytes can not be larger than $end.
$c_end = ($c_end > $end) ? $end : $c_end;
$start  = $c_start;
$end    = $c_end;
$length = $end - $start + 1;

fseek( $fp, $start );

header( 'HTTP/1.1 206 Partial Content' );
header( "Content-Range: bytes $start-$end/$size" );
header( "Content-Length: $length" );

// Start buffered download
$buffer = 1024 * 8;
while ( ! feof( $fp ) && ( $p = ftell($fp) ) <= $end )
{
	if ( $p + $buffer > $end )
	{
		$buffer = $end - $p + 1;
	};

	set_time_limit( 0 );

	echo fread( $fp, $buffer );

	flush();
};

fclose( $fp );

}else{
// send file
}`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment