How to download an mp3 file from remote url? - php

I am redirecting my website to a url where only an mp3 file is streaming and I want that file to be downloaded to local computer.
how can i do that?
I have already searched google and stacksoverflow but the solutions didn't worked for me
I couldn't find solution for my specific problem.

Use CURL to download, then you can use file_get_contents to save file on server, or you can use some headers to force download the file.
$ch = curl_init('http://url-to-file.com/audio.mp3');
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_NOBODY, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
$output = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status == 200) {
file_put_contents(dirname(__FILE__) . '/audio.mp3', $output);
}
Download to browser:
$ch = curl_init('http://url-to-file.com/audio.mp3');
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_NOBODY, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
$output = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status == 200) {
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=audio.mp3");
echo $output;
die();
}

curl only works for small files.
For larger files you can download mp3, mp4, zip by doing the following:
file_put_contents(dirname(__FILE__) . '/recordings/audio.mp3', fopen('http://url-to-file.com/audio.mp3', 'r'))

There are two ways to do it.
First way is use function readfile - it will be faster, then all other methods.
function curl_get_file_size( $url ) {
$result = -1;
$curl = curl_init( $url );
curl_setopt( $curl, CURLOPT_NOBODY, true );curl_setopt( $curl, CURLOPT_HEADER, true );curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, true );
$data = curl_exec( $curl );
curl_close( $curl );
if( $data ) {
$content_length = "unknown";
$status = "unknown";
if( preg_match( "/^HTTP\/1\.[01] (\d\d\d)/", $data, $matches ) ) $status = (int)$matches[1];
if( preg_match( "/Content-Length: (\d+)/", $data, $matches ) ) $content_length = (int)$matches[1];
if( $status == 200 || ($status > 300 && $status <= 308) )
$result = $content_length;
}
return $result;
}
function run() {
global $url,$title;
header("Content-type: audio/mpeg");
header("Content-Disposition: attachment; filename=$title.mp3");
header("Content-length: " . curl_get_file_size($url));
header("accept-ranges: bytes");
readfile($url);
}
run();
Second way is when you download full file and then return it
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_NOBODY, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
$output = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status == 200) {
header("Content-type: audio/mpeg");
header("Content-Disposition: attachment; filename=$title.mp3");
header("Content-length: " . strlen($output));
header("accept-ranges: bytes");
echo $output;
die();
}

Related

The display of some images through the readfile does not work

I have this simple function that I use to display images on a website (due to mixed content) but it doesn't work for this particular one. How to view it?
Code:
<?php
$remoteImage = "http://data.rcm-pelikan.cz/products2/KAV0152&5/b_0_779bc.jpg";
$imginfo = getimagesize($remoteImage);
header("Content-type: ".$imginfo['mime']);
readfile($remoteImage);
Edit:
Solution:
$remoteImage = "http://data.rcm-pelikan.cz/products2/KAV0152&5/b_0_779bc.jpg";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $remoteImage);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$res = curl_exec($ch);
$rescode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
curl_close($ch) ;
header("Content-Type: $contentType");
echo $res;

PHP stream remote video file

Let's say I have a video on a remote server and this its url
"http://domain/video-path/video.mp4"
What is the correct way to stream this video using php with seekable..
I know how to stream the video using fopen and fread but it can't seek with remote file
I'm using this, working both local & external video, seekable & resumable
ini_set('max_execution_time', 0);
$useragent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36";
$v = $_GET['url'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 222222);
curl_setopt($ch, CURLOPT_URL, $v);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$info = curl_exec($ch);
$size2 = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
header("Content-Type: video/mp4");
$filesize = $size2;
$offset = 0;
$length = $filesize;
if (isset($_SERVER['HTTP_RANGE'])) {
$partialContent = "true";
preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches);
$offset = intval($matches[1]);
$length = $size2 - $offset - 1;
} else {
$partialContent = "false";
}
if ($partialContent == "true") {
header('HTTP/1.1 206 Partial Content');
header('Accept-Ranges: bytes');
header('Content-Range: bytes '.$offset.
'-'.($offset + $length).
'/'.$filesize);
header("Content-length: ".$length); // added
} else {
header('Accept-Ranges: bytes');
header("Content-length: ".$size2); // added
}
// header("Content-length: ".$size2); // removed
$ch = curl_init();
if (isset($_SERVER['HTTP_RANGE'])) {
// if the HTTP_RANGE header is set we're dealing with partial content
$partialContent = true;
// find the requested range
// this might be too simplistic, apparently the client can request
// multiple ranges, which can become pretty complex, so ignore it for now
preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches);
$offset = intval($matches[1]);
$length = $filesize - $offset - 1;
$headers = array(
'Range: bytes='.$offset.
'-'.($offset + $length).
''
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 222222);
curl_setopt($ch, CURLOPT_URL, $v);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
curl_setopt($ch, CURLOPT_NOBODY, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
curl_exec($ch);
After the other answers on this hadn't been working for me, I've finally found (after much tweaking) a new solution to this which is working for remote/local files.
<?php
$file = 'https://yourfilelocation';
$head = array_change_key_case(get_headers($file, TRUE));
$size = $head['content-length']; // because filesize() won't work remotely
header('Content-Type: video/mp4');
header('Accept-Ranges: bytes');
header('Content-Disposition: inline');
header('Content-Length:'.$size);
readfile($file);
exit;
?>
This allows tracking etc. too, enjoy!

download a file from PHP Curl

I have this code in my curl:
$data_string = json_encode($data);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json; charset=utf-8',
'User-Agent: '.$_SERVER['HTTP_USER_AGENT'],
'X-Forwarded-For: '.$this->getIp()
));
$result = curl_exec($ch);
return $result;
I am getting this giberish result:
I am expecting an image file.
Question here is that how can i download this image file?
you can use this code
$profile_Image = $url; //image url
$userImage = 'myimg.jpg'; // renaming image
$path = ''; // your saving path
$ch = curl_init($profile_Image);
$fp = fopen($path . $userImage, 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
$result = curl_exec($ch);
curl_close($ch);
fclose($fp);
you can try this:
$data=send_curl($url);
$path='./test.jpg';
$file = file_put_contents($path,$data);
the function of send_curl
function send_curl($url, $data, $PROXY = "") {
$ch = curl_init ();
if ($PROXY != "") {
curl_setopt ( $ch, CURLOPT_PROXY, $PROXY );
}
curl_setopt ( $ch, CURLOPT_URL, $url );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt ( $ch, CURLOPT_POST, 1 );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $data );
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
$result = curl_exec ( $ch );
curl_close ( $ch );
return $result;
}
Ideally, browsers decide how to display a given piece of content using the information of the Content-Type HTTP header and PHP can generate HTTP headers with the header() function.
If you know for sure that your picture will always be in JPEG format it's rather straightforward:
header('Content-Type: image/jpeg');
echo your_download_function();
exit;
Otherwise, you need to fetch the header returned by the remote server. Curl has a tricky syntax—I refer you to PHP cURL retrieving response headers AND body in a single request?

Curl progress function in PHP

I am wondering why this download() function is not working.
function download($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, 'progress');
curl_setopt($ch, CURLOPT_NOPROGRESS, false);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
$html = curl_exec($ch);
curl_close($ch);
function progress($resource, $download_size, $downloaded, $upload_size, $uploaded)
{
if ($download_size > 0)
$progress = round($downloaded / $download_size * 100);
$progress = array('progress' => $progress);
$path = "temp/";
$destination = $path."11.json";
$file = fopen($destination, "w+");
fwrite($file, json_encode($progress, JSON_UNESCAPED_UNICODE));
fclose($file);
}
}
download("http://stackoverflow.com");
But when I am using without function like
curl_setopt($ch, CURLOPT_URL, "http://stackoverflow.com");
or when I am using the function twice like
download("http://stackoverflow.com");
download("http://stackoverflow.com");
it works. Otherwise it doesn't create any json file.
Declare your function progress outside of download:
function download($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, 'progress');
curl_setopt($ch, CURLOPT_NOPROGRESS, false);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
$html = curl_exec($ch);
curl_close($ch);
}
function progress($resource, $download_size, $downloaded, $upload_size, $uploaded)
{
if ($download_size > 0)
$progress = round($downloaded / $download_size * 100);
$progress = array('progress' => $progress);
$path = "temp/";
$destination = $path."11.json";
$file = fopen($destination, "w+");
fwrite($file, json_encode($progress, JSON_UNESCAPED_UNICODE));
fclose($file);
}

php fopen fread images

I am trying to tcp an image from my linux php ec2 instance to another server.
when i echo out the contents of fopen and fread i can see the image is processed but only halfway
Does anyonew know what is causing this please, thank you.
$imageURL = 'http://ec2-**-***-**-**.compute-1.amazonaws.com/New_Era_For_NASA_2.jpg';
$ch = curl_init($imageURL);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$data = curl_exec($ch);
//echo $data;
curl_close($ch);
if ($data === false) {
die('cURL failed');
}
if ( preg_match('/Content-length: (\d+)/', $data, $matches) || preg_match('/Content-Length: (\d+)/', $data, $matches) ) {
$size = (int)$matches[1];
}
$fileHandle = fopen($imageURL, 'rb'); //r or rb
$fileData = fread( $fileHandle, $size );
//echo $fileData;
fclose( $fileHandle );
$data = $fileData;
header('Content-type: image/jpeg');
echo $data;
Why fetch it twice? Curl could do the job in one step. i.e.
$imageURL = 'http://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Tibia_insulaechorab_transparent.png/320px-Tibia_insulaechorab_transparent.png';
$ch = curl_init($imageURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$data = curl_exec($ch);
curl_close($ch);
if ($data === false) {
die('cURL failed');
}
header('Content-Type: image/png');
header('Content-Length: ' . curl_getinfo( $ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD ) );
echo $data;
$imageURL = 'http://ec2-**-***-**-**.compute-1.amazonaws.com/New_Era_For_NASA_2.jpg';
$ch = curl_init($imageURL);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$data = curl_exec($ch);
echo $data;
curl_close($ch);
Would be enough
file_get_content( $imageURL );
Would work to0 but be aware of memory_limit, fread might be a better option.

Categories