python - 使用 Flask 提供 .mp4 文件并在 Objective-C 应用程序上播放会导致管道损坏且无法播放

标签 python objective-c video flask avplayer

我正在尝试在我的 iOS 应用程序上播放由 Flask Web 应用程序提供的视频。虽然我可以播放使用“传统”Web 服务器(如 Apache)提供的任何视频,但我无法播放 Flask 提供的视频。相关代码如下:

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,视频会正确加载。

我该如何解决我的问题?

提前谢谢您!

最佳答案

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

我按照 https://codeburst.io/the-taste-of-media-streaming-with-flask-cdce35908a50 中的示例进行操作,Flask 服务器代码需要使用“部分内容”(HTTP 状态代码 206)构建响应,并且需要处理请求中的“范围” header 。相关代码如下:

  1. 在 Flask 应用 after_request 中添加“Accept-Ranges”,以便客户端知道支持“range”:
@app.after_request
def after_request(response):
    response.headers.add('Accept-Ranges', 'bytes')
    return response
  • 在提供 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 客户端以及 Chrome、Firefox 浏览器的 .mp4 文件。

    关于python - 使用 Flask 提供 .mp4 文件并在 Objective-C 应用程序上播放会导致管道损坏且无法播放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50001356/

    相关文章:

    python - 男人脸和女人脸的区别

    python - 如何让程序根据给定的用户输入再次运行?

    ios - UIScrollView "out of frame"触摸区域无响应

    qt - 如何在 QML 的最后一帧暂停视频?

    python - 在 Python 中生成数字列表及其负数

    python - 在Python/matplotlib中绘制具有足够刻度空间的点图?

    ios - 为什么在 iOS7 上触摸 UISearchBar 时,我的 UISearchBar 和 UITableView Cell Header 之间会出现间隙?

    ios - -[NSCalendar dateFromComponents :] crashes with SIGABRT

    javascript - 在上传到远程网站期间缩小/调整视频大小

    c - libavcodec : how to encode with h264 codec , 与 mp4 容器使用可控帧率和比特率(通过 c 代码)