【问题标题】:Show Video on iPhone/iPad through PHP通过 PHP 在 iPhone/iPad 上显示视频
【发布时间】:2013-07-31 17:58:42
【问题描述】:

我想通过视频标签显示一个 mp4,视频的源 URL 是 YII 应用程序的 URL。我之前使用的是 Yii:app->request->sendFile 但视频无法在 iPad/iPhone 上运行,所以现在我尝试使用下面的代码自己发送标题但仍然无法正常工作。

$finfo = finfo_open(FILEINFO_MIME_TYPE);  
$file_path = "video.mp4";
$file_mime_type = finfo_file($finfo, $file_path);
$file_size = filesize($file_path);

header("HTTP/1.1 206 Partial Content");
header("Accept-Ranges: bytes");
header("Content-Type: $file_mime_type");
header("Content-Length: $file_size");
header("Content-Range: bytes 0-".($file_size-1)."/$file_size");
readfile($file_path);
exit;

我什至尝试从 http://mobiforge.com/developing/story/content-delivery-mobile-devices 实现 rangeDownload 函数,但问题是 $_SERVER['HTTP_RANGE'] 始终为 null,即使请求来自 iPhone/iPad。

我也在这里mp4 file through php not playing as html5 video 尝试过这个解决方案,但再次无济于事..

上面的代码适用于网络浏览器。此外,如果我直接从 iPhone/iPad 访问 .mp4,它也可以正常工作,所以视频本身不是问题

有什么帮助吗?

【问题讨论】:

  • 为什么不直接做一个header('Location: video.mp4'); ?
  • 如果$_SERVER['HTTP_RANGE'] 是NULL,为什么要发送部分内容响应?此外,如果您发送部分内容响应,为什么要发送整个文件?此外,您需要提供生成的响应标头,不仅是代码,还有实际响应。 HTTP 在这里顺便说一句:tools.ietf.org/html/rfc2616
  • 也试着看看,像 Fiddler2 这样的工具会发生什么。首先你可以看到 mp4 在 html 中会发生什么,然后是 php 会发生什么并比较 HTTP 请求标头。
  • @cmorrissey,它不适用于受密码保护的目录。

标签: php iphone video http-headers mp4


【解决方案1】:

您的问题可能有多种原因。
1)您无法创建正确的视频。尝试使用这样的字符串:

c:\utils\ffmpeg\bin\ffmpeg -i MVI_7386.MOV -acodec aac -ac 2 -strict experimental -b:a 160k -s 640x480 -vcodec libx264 -preset slow -profile:v baseline -level 30 -maxrate 10000000 -bufsize 10000000 -b:v 1200k -pix_fmt yuv420p -f mp4 -threads 2 -async 1 -vsync 1 -y video.ipad.mp4

2) 我使用this answer 对通过 php 发送视频稍作改动。这是我的 video.php 文件:

<?php
$path = './video.ipad.mp4';
if (file_exists($path)) {
  $size=filesize($path);
  $fm=@fopen($path,'rb');
  if(!$fm) {
    // You can also redirect here
    header ("HTTP/1.1 404 Not Found");
    die();
  }
  $begin=0;
  $end=$size;
  if(isset($_SERVER['HTTP_RANGE'])) {
    if(preg_match('/bytes=\h*(\d+)-(\d*)[\D.*]?/i',   
      $_SERVER['HTTP_RANGE'],$matches)){
      $begin=intval($matches[1]);
      if(!empty($matches[2])) {
        $end=intval($matches[2]);
      }
    }
  }
  if($begin>0||$end<$size) header('HTTP/1.1 206 Partial Content');
  else header('HTTP/1.1 200 OK');
  header("Content-Type: video/mp4");
  header('Content-Length:'.($end-$begin));
  header("Content-Range: bytes $begin-$end/$size");
  $cur=$begin;
  fseek($fm,$begin,0);
  while(!feof($fm)&&$cur<$end&&(connection_status()==0)) {
    print fread($fm,min(1024*16,$end-$cur));
    $cur+=1024*16;
    usleep(1000);
  }
  die();
}

而且html很简单:

<!doctype html>
<html>
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <title>test</title>
</head>
<body>
    <video controls>
        <source src="./video.php" type="video/mp4">
    </video>
</body>
</html>

你可以看到我做了什么here。

附注对不起视频。 :) 我找不到另一个。

【讨论】:

  • 嗨,德米特里,感谢您提供的有用答案。我已经按照您的方式设置了所有内容,但问题是您的演示可以在 iPad 上运行,而不是 the demo on my server。我正在使用相同的 PHP 脚本。标头几乎相同:我的共享主机服务器设置“连接:关闭”而不是“保持活动”,而且我有一个“缓存控制:max-age=2592000”。我禁用了 gzip,启用了 Accept-Ranges。设置了正确的 MIME 类型 video/mp4 .mp4。你能帮助我吗? (PS:当我找到解决方案后,我会将您的视频从我的服务器中删除,谢谢)
  • 这里是问题的完整描述:stackoverflow.com/questions/24042894/…
  • @EchtEinfachTV,我看不出这个视频有什么问题:echteinfach.tv/videos/test4.php 我创建了这个页面,第一个视频是 test4.php:kurilo.su/iphone/testvideo1.html 来自echteinfach.tv/test/ipad/test-headers.php 的视频是第二个视频在我的测试页面上,它不起作用。我试图将它放在我的服务器上并且它可以工作(我的测试页面上的第三个视频)。如我所见,您有两次 Accept-Ranges:bytes 标头。我不知道您如何两次创建相同的标题。据我了解,这并不容易。 :) 但我认为这可能是问题的根源。
  • 感谢您的回复并在您的服务器上测试脚本,非常感谢!正如我所见,embedded videos(PHP 从我的服务器加载的视频文件)也没有出现在 iPad 上。但是您上传到服务器的第三个视频(直接嵌入也适用于我的服务器)。 # Accept-Ranges 由 htaccess 加上 PHP 脚本设置。我从 htaccess 中删除了它,但它没有改变任何东西。我的主机将服务器设置为“连接:关闭”,我无法将其更改为“保持活动状态”。您认为这可能是问题所在吗?
  • 您可以尝试将PHP scripts(将.php 替换为.txt 以下载它们)上传到您的测试文件夹吗?然后我们可以看看它们是否在您的服务器上工作。谢谢你:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-07
相关资源
最近更新 更多