public function downloadAction() { $this->_helper->viewRenderer->setNoRender(); $this->_helper->layout->disableLayout(); $videoFolder = realpath(APPLICATION_PATH . "/videos"); //This is example video - it can be from a param $video = $videoFolder . "/zyploiifb5cja02a.mp4"; $fileBaseName = basename($video); $fileParts = explode(".", $fileBaseName); $ext = $fileParts[count($fileParts)-1]; switch ($ext) { case 'mp4': $this->getResponse()->setHeader('Content-Type', 'video/mp4'); break; case 'flv': $this->getResponse()->setHeader('Content-Type', 'video/flv'); } $fp = fopen($video, 'rb'); $size = filesize($video); $length = $size; $chunksize = 1 * (1024 * 1024); if(empty($_SERVER['HTTP_RANGE'])) { $this->getResponse()->setHeader('Content-Length', $length); $this->getResponse()->sendHeaders(); while (!feof($fp)) { echo fread($fp, $chunksize); ob_flush(); flush(); } fclose($fp); exit; } /* * FROM http://mobiforge.com/developing/story/content-delivery-mobile-devices */ $start = 0; $end = $length - 1; $this->getResponse()->setHeader('Accept-Ranges', '0-'.$length); $this->getResponse()->setHttpResponseCode(206); $c_start = $start; $c_end = $end; list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2); if ($range == '-') { $c_start = $size - substr($range, 1); } else { $range = explode('-', $range); $c_start = $range[0]; $c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size; } $c_end = ($c_end > $end) ? $end : $c_end; $start = $c_start; $end = $c_end; $length = $end - $start + 1; fseek($fp, $start); $this->getResponse()->setHeader('Content-Range', "bytes $start-$end/$size"); $this->getResponse()->setHeader('Content-Length', $length); $this->getResponse()->sendHeaders(); $bytesSent = 0; while(!feof($fp) && ($p = ftell($fp)) <= $end) { if ($p + $chunksize > $end) { $chunksize = $end - $p + 1; } set_time_limit(0); echo fread($fp, $chunksize); $bytesSent += $chunksize; ob_flush(); flush(); } fclose($fp); die; }