Laravel 5 HTTP 响应、M4V 文件和 iOS MPMoviePlayerViewController

2023-11-23

我遇到了一个让我感到困惑的情况,所以我正在寻求任何可以获得的帮助。

我有一个 iOS 应用程序,它使用 MPMoviePlayerViewController 来播放由 Laravel 5 站点管理的 M4V 视频文件。

如果直接从 Laravel 5 /public 文件夹下载视频文件,则可以完美播放(在 iOS 中)。不过,我通常会从 Laravel 5 的存储外观存储和提供视频文件,因为我最终将使用 S3 和弹性转码器。

这可以在 FireFox 中与 QuickTime 浏览器插件、VLC 和其他流视频客户端一起使用,但不适用于我们的 iOS 应用程序。

据我所知,MPMovies PlayerViewController 对 HTTP 响应的格式化方式很挑剔。我尝试过 StreamedResponse,但这似乎没有帮助。

例如,以下 URL 直接从 /public 文件夹中提取文件在 iOS 中工作正常:

http://172.16.160.1/video_ae9a7da0efa211e4b115f73708c37d67.m4v

但是如果我使用 Laravel 5 使用此 URL 从存储中提取文件,iOS 将不会播放它。

http://172.16.160.1/api/getfile/f444b190ef5411e4b7068d1890d109e8/video_ae9a7da0efa211e4b115f73708c37d67.m4v

注意 iOS 没有提供任何有意义的错误来帮助调试,但我确信 Laravel 5 是如何生成我的 HTTP 响应的。

这是我的路线:

Route::get('myapi/getfile/{filename?}', 'APIController@getfile')->where('filename', '(.*)');

这是我的控制器:

    public function getfile($filename)
{
    return $api = API::getfile($filename);
}

这是我的模型:

public static function getfile($filename) {
$file = Storage::disk('local')->get('Files/'.$filename);
return (new Response($file, 200))->header('Content-Type', 'video/mp4');
}

如果我遗漏了任何支持信息,请告诉我,我会发布它。我的下一步可能是设置 Wireshark 测试平台,看看握手是什么样子的。

先谢谢您的帮助。 :-)


看来我自己的问题有了答案。根本原因是 Laravel 5 在提供文件时本身不支持 HTTP 字节范围请求。

位于此处的这篇文章让我走上了正轨:

MPMoviePlayerPlaybackDidFinishNotification 立即被调用

然后我发现了两篇关于 Laravel 5 的文章:

http://laravel.io/forum/09-23-2014-how-to-support-http-byte-serving-in-file-streams

https://gist.github.com/m4tthumphrey/b0369c7bd5e2c795f6d5

唯一的缺点是我无法使用存储外观直接以流形式访问文件。因此该解决方案只能用于位于本地文件系统上的文件。

public static function getfile($filename) {

$size = Storage::disk('local')->size('files/'.$filename);
$file = Storage::disk('local')->get('files/'.$filename);
$stream = fopen($storage_home_dir.'files/'.$filename, "r");

$type = 'video/mp4';
$start = 0;
$length = $size;
$status = 200;

$headers = ['Content-Type' => $type, 'Content-Length' => $size, 'Accept-Ranges' => 'bytes'];

if (false !== $range = Request::server('HTTP_RANGE', false)) {
    list($param, $range) = explode('=', $range);
    if (strtolower(trim($param)) !== 'bytes') {
    header('HTTP/1.1 400 Invalid Request');
    exit;
    }
    list($from, $to) = explode('-', $range);
    if ($from === '') {
    $end = $size - 1;
    $start = $end - intval($from);
    } elseif ($to === '') {
    $start = intval($from);
    $end = $size - 1;
    } else {
    $start = intval($from);
    $end = intval($to);
    }
    $length = $end - $start + 1;
    $status = 206;
    $headers['Content-Range'] = sprintf('bytes %d-%d/%d', $start, $end, $size);
}

return Response::stream(function() use ($stream, $start, $length) {
    fseek($stream, $start, SEEK_SET);
    echo fread($stream, $length);
    fclose($stream);
    }, $status, $headers);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Laravel 5 HTTP 响应、M4V 文件和 iOS MPMoviePlayerViewController 的相关文章

随机推荐