PHP服务MP4 - Chrome"临时标题显示/请求尚未完成"窃听器

时间:2014-09-22 13:58:57

标签: php google-chrome http-headers video-streaming stripe-payments

我想检查用户'订阅之前允许他们看到视频,因此我使用PHP与Stripe进行互动以检查用户的订阅,而不是使用PHP script将MP4投放到浏览器

首次在Google Chrome中播放视频时使用效果很好(使用HTML5播放器)... 但是,当我关闭视频并再次播放时,视频不再播放...我也无法重新加载当前页面。就像服务器停止工作一样。

当我检查第一个视频请求(播放的那个)时,在Timing选项卡中我看到:"小心:请求尚未完成!" (下面的截图)

CAUTION: request is not finished yet!

当我检查第二个视频请求(未播放的那个)时,在标题选项卡中显示" [警告标志]显示临时标题" (下面的截图)

enter image description here

一切都在Safari或Firefox中按预期工作

任何人都知道发生了什么事吗?视频再次播放的唯一方法是关闭当前标签,再次进入该网站。重新加载不起作用!

3 个答案:

答案 0 :(得分:1)

我建议您使用以下功能代替当前的“流式脚本”。如果你传递$ filename_output,它将把文件作为下载服务,否则它将流传输!

它应该适用于每个浏览器。

serveFile( '/哪里/我/ 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();
    }
}

答案 1 :(得分:1)

嗯,我当然是一个有趣的问题。并且很难确定这里的根本原因。但如果我在你的情况下,我会检查两件事。

  1. 首先,我要确保httpd.conf上的keep-alive设置为关闭KeepAlive Off

  2. 然后使用此配置对其进行测试。

  3. 然后我将禁用所有浏览器缓存:

    标题('缓存控制:无缓存,无存储,必须重新验证'); 标题(' Pragma:no-cache'); 标题('过期:0');

  4. 之后的最终测试。

  5. 问题似乎是保持活动或浏览器缓存,或者两者兼而有之,但我无法理解为什么它只出现在chrome中。作为最后的手段,请确保您没有使用可能会产生Adblock等问题的任何扩展程序。

    希望我能告诉您这些信息:)

答案 2 :(得分:0)

尝试流式传输音频文件时遇到了同样的问题。我最终真的巧妙地解决了我的问题。

我在某个时候创建​​了一个脚本,可以使用FFMPEG将文件的比特率降低到128kbps(据我所知也适用于视频)。之后在检查chrome时我开始注意到我的所有请求都在几秒钟后完成,而不是像以前一样无限期地保持不完整。不确定这是否适合您,但压缩文件解决了这个问题以及提高流速度,所以我强烈推荐这个。