javascript - 在Safari 8中播放.MOV文件的HTML —发生了什么变化?

标签 javascript html safari quicktime .mov

我有一个相当大的QuickTime .MOV文件库,该文件由一个曾经工作得很好的页面提供; HTML多年来没有变化,但有人注意到它不再适用于Safari,尽管所有其他浏览器似乎都不错。

取而代之的是,现在在OS X的Safari 8.0.7中,它显示了一个“缺少插件”按钮,当按下该按钮时会弹出一个警告,提示:


  该网页包含需要Internet插件的内容。
  
  该页面包含无法显示的内容,因为其类型未指定。
  该页面可能具有供您下载和安装的插件:
  
  http://www.apple.com/quicktime/download/
  
  要打开此页面吗?


按“确定”将我带到那里,但是使用OS X只能得到的是“ QuickTime已内置在Mac OS X中”。没有插件。

虽然我没有什么比切换到.MP4格式并使用HTML5 VIDEO标签更好的了,但是我试图保持向后兼容性。此外,新的视频标签只能播放MP4,WebM和Ogg格式。苹果无法在自己的浏览器中播放QuickTime文件似乎很荒谬。 [请参阅下面的更新]

除了...可以。将直接URL加载到.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>


之所以说“已生成”,是因为我遵循Apple的HTML Scripting准则,即使用Apple编写的this exampleac_quicktime.js脚本(v1.2)为给定的浏览器生成正确的代码。

<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确实生成了object / embedded块。

我什至用wget验证了直接拉出媒体文件时MIME类型是正确的:

Content-Type: video/quicktime


使用Ghostery和uBlock Origin进行的一些实验表明,没有任何东西被阻止。在站点的控制之下,它确认没有跟踪器,并且在生成上述内容时,它没有阻止JavaScript。

更多的实验表明,这个问题也发生在我的iPhone和iPad上。没有“缺少插件”按钮,只是画布上应该放置影片的空洞。

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>


令我惊讶的是,这实际上在Safari中“有效”。但是,它在不支持HTML5的其他浏览器以及识别出不支持此视频格式的浏览器中严重崩溃。

因此,已经确认VIDEO标签不是解决方案,因为这违反了向后兼容的要求。

新的消息:

我有一个表白上面显示的file.mov是为读者简化示例的。实际值是一个包含PHP脚本的URL,该脚本选择要显示的.MOV文件。

我刚刚发现,当我将文件与.mov而不是.php一起使用时,页面工作正常。多年来一直作为PHP使用……。

更令人不安的是,该插件似乎没有查看正确传递的Content-Type,而是文件扩展名。这既可能是Apple的错误,也可能是我的错误(我希望是这样)。但是目前,它阻止了我提供动态内容。

Apple的JavaScript函数正在使用我的URL生成正确的对象/嵌入标签,并且静态快照显示,如果我使用带有.mov扩展名的文件,则可以工作,但不能使用脚本,即使两者都提供相同的内容。

我正在做进一步的实验来断言Content-Type是否正确。 wget说的是,Safari的Web检查器似乎在说其他的话。



更新#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>


至少对我来说,这表明苹果确实有一个错误,那就是它不会加载动态内容。

同意?不同意?有什么想法吗?

我真的不知道这样做的“正确”方法是什么。

另一个实验,我将video/quicktime更改为video/mp4,并且适用于Safari版本。

我担心我可能不得不检测浏览器是否是Safari,是否可以处理VIDEO标签,如果可以,请使用.php选择代码而不是Apple的object / embed标签发出该黑客。

更新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代码和积分,请参见标记的答案。

最佳答案

这篇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();

}

关于javascript - 在Safari 8中播放.MOV文件的HTML —发生了什么变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31887262/

相关文章:

javascript - Selenium - ElementNotVisibleException。元素在 Safari 9.1 中可见,但在 10.1 中不可见?

javascript - 通过 DOMParser 渲染时,HTML 5 视频不会在 Safari 中显示(通过 innerHTML 渲染工作正常)

c# - Angularjs - 在表格上保存默认日期?

html - 如何在另一个 flex 元素内修复 flex 元素中的标题

javascript - 将文档附加到 iFrame

Javascript、jquery、ajax url 查询字符串重写

php - 如何正确加载和 HTML 嵌入受密码保护的文件?

javascript - 网络音频中的多个实例

javascript - Mysql Escape()时防止单引号

javascript - 按 ID 数组对对象数组进行排序