PHP文件作为URL无法播放视频流

4
我有一个包含视频HTML标记的PHP文件。在源标签的src部分中,我不使用完整的URL,而是使用一个包含呈现视频文件代码的PHP文件。
PHP文件名称后跟一串随机字符,用作实际视频文件名称的密钥。我将这些值存储在$_SESSION中,以便呈现视频文件的PHP文件知道要查找哪个文件。我还使用cookie,以使任何人都无法重复使用令牌。
这在Firefox和Chrome中运行得很好,但在Safari和Android和iOS上尝试的所有移动浏览器中都失败了。
为简单起见,我将整个过程简化为仅使视频呈现PHP文件,而包含HTML标记的PHP文件直接调用该文件,而不使用唯一令牌。
这样做时,有时Safari会加载(非常慢),而移动设备仍然完全失败。
第一个文件的相关部分如下:
<video>
<source src=\"/videofile.php\" type=\"video/mp4\">
</video>

另一个文件只是为了检查这个是否有效:
readfile('filename.mp4');

因此,非移动版Safari有时会以非常缓慢的方式加载它。但是,每当我添加任何其他内容(包括将文件名存储在变量中并调用变量作为readfile()函数的参数时,使用会话时,使用cookie时以及基本上任何其他操作),它都会失败。
我尝试了许多其他方法来将文件分成块,因为我认为这就是为什么它在移动设备上无法播放的原因,但是直接将视频文件加载到源标签中没有问题。问题似乎出在我如何调用视频文件上。
我不知道为什么它可以在Firefox和Chrome上运行,但对于上述其他浏览器却无法运行。我现在不确定该怎么办。我甚至不确定我是否正确地表达了问题,因为我的所有谷歌查询都未能产生像我所说的那样的结果。
编辑:我已经添加了我正在使用的完整文件代码。
第一个。
<?php
ini_set('session.use_cookies',1);
session_start();

$mp4=uniqid(); 
$_SESSION[$mp4]='video.mp4';
$ogv=uniqid(); 
$_SESSION[$ogv]='video.ogv';

echo "
<div style=\"position: relative;padding-bottom: 56.25%;padding-top:35px;height: 0;overflow: hidden;\" oncontextmenu=\"return false\">
<video style=\"position: absolute;top:0;left: 0;width: 100%;height: 100%;\" height=\"540\" width=\"864\" controls>

<source src=\"/videorender.php?video=" . $mp4 . "\" type=\"video/mp4\">
<source src=\"/videorender.php?video=" . $ogv . "\" type=\"video/ogv\">
</video>
</div>
";

?>

现在来看一下VideoRenderer.php。
<?php
ini_set('session.use_cookies',1);
session_start();

$file = $_SESSION[$_GET['video']];

$_SESSION=array();
$params = session_get_cookie_params();
setcookie(session_name(),'', time()-42000,$params["path"],$params["domain"],
                                     $params["secure"], $params["httponly"]);

if(!file_exists($file) || $file === '' || !is_readable($file)){
header('HTTP/1.1 404 File not found',true);

exit;
}

readfile($file);

exit;

?>

你比较过你的 PHP 脚本和直接嵌入的 HTTP 标头了吗?另一方面,通过 PHP 管道传输 vid 文件真的是一个非常糟糕的想法...(性能问题) - Tino Rüb
1个回答

0
你有比较过你的 PHP 脚本和直接嵌入视频文件之间的 HTTP 头吗?
例如,你必须发送 Content-Type:video/mp4
header("Content-Type:video/mp4");

Content-Length 头部也是一个好主意:

header('Content-Length: '.filesize($videoFile));

还有其他情况,比如一些浏览器发送多个请求。请参见类似的问题:https://dev59.com/zk7Sa4cB1Zd3GeqP5ag4#3125869

另一方面:通过php传输视频文件是一个非常糟糕的想法(会影响服务器性能),就像您所描述的那样。使用这种方法,您将得不到任何能够令您满意的解决方案。

如果您想要实现像授权之类的东西,最好的方法是使用流媒体服务器。无论视频是在流媒体中传输还是作为渐进式下载提供。

我能想到的唯一解决方案是将http重定向到视频文件。但我想这也可能会失败,特别是在原生播放器(如移动设备)上。


最好的结果确实是使用该头文件。然而,这只是让Safari在非移动版Safari中加载速度稍微快了一点,并且稍微更频繁地加载。 - entropic616
请使用 Firebug 等工具比较“正常”的嵌入方式和您的解决方案之间的完整http headers,并像上面描述的那样操作所有标头信息。 我猜 Content-Length 对于例如正确执行此操作也是必需的。 - Tino Rüb
我刚刚看了你发布的链接。我确实注意到Safari正在发出两个请求。我的测试方法是在文件变量加载会话令牌后使用mail()向我发送电子邮件。当我通过Safari调用文件时,我会收到两封电子邮件。其中一封包含文件名,另一封则为空白。我正在认真考虑采取不同的方法。我听说使用Web套接字可以非常有用地流式传输视频。 - entropic616
@entropic616 谢谢您的回复。对于使用Web套接字进行视频流传输,我还不太熟悉。如果您能成功采用这种方法,那将是很好的。 - Tino Rüb
1
我最终没有使用一次性的php url来完成它。此外,我使用了一个条件语句来判断用户是否在移动设备上。如果他们在移动设备上,它将提供直接的视频文件。如果不是移动设备,则管道正在工作。对于Safari,我添加了一个查询字符串到php视频源。videorenderer.php?type=stuff.mp4。这个加上视频类型头,似乎已经帮助视频在Safari中每次成功加载。它仍然有点慢,但我添加了.gif,用于视频加载时。 - entropic616
@entropic616 感谢你的反馈! - Tino Rüb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接