【CakePHP】コントローラーから動画を表示する場合のメモ(会員サイトなど)

2019年7月29日

バージョン:CakePHP2.x

CakePHPで動画を表示する際、コントローラー経由で表示をする場合のメモです。
動画ファイルは非公開のフォルダに入れて、ファイルパスとファイル名を取得し表示しています。

	public function index() {
		$this->autoRender = false;
		
		$mime_type = "video/mp4";
		$file_path = "ファイルパス+ファイル名";
		
		if (isset($_SERVER['HTTP_RANGE'])){
			Header('Content-type:'.$mime_type);
			$this->_rangeDownload($file_path);
			exit;
		} else {
			Header( "Accept-Ranges: bytes" ) ;
			Header('Content-type: MIME-Type');
			Header('Content-type:'.$mime_type);
			Header("Accept-Ranges: bytes");
			Header("Content-length: " . filesize($file_path));
			Header("Etag: \"" . md5( $_SERVER["REQUEST_URI"] ) . filesize($file_path) . "\"" );
			Header("Last-Modified: " . gmdate( "D, d M Y H:i:s", filemtime($file_path)) . " GMT");
			readfile($file_path);
			exit;
		}
	}
	function _rangeDownload($file){
		$fp = @fopen($file, 'rb');
	
		$size   = filesize($file);
		$length = $size;
		$start  = 0;
		$end    = $size - 1;
		header("Accept-Ranges: 0-$length");
		
		if (isset($_SERVER['HTTP_RANGE'])){
			$c_start = $start;
			$c_end   = $end;
	
			list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
			if (strpos($range, ',') !== false){
				header('HTTP/1.1 416 Requested Range Not Satisfiable');
				header("Content-Range: bytes $start-$end/$size");
				exit;
			} 
			if ($range{0} == '-'){
				$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;
			if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size){
				header('HTTP/1.1 416 Requested Range Not Satisfiable');
				header("Content-Range: bytes $start-$end/$size");
				exit;
			}
	
			$start  = $c_start;
			$end    = $c_end;
			$length = $end - $start + 1;
			fseek($fp, $start);
			header('HTTP/1.1 206 Partial Content');
				}
	
				header("Content-Range: bytes $start-$end/$size");
				header("Content-Length: $length");
	
				$buffer = 1024 * 8;
				while(!feof($fp) && ($p = ftell($fp)) <= $end){
					if ($p + $buffer > $end){
						$buffer = $end - $p + 1;
					}
	
					set_time_limit(0);
					echo fread($fp, $buffer);
					flush();
				}
	
				fclose($fp);
		}
	}

参考:stackoverflow

スポンサーリンク