PHP serve MP4 - Chrome "Provisional headers are shown/request is not finished yet" bug PHP serve MP4 - Chrome "Provisional headers are shown/request is not finished yet" bug google-chrome google-chrome

PHP serve MP4 - Chrome "Provisional headers are shown/request is not finished yet" bug


I suggest you use the following function instead of your current 'streaming script'. If you pass $filename_output, it will serve the file as download, and it will stream otherwise!

It should work in every browser.

serveFile('/where/my/vid.mp4');

public function serveFile($filename, $filename_output = false, $mime = 'application/octet-stream'){    $buffer_size = 8192;    $expiry = 90; //days    if(!file_exists($filename))    {        throw new Exception('File not found: ' . $filename);    }    if(!is_readable($filename))    {        throw new Exception('File not readable: ' . $filename);    }    header_remove('Cache-Control');    header_remove('Pragma');    $byte_offset = 0;    $filesize_bytes = $filesize_original = filesize($filename);    header('Accept-Ranges: bytes', true);    header('Content-Type: ' . $mime, true);    if($filename_output)    {        header('Content-Disposition: attachment; filename="' . $filename_output . '"');    }    // Content-Range header for byte offsets    if (isset($_SERVER['HTTP_RANGE']) && preg_match('%bytes=(\d+)-(\d+)?%i', $_SERVER['HTTP_RANGE'], $match))    {        $byte_offset = (int) $match[1];//Offset signifies where we should begin to read the file                    if (isset($match[2]))//Length is for how long we should read the file according to the browser, and can never go beyond the file size        {            $filesize_bytes = min((int) $match[2], $filesize_bytes - $byte_offset);        }        header("HTTP/1.1 206 Partial content");        header(sprintf('Content-Range: bytes %d-%d/%d', $byte_offset, $filesize_bytes - 1, $filesize_original)); ### Decrease by 1 on byte-length since this definition is zero-based index of bytes being sent    }    $byte_range = $filesize_bytes - $byte_offset;    header('Content-Length: ' . $byte_range);    header('Expires: ' . date('D, d M Y H:i:s', time() + 60 * 60 * 24 * $expiry) . ' GMT');    $buffer = '';    $bytes_remaining = $byte_range;    $handle = fopen($filename, 'r');    if(!$handle)    {        throw new Exception("Could not get handle for file: " .  $filename);    }    if (fseek($handle, $byte_offset, SEEK_SET) == -1)    {        throw new Exception("Could not seek to byte offset %d", $byte_offset);    }    while ($bytes_remaining > 0)    {        $chunksize_requested = min($buffer_size, $bytes_remaining);        $buffer = fread($handle, $chunksize_requested);        $chunksize_real = strlen($buffer);        if ($chunksize_real == 0)        {            break;        }        $bytes_remaining -= $chunksize_real;        echo $buffer;        flush();    }}


Well i certainly is an intriguing problem. And is really hard to determine the root cause here. But if i was in your case i would check for two things.

  1. First i would make sure that keep-alive is set to off KeepAlive Off on your httpd.conf

  2. Afterwards test it with this configuration.

  3. Then i would disable all browser caching:

    header('Cache-Control: no-cache, no-store, must-revalidate');header('Pragma: no-cache');header('Expires: 0');

  4. Final test after that.

The issue seems to be either with keep-alive or browser caching or even both, but i can not understand why it appears only in chrome. As a last resort make sure that you are not using any extensions that may create problems like Adblock.

Hope i get you going with these information :)


I had this same issue when trying to stream audio files. I ended up actually solving my problem by sheer coincidence.

I at some point created a script that would reduce the bitrate of the files to 128kbps using FFMPEG (works for videos too as far as i know). After that when inspecting in chrome I started to notice that all of my requests where completing after a couple of seconds, as opposed to staying incomplete indefinitely as before. Not sure if this viable for you not, but compressed the files solved this issue as well as increasing streaming speeds so I highly recommend this.