Laravel 5 HTTP响应,M4V文件和iOS MPMoviePlayerViewController [英] Laravel 5 HTTP Response, M4V Files, and iOS MPMoviePlayerViewController

查看:252
本文介绍了Laravel 5 HTTP响应,M4V文件和iOS MPMoviePlayerViewController的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的情况令我难过,所以我正在寻找任何可以得到的帮助。

I have a situation that has me stumped so I'm looking for any help I can get.

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

I have a iOS App that uses MPMoviePlayerViewController to play M4V Video Files managed by a Laravel 5 site.

如果直接从Laravel 5 / public文件夹下载视频文件,那么视频文件的播放效果非常好(在iOS中)。但是,我通常会在Laravel 5的Storage Facade中存储和提供视频文件,因为我最终将使用S3和弹性转码器。

The video files play perfectly fine (in iOS) if they are directly downloaded from the Laravel 5 /public folder. However, I'm normally storing and serving the Video Files from Laravel 5's Storage Facade as I'm eventually going to use S3 and elastic transcoder.

这适用于FireFox QuickTime浏览器插件,VLC和其他流媒体视频客户端,但不是我们的iOS应用程序。

This works in FireFox with the QuickTime browser plugin, VLC, and other streaming video clients, but not our iOS App.

据我所知,MPMoviePlayerViewController对于HTTP响应如何挑剔正在格式化。我已经尝试了StreamedResponse,但这似乎没有帮助。

As far as I can tell the MPMoviePlayerViewController is being picky about how the HTTP Response is being formatted. I have tried StreamedResponse, but that does not seem to help.

所以例如以下从/ public文件夹中直接提取文件的URL可以在iOS上正常工作: / p>

So for example the following URL that pulls the file directly from the /public folder works fine from iOS:

http://172.16.160.1/video_ae9a7da0efa211e4b115f73708c37d67.m4v

但如果我使用Laravel 5从存储器中取出该文件,iOS将无法播放。

But if I use Laravel 5 to pull the file from Storage with this URL iOS will not play it.

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

注意iOS没有提供任何有意义的错误,以帮助调试它,但我很肯定它是如何通过Laravel 5进行我的HTTP响应。

Note iOS does not provide any meaningful errors, to help debug this, but I'm positive its how my HTTP Response is being made by Laravel 5.

这是我的路线:

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测试平台并查看握手的样子。

If I left out any supporting info please let me know and I'll post it. My next step may be to setup Wireshark testbed and see what the handshake looks like.

提前感谢您的帮助。 : - )

Thanks in advance for the help. :-)

推荐答案

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

It looks like I have the answer to my own question. The underlying cause was that Laravel 5 does not natively support HTTP byte-range requests when serving files.

这篇文章让我走上正轨:

This post located here got me on the right track:

立即调用MPMoviePlayerPlaybackDidFinishNotification

然后我发现了两张关于Laravel 5的帖子:

I then found two posts on doing this Laravel 5:

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

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

唯一退回是我无法使用存储Facade直接访问文件作为流。因此,此解决方案只能用于位于本地文件系统上的文件。

The only draw back is I can't use the Storage Facade to directly access the files as streams. So this solution can only be used for files located on the local filesystem.

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);
}

这篇关于Laravel 5 HTTP响应,M4V文件和iOS MPMoviePlayerViewController的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆