我有一个相当大的 QuickTime .MOV 文件库,这些文件由以前工作得很好的页面提供服务; HTML没有多年改变,但有人注意到它不再适用于Safari,尽管所有其他浏览器似乎都没问题。
相反,现在在OS X 中的 Safari 8.0.7中,它会显示" 缺少插件"按钮,按下时会弹出一个警告:
此网页包含需要互联网插件的内容。
此页面包含无法显示的内容,因为其类型未指定。 此页面可能包含供您下载和安装的插件:
http://www.apple.com/quicktime/download/
想要打开此页吗?
按OK就会把我带到那里,但我得到的OS X就是" QuickTime内置于Mac OS X中。"没有插件。
虽然我最喜欢切换到.MP4格式并使用HTML5 VIDEO标记,但我试图保持向后兼容性。除了新的视频标签只能播放MP4,WebM和Ogg格式。 Apple无法在自己的浏览器中播放QuickTime文件似乎很荒谬。 [见下面的更新]
除此之外......它可以。 直接将网址加载到.MOV文件,这表明它不是格式,而是错误的HTML 。事实上,我在plug-in list中列出了QuickTime 7.7.3。
生成的内容是:
<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" width="320" height="256" codebase="http://www.apple.com/qtactivex/qtplugin.cab#version=7,3,0,0" align="middle">
<param name="src" value="file.mov">
<param name="kioskmode" value="true">
<embed src="file.mov" width="320" height="256" pluginspage="http://www.apple.com/quicktime/download/" align="middle" kioskmode="true">
</object>
我说&#39;生成&#39;因为我遵循了Apple的HTML Scripting指南,即使用this example的ac_quicktime.js
脚本(v1.2)编写的 Apple ,为给定的浏览器生成正确的代码。
<script language="javacript" type="text/javascript">
QT_WriteOBJECT('file.mov',
'320', '256',
'',
'kioskmode', 'true',
'pluginspage','http://www.apple.com/quicktime/download/',
'align', 'middle');
</script>
使用Safari的Web Inspector检查DOM,显示上面的JavaScript确实生成了对象/嵌入块。
我甚至用wget
验证了直接拉媒体文件时MIME类型是否正确:
Content-Type: video/quicktime
使用Ghostery和uBlock Origin的一些小实验表明没有任何东西被阻挡。控制网站,它确认没有跟踪器,并且因为它生成了上述内容,所以它不会阻止JavaScript。
更多实验表明,我的iPhone和iPad上也会出现此问题。否#34;缺少插件&#34;按钮,只是画布上应该是电影的空洞。
ffprobe报告有效的视频文件(H.264,320x240; AAC 48000 Hz,Mono,29.97 fps,19.8 MB,294.68 kbit / s):
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'file.mov':
Metadata:
major_brand : qt
minor_version : 537199360
compatible_brands: qt
creation_time : 2007-09-17 02:37:42
Duration: 00:08:42.39, start: 0.000000, bitrate: 302 kb/s
Stream #0:0(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, mono, fltp, 80 kb/s (default)
Metadata:
creation_time : 2007-09-17 02:37:42
handler_name : Apple Alias Data Handler
Stream #0:1(eng): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, smpte170m/smpte170m/bt709), 320x240, 173 kb/s, 29.97 fps, 29.97 tbr, 2997 tbn, 5994 tbc (default)
Metadata:
creation_time : 2007-09-17 02:37:42
handler_name : Apple Alias Data Handler
encoder : H.264
Stream #0:2(eng): Data: none (rtp / 0x20707472), 32 kb/s
Metadata:
creation_time : 2007-09-17 02:37:42
handler_name : Apple Alias Data Handler
Stream #0:3(eng): Data: none (rtp / 0x20707472), 9 kb/s
Metadata:
creation_time : 2007-09-17 02:37:42
handler_name : Apple Alias Data Handler
对可能发生的事情的任何想法?
更新#1:
建议使用HTML5 VIDEO标记,如下所示:
<video width="320" height="240" controls>
<source src="file.mov" type="video/quicktime">
Your browser does not support the video tag.
</video>
令我惊讶的是,这实际上是#34;工作&#34;在Safari中。但是,在其他不支持HTML5的浏览器中以及那些认识到这不支持视频格式的浏览器中,它可怕地破坏了。
因此确认VIDEO标记不是解决方案,因为这会破坏向后兼容性要求。
新信息:
我有一个忏悔。上面显示的file.mov
是为了简化读者的示例。 实际值是一个包含PHP脚本的URL,用于选择要显示的.MOV文件。
我刚刚发现,当我使用.mov
而不是.php
的文件时,页面工作得很好。 这曾经用作PHP ...多年。
更令人不安的是, 该插件 正在查看正确传递的Content-Type
,但文件扩展名为 。这可能是苹果公司的一个错误,也可能是我的错误(我希望是这样的)。但目前,它阻止我提供动态内容。
Apple的JavaScript函数正在使用我的URL生成正确的对象/嵌入标记,静态快照显示如果我使用扩展名为.mov
的文件,它可以工作,但不是脚本,甚至如果两者都提供相同的内容。
我正在进行进一步的实验来断言内容类型是正确的。 wget
说,Safari的网络检查员似乎不这么说。
更新#2:
奇怪的事情肯定会发生。
如果我直接在浏览器中加载file.mov
,则会播放。
如果我直接在浏览器中加载此file.php
,它也会播放。
<?php
$filename = "file.mov";
$handle = fopen( $filename, "rb" );
if ( $handle ) {
header( "Content-type: video/quicktime" );
header( "Accept-Ranges: bytes" );
header( "Content-Length: " . filesize( $filename ) );
fpassthru( $handle );
flush();
exit;
} // if handle
?>
如果我在浏览器中加载此file.html
,则会发生有趣的事情。第一个条目显示Missing Plug-In,其他条目播放。
<HTML>
<BODY>
<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" width="320" height="256" codebase="http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0" align="middle">
<param name="src" value="file.php">
<param name="kioskmode" value="true">
<embed src="file.php" width="320" height="256" pluginspage="http://www.apple.com/quicktime/download/" align="middle" kioskmode="true">
</object>
<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" width="320" height="256" codebase="http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0" align="middle">
<param name="src" value="file.mov">
<param name="kioskmode" value="true">
<embed src="file.mov" width="320" height="256" pluginspage="http://www.apple.com/quicktime/download/" align="middle" kioskmode="true">
</object>
<video width="320" height="240" controls>
<source src="file.php" type="video/quicktime">
Your browser does not support the video tag.
</video>
<video width="320" height="240" controls>
<source src="file.mov" type="video/quicktime">
Your browser does not support the video tag.
</video>
</BODY>
</HTML>
至少对我来说,这表明Apple 有一个错误,因为它不会加载动态内容。
同意?不同意?想法?
我真的好奇&#34;对&#34;这样做的方法是。
另一项实验,我将video/quicktime
更改为video/mp4
,它适用于Safari版本。
我担心我可能必须检测浏览器是否为Safari,如果它处理VIDEO标记,如果是,则使用.php
选择代码而不是Apple的object / embed标记发出该hack
更新3:
发现Safari正在发出此错误消息:
Failed to load resource: Plug-in handled load
发现这篇有趣的帖子someone else confirms that videos from PHP don't work, but directly served they do。
这表明视频不应再通过blob servers发送。
解决:
这就是问题所在。曾经有人能够发送整个文件,Safari和iOS不再那样了。
这就是为什么提供相同内容的行为方式不同。这是问题的传递机制,而不是内容。
查看有关使用PHP代码和信用的标记答案。
答案 0 :(得分:1)
这篇StackOverflow文章让我找到了一个有效的解决方案:
Using php to output an mp4 video
问题是Safari和iOS不希望一次性传送整个.MOV文件,事实上,插件会抛出错误。相反,它想把它搞定。
这是解决问题的代码,几乎从上面的答案中获取并包含在函数中:
function RenderVideo( $file ) {
$fp = @fopen($file, 'rb');
$size = filesize($file); // File size
$length = $size; // Content length
$start = 0; // Start byte
$end = $size - 1; // End byte
header('Content-type: video/mp4');
header("Accept-Ranges: 0-$length");
if (isset($_SERVER['HTTP_RANGE'])) {
$c_start = $start;
$c_end = $end;
list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
if (strpos($range, ',') !== false) {
header('HTTP/1.1 416 Requested Range Not Satisfiable');
header("Content-Range: bytes $start-$end/$size");
exit;
}
if ($range == '-') {
$c_start = $size - substr($range, 1);
}else{
$range = explode('-', $range);
$c_start = $range[0];
$c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
}
$c_end = ($c_end > $end) ? $end : $c_end;
if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size) {
header('HTTP/1.1 416 Requested Range Not Satisfiable');
header("Content-Range: bytes $start-$end/$size");
exit;
}
$start = $c_start;
$end = $c_end;
$length = $end - $start + 1;
fseek($fp, $start);
header('HTTP/1.1 206 Partial Content');
}
header("Content-Range: bytes $start-$end/$size");
header("Content-Length: ".$length);
$buffer = 1024 * 8;
while(!feof($fp) && ($p = ftell($fp)) <= $end) {
if ($p + $buffer > $end) {
$buffer = $end - $p + 1;
}
set_time_limit(0);
echo fread($fp, $buffer);
flush();
}
fclose($fp);
exit();
}