Python 使用烧瓶提供.mp4文件并在Objective-C应用程序上播放会导致管道破裂和无法播放
我正在尝试播放由iOS应用程序上的Flask web应用程序提供服务的视频。虽然我可以播放“传统”web服务器(如Apache)提供的任何视频,但我不能播放Flask提供的视频。以下是相关代码: 目标-CPython 使用烧瓶提供.mp4文件并在Objective-C应用程序上播放会导致管道破裂和无法播放,python,objective-c,video,flask,avplayer,Python,Objective C,Video,Flask,Avplayer,我正在尝试播放由iOS应用程序上的Flask web应用程序提供服务的视频。虽然我可以播放“传统”web服务器(如Apache)提供的任何视频,但我不能播放Flask提供的视频。以下是相关代码: 目标-C NSURL *videoURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@",videourltemp]]; AVPlayer *player = [AVPlayer playerWithURL:videoURL]; play
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];
蟒蛇
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,则视频已正确加载
我怎样才能解决我的问题
提前谢谢你 您有两个选择:
返回响应(文件(“/root/media\u assets/”+文件[“path”]),direct\u passthrough=True)
我遇到了同样的问题,最终发现真正的问题是视频播放器客户端(至少在Objective-CIOS中)在响应中使用了“range”头(您可以打印出Flask
request.headers
进行检查)。换句话说,流实际上是使用HTTP中的“范围”支持实现的
我在上进行了示例,Flask服务器代码需要使用“部分内容”(HTTP状态代码206)构建响应,并且需要处理请求中的“范围”头。相关代码如下所示:
file\u size=os.stat(完整路径).st\u size
开始=0
长度=10240#可以是您想要的任何默认长度
range\u header=request.headers.get('range',None)
如果范围_标题:
m=重新搜索(“([0-9]+)-([0-9]*)”,范围(U标题)#示例:0-1000或1250-
g=m.群()
字节1,字节2=0,无
如果g[0]:
字节1=int(g[0])
如果g[1]:
字节2=int(g[1])
如果字节1<文件大小:
开始=字节1
如果字节2:
长度=字节2+1-字节1
其他:
长度=文件大小-开始
打开(完整路径,'rb')作为f:
f、 搜索(开始)
chunk=f.read(长度)
rv=响应(chunk,206,mimetype='video/mp4',content\u type='video/mp4',direct\u passthrough=True)
add('Content-Range','bytes{0}-{1}/{2}'。格式(start,start+length-1,文件大小))
返回rv
在我的测试中,上述Flask代码适用于iOS objective-C客户端以及用于.mp4文件的Chrome、Firefox浏览器。这两种解决方案都无法解决我的问题。第一个使我的视频加载无休止,第二个并没有改变问题。如果有帮助的话,我已经看到,不仅iOS,Mac版的Safari都有这个问题,而任何操作系统(包括macOS)和Firefox版的Chrome都没有问题。
from flask import stream_with_context, Response
@app.route('/stream_data')
def stream_data():
def generate():
with open("/root/media_assets/" + file["path"], "rb") as f:
while True:
chunk = ... # read each chunk or break if EOF
yield chunk
return Response(stream_with_context(generate()), mimetype="video/mp4")
@app.after_request
def after_request(response):
response.headers.add('Accept-Ranges', 'bytes')
return response
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