使用Flask提供.mp4文件并在Objective-C应用上播放会导致管道破裂且无法播放 [英] Serving a .mp4 file with Flask and playing it on an Objective-C app causes Broken pipe and no play

查看:172
本文介绍了使用Flask提供.mp4文件并在Objective-C应用上播放会导致管道破裂且无法播放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在iOS应用程序上播放Flask网络应用程序提供的视频.虽然我可以播放常规" Web服务器(例如Apache)上提供的任何视频,但不能播放Flask上提供的视频.这是相关代码:

I'm trying to play a video that is served by a Flask web application on my iOS application. While I can play any video served with a "conventional" web server (like Apache), I can't play the video served by Flask. Here is the relevant code:

Objective-C

Objective-C

NSURL *videoURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@",videourltemp]];
AVPlayer *player = [AVPlayer playerWithURL:videoURL];

playerViewController.player = player;
[self.view addSubview:playerViewController.view];
[self.navigationController pushViewController:playerViewController animated:YES];

Python

from flask import Response, ...

def get_img(imgid):
    # private code hidden - file["path"] contains the path relative to /root/media_assets directory

    return Response(open("/root/media_assets/" + file["path"], "rb"), mimetype="video/mp4")

旁注:如果我尝试从浏览器访问URL,则表明视频已正确加载.

Sidenote: if I try to reach my URL from a browser, the video is correctly loaded.

我该如何解决我的问题?

How could I solve my problem?

提前谢谢!

推荐答案

我遇到了相同的问题,最终发现真正的问题是视频播放器客户端(至少在Objective-C iOS中)使用了范围"标头在响应中(您可以打印出Flask request.headers进行检查).换句话说,流传输实际上是使用HTTP中的范围"支持来实现的.

I encountered the same problem and eventually found that the real issue is that the video player client (in Objective-C iOS at least) uses the "range" header in the response (you can print out Flask request.headers to check). In other words, the streaming is really implemented using "range" support in HTTP.

我在,Flask服务器代码需要使用部分内容"(HTTP状态代码206)构建响应,并需要在请求.相关代码如下:

I followed examples at https://codeburst.io/the-taste-of-media-streaming-with-flask-cdce35908a50, the Flask server code needs to build response using "partial content" (HTTP status code 206) and needs to process the "range" header in the request. The related code looks like this:

  1. 在Flask应用程序after_request中添加接受范围",以便客户端知道支持范围":

@app.after_request
def after_request(response):
    response.headers.add('Accept-Ranges', 'bytes')
    return response

  1. 在提供mp4文件的函数中,假设文件路径为"full_path":

    file_size = os.stat(full_path).st_size
    start = 0
    length = 10240  # can be any default length you want

    range_header = request.headers.get('Range', None)
    if range_header:
        m = re.search('([0-9]+)-([0-9]*)', range_header)  # example: 0-1000 or 1250-
        g = m.groups()
        byte1, byte2 = 0, None
        if g[0]:
            byte1 = int(g[0])
        if g[1]:
            byte2 = int(g[1])
        if byte1 < file_size:
            start = byte1
        if byte2:
            length = byte2 + 1 - byte1
        else:
            length = file_size - start

    with open(full_path, 'rb') as f:
        f.seek(start)
        chunk = f.read(length)

    rv = Response(chunk, 206, mimetype='video/mp4', content_type='video/mp4', direct_passthrough=True)
    rv.headers.add('Content-Range', 'bytes {0}-{1}/{2}'.format(start, start + length - 1, file_size))
    return rv

在我的测试中,以上Flask代码可与iOS Objective-C客户端以及适用于.mp4文件的Chrome,Firefox浏览器一起使用.

In my testing, the above Flask code works with iOS objective-C client as well as Chrome, Firefox browsers for .mp4 files.

这篇关于使用Flask提供.mp4文件并在Objective-C应用上播放会导致管道破裂且无法播放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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