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

前端 未结 3 1995
野性不改
野性不改 2020-12-11 03:09

I want to check for users\' subscription before allow them to see the video, for this reason I use PHP to interact with Stripe to check for user\'s subscription, and than us

3条回答
  •  感动是毒
    2020-12-11 04:05

    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();
        }
    }
    

提交回复
热议问题