2009-12-12 2 views
12

Tout d'abord, je suis au courant de questions similaires posées auparavant.Diffusion de fichiers PHP à distance avec prise en charge de la reprise

Le sujet assez explique bien la question, mais encore,

le fichier est hébergé sur un autre serveur, l'utilisateur télécharger le fichier via mon script, lui diffusé en continu ...

Mais le problème est facile à utiliser ne peut pas le reprendre une fois en pause ... des solutions?

Répondre

1

Si vous utilisez PHP pour servir le fichier, vous devez implémenter toute la logique de reprise vous-même.

Vous devrez envoyer Accept-Ranges et respond appropriately à Ranges.

C'est un gros morceau de travail. Il pourrait être plus facile d'utiliser mod_proxy.

1

Quel est le but de ceci? cacher des URL seulement ou simplement permettre aux membres de télécharger?

La façon dont vous l'avez décrit, il est un peu difficile ...

  1. Le serveur distant de votre script téléchargera de téléchargements devrait soutenir la reprise.
  2. Votre script php doit vérifier l'en-tête 'Accept-Range' & le passer au serveur distant (l'utilisation de sockets est votre meilleure option je suppose) donc votre script agit comme un proxy.
17

Vous pouvez mettre en œuvre votre propre script de téléchargement en utilisant Accept-Ranges et Content-Range ici est un prof concept:

set_time_limit(0); 
$download = new ResumeDownload("word.dir.txt", 50000); //delay about in microsecs 
$download->process(); 

Utilisation d'Internet Download Manager

Début

Start

fit une pause

Paused

État Paused

Paused State

CV

Resume

Fini

enter image description here

classe Utilisé

class ResumeDownload { 
    private $file; 
    private $name; 
    private $boundary; 
    private $delay = 0; 
    private $size = 0; 

    function __construct($file, $delay = 0) { 
     if (! is_file($file)) { 
      header("HTTP/1.1 400 Invalid Request"); 
      die("<h3>File Not Found</h3>"); 
     } 

     $this->size = filesize($file); 
     $this->file = fopen($file, "r"); 
     $this->boundary = md5($file); 
     $this->delay = $delay; 
     $this->name = basename($file); 
    } 

    public function process() { 
     $ranges = NULL; 
     $t = 0; 
     if ($_SERVER['REQUEST_METHOD'] == 'GET' && isset($_SERVER['HTTP_RANGE']) && $range = stristr(trim($_SERVER['HTTP_RANGE']), 'bytes=')) { 
      $range = substr($range, 6); 
      $ranges = explode(',', $range); 
      $t = count($ranges); 
     } 

     header("Accept-Ranges: bytes"); 
     header("Content-Type: application/octet-stream"); 
     header("Content-Transfer-Encoding: binary"); 
     header(sprintf('Content-Disposition: attachment; filename="%s"', $this->name)); 

     if ($t > 0) { 
      header("HTTP/1.1 206 Partial content"); 
      $t === 1 ? $this->pushSingle($range) : $this->pushMulti($ranges); 
     } else { 
      header("Content-Length: " . $this->size); 
      $this->readFile(); 
     } 

     flush(); 
    } 

    private function pushSingle($range) { 
     $start = $end = 0; 
     $this->getRange($range, $start, $end); 
     header("Content-Length: " . ($end - $start + 1)); 
     header(sprintf("Content-Range: bytes %d-%d/%d", $start, $end, $this->size)); 
     fseek($this->file, $start); 
     $this->readBuffer($end - $start + 1); 
     $this->readFile(); 
    } 

    private function pushMulti($ranges) { 
     $length = $start = $end = 0; 
     $output = ""; 

     $tl = "Content-type: application/octet-stream\r\n"; 
     $formatRange = "Content-range: bytes %d-%d/%d\r\n\r\n"; 

     foreach ($ranges as $range) { 
      $this->getRange($range, $start, $end); 
      $length += strlen("\r\n--$this->boundary\r\n"); 
      $length += strlen($tl); 
      $length += strlen(sprintf($formatRange, $start, $end, $this->size)); 
      $length += $end - $start + 1; 
     } 
     $length += strlen("\r\n--$this->boundary--\r\n"); 
     header("Content-Length: $length"); 
     header("Content-Type: multipart/x-byteranges; boundary=$this->boundary"); 
     foreach ($ranges as $range) { 
      $this->getRange($range, $start, $end); 
      echo "\r\n--$this->boundary\r\n"; 
      echo $tl; 
      echo sprintf($formatRange, $start, $end, $this->size); 
      fseek($this->file, $start); 
      $this->readBuffer($end - $start + 1); 
     } 
     echo "\r\n--$this->boundary--\r\n"; 
    } 

    private function getRange($range, &$start, &$end) { 
     list($start, $end) = explode('-', $range); 

     $fileSize = $this->size; 
     if ($start == '') { 
      $tmp = $end; 
      $end = $fileSize - 1; 
      $start = $fileSize - $tmp; 
      if ($start < 0) 
       $start = 0; 
     } else { 
      if ($end == '' || $end > $fileSize - 1) 
       $end = $fileSize - 1; 
     } 

     if ($start > $end) { 
      header("Status: 416 Requested range not satisfiable"); 
      header("Content-Range: */" . $fileSize); 
      exit(); 
     } 

     return array(
       $start, 
       $end 
     ); 
    } 

    private function readFile() { 
     while (! feof($this->file)) { 
      echo fgets($this->file); 
      flush(); 
      usleep($this->delay); 
     } 
    } 

    private function readBuffer($bytes, $size = 1024) { 
     $bytesLeft = $bytes; 
     while ($bytesLeft > 0 && ! feof($this->file)) { 
      $bytesLeft > $size ? $bytesRead = $size : $bytesRead = $bytesLeft; 
      $bytesLeft -= $bytesRead; 
      echo fread($this->file, $bytesRead); 
      flush(); 
      usleep($this->delay); 
     } 
    } 
} 

File Used

+0

Merci! Tu m'as beaucoup aidé !!! – HtmHell

+0

Vous êtes les bienvenus :) – Baba

+0

vraiment grand travail 1+ –

Questions connexes