2013-06-28 12 views
5

Ich versuche, eine MP4-Datei herunterladen. (ca. 1,3 GB Größe). Ich verwende folgende: Force-Download, von PHP-Datei

<?php 
$path = "video.mp4"; 
header('Accept-Ranges: bytes'); // For download resume 
header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
header('Content-Description: File Transfer'); 
header('Content-Disposition: attachment; filename="'.basename($path).'"'); 
header('Content-Length: ' . filesize($path)); // File size 
header('Content-Transfer-Encoding: binary'); // For Gecko browsers mainly 
header('Content-Type: application/octet-stream'); 
header('Expires: 0'); 
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime($path)) . ' GMT'); 
header('Pragma: no-cache'); 
ob_clean(); 
flush(); 
readfile($path); 

ich meine PHP-Datei öffnen und Firefox öffnet sich mit dem „speichern möchten“ -Menü. Größe sieht richtig aus. Ich drücke Speichern unter auf meinem Desktop. Die zuletzt heruntergeladene Datei wird in einer zufälligen Größe von etwa 400 MB (330, 463 und 440) aufgelistet.

Antwort-Header sind:

Connection: Keep-Alive 
Content-Disposition: attachment; filename="//www.frederikspang.dk/elevgallavideo.mp4" 
Content-Length: 1422778850 
Content-Type: video/mp4 
Date: Sun, 30 Jun 2013 22:12:30 GMT 
Keep-Alive: timeout=10, max=50 
Pragma: public 
Server: Apache 
content-transfer-encoding: binary 
+1

Sie könnten ein Ausführungszeitlimit erreichen. Stoppt der Download immer nach der gleichen Zeit? –

+0

Wiederaufladbare Datei-Downloads benötigen viel mehr Code als das; Sie sollten also "Accept-Ranges" entfernen. Siehe: http://stackoverflow.com/questions/157318/resumable-downloads-when-using-php-to-send-the-file –

+0

Verwenden Sie tatsächlich die Pufferung von Ausgaben? Wenn nicht, brauchen Sie wahrscheinlich ob_clean() und flush() nicht, da der Befehl readfile die Daten direkt an den Client ausgibt. – dethtron5000

Antwort

0
<?php 
$filename = "theDownloadedFileIsCalledThis.mp4"; 
$myFile = "/absolute/path/to/my/file.mp4"; 

// Add bellow code for mime type 
$ext=strtolower(substr($fl,strrpos($myFile,"."))); 
$mime_types = array(
      '.txt' => 'text/plain', 
      '.htm' => 'text/html', 
      '.html' => 'text/html', 
      '.php' => 'text/html', 
      '.css' => 'text/css', 
      '.js' => 'application/javascript', 
      '.json' => 'application/json', 
      '.xml' => 'application/xml', 
      '.swf' => 'application/x-shockwave-flash', 
      '.flv' => 'video/x-flv', 

      // images 
      '.png' => 'image/png', 
      '.jpe' => 'image/jpeg', 
      '.jpeg' => 'image/jpeg', 
      '.jpg' => 'image/jpeg', 
      '.gif' => 'image/gif', 
      '.bmp' => 'image/bmp', 
      '.ico' => 'image/vnd.microsoft.icon', 
      '.tiff' => 'image/tiff', 
      '.tif' => 'image/tiff', 
      '.svg' => 'image/svg+xml', 
      '.svgz' => 'image/svg+xml', 

      // video 
      '.3gp' => 'video/3gpp', 
      '.3g2' => 'video/3g2', 
      '.avi' => 'video/avi', 
      '.mp4' => 'video/mp4', 
      '.asf' => 'video/asf', 
      '.mov' => 'video/quicktime', 
     ); 

if (array_key_exists($ext, $mime_types)){ 
    $mm_type=$mime_types[$ext]; 
}else{ 
    $mm_type="application/octet-stream"; 
} 
$mm_type="application/octet-stream"; 

header("Cache-Control: public, must-revalidate"); // Avoid this line 
header("Pragma: public"); // Add this line 
header("Pragma: hack"); // Avoid this line 
header("Content-Type: " . $mm_type); 
header("Content-Length: " .(string)(filesize($myFile))); // Avoid this line 
header('Content-Disposition: attachment; filename="'.$filename.'"'); 
header('Content-Length: ' . filesize($myFile)); // Add this line 
header("Content-Transfer-Encoding: binary\n"); 
ob_clean(); // Add this line 

readfile($myFile); 

?> 
+0

Sehr unklare Antwort. Es ist nicht gut dokumentiert. Bitte erläutern Sie "vermeiden" und "hinzufügen" und warum. –

+0

Referenz von Mime-Typen ist nützlich und Header-Deklarationen machen Sinn ... "Vermeiden" bedeutet offensichtlich "nicht verwenden" und "Hinzufügen" bedeutet "hinzufügen". Was er hätte tun können wäre eine bessere Erklärung, warum – zgr024

+0

Was ist mit all dem Mime-Typ Müll, wenn Sie nur $ mm_type = "application/octet-stream" setzen sowieso? –

1

, das ist schwer - die meisten PHP-Konfiguration nach 30 Sekunden fehl. Wenn Sie php.ini besitzen, können Sie das zu einem längeren Limit ändern. Aber trotzdem - ist das das überhaupt wert? Ich meine - die Dateien können größer werden oder Netzwerk langsamer - und noch einmal werden Sie die Zeitüberschreitung treffen. Dies ist

warum Download- gemacht wurden - große Dateien in kleinere Stücke zum Download Half Crazed zeigte Sie Code für die i THIS Antwort (es ist nicht nur eine - dies berücksichtigt nur eine der Möglichkeiten, Kunden die Transfers verhandeln - aber immer noch seine ein guter Anfang).

Mega.co.nz verwendet zum Beispiel neue HTML5-Funktionen. Lädt die Datei im Browser mit Chunks herunter, fügt die Datei dem Benutzer hinzu und "lädt" sie dann aus dem Browser-Speicherplatz. Es kann Dateien fortsetzen, Dateien anhalten und so weiter. (Entschuldigung - kein Code dafür, da es ziemlich groß wäre und mehr als eine Sprache (php, js) beinhalten würde).

PS: Ihr readfile($path); in ändern:

$handle=fopen($path, 'rb'); 
while (!feof($handle)) 
{ 
    echo fread($handle, 8192); 
    flush(); 
} 
fclose($handle); 

Dies wird nicht ganze Datei in den Speicher geladen werden, nur Teile 8KiB einmal an und dann an Benutzer senden.

+0

Obwohl das sehr wahr ist - es war das Keep-Alive von Apache2, das nicht hoch genug war. (Ich sah diese Frage noch einmal, dachte, ich würde dir eine Antwort geben) –

+0

Sorry für späte Antwort, aber Keep-Alive wird aus anderen Gründen verwendet ... Die meisten Server werden PHP nur nach 60 Sekunden beenden - auch wenn es immer noch sendende Datei (würde nur getötet werden). Und diese Grenze zu heben ist nicht oft weise – Seti