• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 375
  • Last Modified:

force download for mp3 files

I have downloadedable files on my server for clients to download, however I dont want them played in the browser, I want the download prompt to happen

what do I have to do...  as of right now all I have is the actual link to the mp3 file
0
prowebinteractive
Asked:
prowebinteractive
  • 2
  • 2
  • 2
  • +2
2 Solutions
 
RoonaanCommented:
You have to write a download.php file which is called like downloadmp3.php?filemysoundfile.mp3

then have it like this:
<?php

  $mp3dir = 'mp3/';
 
  if(empty($_GET['file'])) exit('File not found');
 
  $file = basename($_GET['file']);
 
  if(!is_file($mp3dir.$file)) exit('File not found');
 
  header('Content-type:attachment;filename='.$file);
  readfile($mpd3dir.$file);
?>

-r-
0
 
prowebinteractiveAuthor Commented:
doesnt appear to work

I get this error:

mp3Complete/BlackcacoDaleconlacinturacomplete.mp3
Warning: Cannot modify header information - headers already sent by (output started at /home/bcadmin/public_html/newsite/myOrder.php:14) in /home/bcadmin/public_html/newsite/myOrder.php on line 19
0
 
duckaxCommented:
If you want to support download resuming as well as send the filesize to the user, you will need a few more lines of code.

I got this code off php.net with a little modification so that it supports IE
You pass the file using GET i.e. script.php?file=song.mp3
Modify $fpath to the directory where your mp3 is stored

<?php
$fname = $_GET['file'];
$fpath = "downloads/$fname";
$fsize = filesize($fpath);
$bufsize = 20000;

if(isset($_SERVER['HTTP_RANGE']))  //Partial download
{
   if(preg_match("/^bytes=(\\d+)-(\\d*)$/", $_SERVER['HTTP_RANGE'], $matches)) { //parsing Range header
       $from = $matches[1];
       $to = $matches[2];
       if(empty($to))
       {
           $to = $fsize - 1;  // -1  because end byte is included
                               //(From HTTP protocol:
// 'The last-byte-pos value gives the byte-offset of the last byte in the range; that is, the byte positions specified are inclusive')
       }
       $content_size = $to - $from + 1;

       header("HTTP/1.1 206 Partial Content");
       header('Cache-Control: public');
       header("Content-Range: $from-$to/$fsize");
       header("Content-Length: $content_size");
       header("Content-Type: application/force-download");
       header("Content-Disposition: attachment; filename=$fname");
       header("Content-Transfer-Encoding: binary");

       if(file_exists($fpath) && $fh = fopen($fpath, "rb"))
       {
           fseek($fh, $from);
           $cur_pos = ftell($fh);
           while($cur_pos !== FALSE && ftell($fh) + $bufsize < $to+1)
           {
               $buffer = fread($fh, $bufsize);
               print $buffer;
               $cur_pos = ftell($fh);
           }

           $buffer = fread($fh, $to+1 - $cur_pos);
           print $buffer;

           fclose($fh);
       }
       else
       {
           header("HTTP/1.1 404 Not Found");
           exit;
       }
   }
   else
   {
       header("HTTP/1.1 500 Internal Server Error");
       exit;
   }
}
else // Usual download
{
   header("HTTP/1.1 200 OK");
   header('Cache-Control: public');
   header("Content-Length: $fsize");
   header("Content-Type: application/force-download");
   header("Content-Disposition: attachment; filename=$fname");
   header("Content-Transfer-Encoding: binary");

   if(file_exists($fpath) && $fh = fopen($fpath, "rb")){
       while($buf = fread($fh, $bufsize))
           print $buf;
       fclose($fh);
   }
   else
   {
       header("HTTP/1.1 404 Not Found");
   }
}
?>
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
duckaxCommented:
You cannot include any other output at the beginning of the script. Remove any non-php, blank lines, print and echo statements
0
 
dimakhCommented:
Hi prowebinteractive,

I'm posting in reference with both of the above posts.
both solution may work with your problem.
please add following code at the start of page. so you wont get any warning messages saying "headers already sent by..." no matter if you are adding any other codes before sending out headers.


<?php
ob_start();
?>

Add above code at very start of your script (at 1st line itself) and your problem will be resolved.

please check this and let me know if you still any error message on this.

Thanks.
0
 
RoonaanCommented:
>doesnt appear to work

>I get this error:

>mp3Complete/BlackcacoDaleconlacinturacomplete.mp3
>Warning: Cannot modify header information - headers already sent by (output started at /home/bcadmin/public_html/newsite/myOrder.php:14) in >/home/bcadmin/public_html/newsite/myOrder.php on line 19

As mentioned. You should call the file on its own. Not embed it into html.

-r-
0
 
dimakhCommented:
Hi,

here is the complete code for forced download:
<?
      $url_path      = $music_full_song.$file_name;     // absolute path for the mp3 file
      
      header("Pragma: public"); // required
      header("Expires: 0");
      header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
      header("Cache-Control: private",false); // required for certain browsers
      header("Content-Type: application/force-download");
      // change, added quotes to allow spaces in filenames
      header("Content-Disposition: attachment; filename=\"".basename($file_name)."\";" );
      header("Content-Transfer-Encoding: binary");
      header("Content-Length: ".filesize($url_path));
      readfile("$url_path");
      exit();
?>

you should open this file in a new page/window .

Thanks.
0
 
LinkyCommented:
If you are going to use a script to force download MP3, make sure you do:

$filename = str_replace('/', '', $filename);
$filename = str_replace('..', '', $filename);

Before processing it. Because someone can easily type stuff like song.php?file=../../somefile.ext and possibly get files that contain password information or server info that you do not want them getting.

Just as a security measure.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 2
  • 2
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now