I am having a mind-boggling problem, I just can't seem to resolve.
Providing a WebM file through PHP is nothing new in my world, and I even know how to work with HTTP 206 Partial Content. But for some reason Chrome does not like it.
A simple HTML5 video playback
<video width="640" height="360" poster="picture/preview/V00000006.jpg" controls="controls" preload>
<source type="video/webm" src="/video/V00000006.webm">
</video>
where /video/V00000006.webm
is rewritten to a PHP-file in Apache, will playback just fine.
But in Chrome the seekbar is not effective. When clicking on the seekbar the player will freeze and no longer playback until page is refreshed. Firefox handles it just fine!
If I change /video/V00000006.webm
to be a direct link to the same video it works just fine. I even compared the network requests between the two versions (with and without PHP) and there is barely any difference in the first request, but the second is failing in the PHP-delivered video.
Initial request and seek request for Apache-delivered video file:
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)
Initial request and seek request for PHP-streamed video:
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
Notice how the second request does not complete, Provisional headers are shown.
I have tried altering the cache headers, setting it to the future, setting them blank and using file attachment headers.
I tried fiddling around a lot with the serving code, but lately I have ended up with a simple example.
<?php
$path = 'test.webm';
$size=filesize($path);
$fm=@fopen($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;
}
?>
Please note, entering the PHP-delivered video URL directly into the browser does not make a difference from showing it in a HTML page.
I hope someone has an answer to why seeking might not work. Let me know if you have any suggestions.
Thanks!