2014-04-11 35 views
1

我有一個令人難以置信的問題,我似乎無法解決。WebM文件無法在Chrome瀏覽器中通過PHP加載(其他瀏覽器工作)

通過PHP提供WebM文件在我的世界中並不新鮮,我甚至知道如何使用HTTP 206 Partial Content。但由於某種原因,Chrome不喜歡它。

一個簡單的HTML5視頻播放

<video width="640" height="360" poster="picture/preview/V00000006.jpg" controls="controls" preload> 
    <source type="video/webm" src="/video/V00000006.webm"> 
</video> 

其中/video/V00000006.webm被改寫爲Apache的一個PHP文件,將播放就好了。 但在Chrome中,seekbar無效。當點擊搜索欄時,播放器將凍結,不再播放,直到頁面刷新。 Firefox處理它就好!

如果我將/video/V00000006.webm更改爲直接鏈接到同一個視頻,它工作得很好。我甚至比較了兩個版本(帶和不帶PHP)之間的網絡請求,第一次請求幾乎沒有任何區別,但第二次是在PHP交付的視頻中失敗。

初始請求,並尋求爲Apache傳輸視頻文件請求:

 
    Request URL:http://mytestserver.net/movie1152x720.webm 
    Request Method:GET 
    Status Code:206 Partial Content 
    Request Headers 
    Accept:*/* 
    Accept-Encoding:identity;q=1, *;q=0 
    Accept-Language:da-DK,da;q=0.8,en-US;q=0.6,en;q=0.4 
    Cache-Control:no-cache 
    Connection:keep-alive 
    Cookie:PHPSESSID=i562540rek172mnv3nk528acj0; userPassword=; userEmail= 
    Host:mytestserver.net 
    Pragma:no-cache 
    Range:bytes=0- 
    Referer:http://mytestserver.net/video.html 
    User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36 
    Response Headers 
    Accept-Ranges:bytes 
    Connection:close 
    Content-Length:4446451 
    Content-Range:bytes 0-4446450/4446451 
    Content-Type:video/webm 
    Date:Fri, 11 Apr 2014 13:07:30 GMT 
    ETag:"d2d0027-43d8f3-b91417c0" 
    Last-Modified:Fri, 11 Apr 2014 12:46:31 GMT 
    Server:Apache/2.2.3 (CentOS) 

    -- 

    Request URL:http://mytestserver.net/movie1152x720.webm 
    Request Method:GET 
    Status Code:206 Partial Content 
    Request Headers 
    Accept:*/* 
    Accept-Encoding:identity;q=1, *;q=0 
    Accept-Language:da-DK,da;q=0.8,en-US;q=0.6,en;q=0.4 
    Cache-Control:no-cache 
    Connection:keep-alive 
    Cookie:PHPSESSID=i562540rek172mnv3nk528acj0; userPassword=; userEmail= 
    Host:mytestserver.net 
    Pragma:no-cache 
    Range:bytes=4445881- 
    Referer:http://mytestserver.net/video.html 
    User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36 
    Response Headers 
    Accept-Ranges:bytes 
    Connection:close 
    Content-Length:570 
    Content-Range:bytes 4445881-4446450/4446451 
    Content-Type:video/webm 
    Date:Fri, 11 Apr 2014 13:09:02 GMT 
    ETag:"d2d0027-43d8f3-b91417c0" 
    Last-Modified:Fri, 11 Apr 2014 12:46:31 GMT 
    Server:Apache/2.2.3 (CentOS) 

初始請求,並尋求PHP-流視頻要求:

 
    Request URL:http://mytestserver.net/video/V00000006.webm 
    Request Method:GET 
    Status Code:206 Partial Content 
    Request Headers 
    Accept:*/* 
    Accept-Encoding:identity;q=1, *;q=0 
    Accept-Language:da-DK,da;q=0.8,en-US;q=0.6,en;q=0.4 
    Cache-Control:no-cache 
    Connection:keep-alive 
    Cookie:PHPSESSID=i562540rek172mnv3nk528acj0; userPassword=; userEmail= 
    Host:mytestserver.net 
    Pragma:no-cache 
    Range:bytes=0- 
    Referer:http://mytestserver.net/video.html 
    User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36 
    Response Headers 
    Accept-Ranges:bytes 
    Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0 
    Connection:close 
    Content-Length:8566268 
    Content-Range:bytes 0-8566267/8566268 
    Content-Type:video/webm 
    Date:Fri, 11 Apr 2014 13:31:27 GMT 
    Expires:Thu, 19 Nov 1981 08:52:00 GMT 
    Pragma:no-cache 
    Server:Apache/2.2.3 (CentOS) 
    X-Powered-By:PHP/5.3.27 

    -- 

    Request URL:http://mytestserver.net/video/V00000006.webm 
    Request Headers CAUTION: Provisional headers are shown. 
    Accept-Encoding:identity;q=1, *;q=0 
    Cache-Control:no-cache 
    Pragma:no-cache 
    Range:bytes=4338314- 
    Referer:http://mytestserver.net/video.html 
    User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36 

注意一下第二個請求沒有完成,臨時標題顯示爲

我試圖改變緩存頭,將其設置爲將來設定他們的空白,並使用文件附件頭

我嘗試了很多與服務代碼擺弄,但最近我已經結束了一個簡單的例子。

<?php 

$path = 'test.webm'; 

$size=filesize($path); 

[email protected]($path,'rb'); 
if(!$fm) { 
    header ("HTTP/1.0 404 Not Found"); 
    die(); 
} 

$begin=0; 
$end = $size-1; 

if(isset($_SERVER['HTTP_RANGE'])) { 
    if(preg_match('/bytes=\h*(\d+)-(\d*)[\D.*]?/i', $_SERVER['HTTP_RANGE'], $matches)) { 
    $begin=intval($matches[0]); 
    if(!empty($matches[1])) { 
     $end=intval($matches[1]); 
    } 
    } 
} 

if($begin>0||$end<$size) 
    header('HTTP/1.0 206 Partial Content'); 
else 
    header('HTTP/1.0 200 OK'); 

header("Content-Type: video/webm"); 
header('Accept-Ranges: bytes'); 
header('Content-Length:'.($end-$begin+1)); 
header("Content-Disposition: inline;"); 
header("Content-Range: bytes $begin-$end/$size"); 
header("Content-Transfer-Encoding: binary\n"); 
header('Connection: close'); 

ob_get_clean(); 
flush(); 

$f = fopen($path, 'r'); 
fseek($f, $offset); 

$pos = 0; 
$length = $end-$begin; 

while($pos < $length) 
{ 
    $chunk = min($length-$pos, 1024); 

    echo fread($f, $chunk); 
    flush(); 

    $pos += $chunk; 
} 
?> 

請注意,直接在瀏覽器中輸入PHP提供的視頻URL並不會在HTML頁面中顯示它。

我希望有人有答案爲什麼尋找可能無法正常工作。如果您有任何建議,請告訴我。

謝謝!

回答

1

每個人的將來參考:

  1. 在PHP HTTP_RANGE的在線例子是完全錯誤
  2. 的Chrome是非常糟糕的,在解釋網絡錯誤
  3. 大小事宜!

總之,我的問題是由於我的PHP腳本計算和返回錯誤的數字。 Chrome只會表現得像它甚至沒有嘗試完成網絡請求,因此很難進行調試。

現在我把所有的網絡電話都通過cURL(在我的Linux控制檯中)。 在這裏,我會得到一個更有用的錯誤,如捲曲:(18)傳送與1個字節剩餘的讀取

這在內容長度1字節的錯誤使得鉻取消網絡請求和不顯示您的響應關閉它得到的標題以及爲什麼它取消了請求。

這是我的工作代碼,帶有Content-Range和Content-Length的工作計算。 $ filesize = filesize($ file);

$offset = 0; 
$length = $filesize; 

$partialContent = false; 

if(isset($_SERVER['HTTP_RANGE'])) 
{ 
    $partialContent = true; 

    if(!preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches)) 
    { 
     header('HTTP/1.1 416 Requested Range Not Satisfiable'); 
     header('Content-Range: bytes */' . $filesize); 
     exit; 
    } 

    $offset = intval($matches[1]); 

    if(isset($matches[2])) 
    { 
     $end = $intval($matches[2]); 
     if($offset > $end) 
     { 
      header('HTTP/1.1 416 Requested Range Not Satisfiable'); 
      header('Content-Range: bytes */' . $filesize); 
      exit; 
     } 

     $length = $end - $offset; 
    } 
    else 
     $length = $filesize - $offset; 
} 

header('Content-Length: ' . $length); 

if($partialContent) 
{ 
    header('HTTP/1.1 206 Partial Content'); 
    header('Content-Range: bytes ' . $offset . '-' . ($offset + $length - 1) . '/' . $filesize); 
    // A full-length file will indeed be "bytes 0-x/x+1", think of 0-indexed array counts 
} 

請注意上面的代碼中只包含與部分內容的代碼,你仍然需要其他標題,等真正用它做什麼。

如果有人有興趣,下面是我的代碼讀取文件。我在網上看到了很多糟糕的錯誤建議,但我認爲我的工作很乾淨。

$f = fopen($file, 'r'); 
fseek($f, $offset); 

$pos = 0; 

while($pos < $length) 
{ 
    $chunk = min($length-$pos, 1024*8); 

    echo fread($f, $chunk); 
    flush(); 
    ob_flush(); 

    $pos += $chunk; 
} 

結案, 好運來所有:-)

相關問題