1
votes

I'm looking to convert a youtube video to mp3 and download it directly to visitor's / user's computer.

The conversion and downloading to the server is pretty easy using a command like that:

youtube-dl --extract-audio --audio-format mp3 [video]

I'm wondering what would be the fastest option to get that mp3 file to the user's computer using php.

2

2 Answers

0
votes
  1. Download the song (and convert it to mp3) to the server (into an accessible folder) but set the output files name to the identifier from youtube (https://youtube.com/watch?=IDENTIFIER). This way, it won't download the same file twice, when somebody else wants the same one. In PHP you can get it similarly to this:

    $link = $_GET['link']; // This is the Youtube link
    $id = str_replace("https://youtube.com/watch?=", ""); // This will remove the youtube link itself
    
  2. When downloaded, just print out the link to the file.

  3. If you want to save bandwidth, then check if a file with the same identifier already exists. If it does, then just give the user the existing one.

Hope this helps. =)

0
votes

I'm doing about the same thing for one of my websites, I use the following function to download & convert the video to mp3. It takes the video link as a param and returns the downloaded file location. It also checks if the file is already downloaded and returns its location if yes.

function downloadMP3($videolink){
    parse_str( parse_url( $videolink, PHP_URL_QUERY ), $parms );
    $id = $parms['v'];
    $output = "download/".$id.".mp3";
    if (file_exists($output)) {
        return $output;
    }else {
        $descriptorspec = array(
            0 => array(
                "pipe",
                "r"
            ) , // stdin
            1 => array(
                "pipe",
                "w"
            ) , // stdout
            2 => array(
                "pipe",
                "w"
            ) , // stderr
        );
        $cmd = 'youtube-dl --extract-audio --audio-quality 0 --audio-format mp3 --output download/"'.$id.'.%(ext)s" '.$videolink;
        $process = proc_open($cmd, $descriptorspec, $pipes);
        $errors = stream_get_contents($pipes[2]);
        fclose($pipes[2]);
        $ret = proc_close($process);
        if ($errors) {
            //print($errors);
        }
        return $output;
    }
}

Now whenever the user tries to download a file, I simply get the link from $link = $_GET['link'] pass it to the function and use the following code to serve the file :

$downloadpath = downloadMP3($videolink);
$song_name = "song";
header('X-Accel-Redirect: /' . $downloadpath);
header("Content-Type: audio/mpeg, audio/x-mpeg, audio/x-mpeg-3, audio/mpeg3");
header('Content-length: ' . filesize($_SERVER["DOCUMENT_ROOT"]."/".$downloadpath));
header('Content-Disposition: attachment; filename="'.$song_name.'.mp3"');
header('X-Pad: avoid browser bug');
header('Cache-Control: no-cache');

I highly recommend using the X-Accel-Redirect header for Nginx or x-sendfile for Apache to serve the file.