You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask分段视频流在iPad和iPhone上无法加载的问题求助

Flask流式MP4在苹果移动设备无法播放的问题排查与修复

问题根源

苹果移动设备(iPad/iPhone)的视频播放器会先发送Range: bytes=0-1的请求来获取视频元数据(时长、编码信息等),但你的Flask代码在解析这种带有明确结束位置的Range头时存在逻辑错误:

  • 原代码仅处理了bytes=xxx-这种无结束位置的请求,当遇到bytes=0-1时,计算出的end值是min(0+1MB, 文件大小-1),返回了远大于请求范围的数据,导致苹果设备无法解析元数据,最终播放器显示为空、无法启动播放。

修复方案

1. 修正Range头解析逻辑

区分两种Range格式:bytes=start-end(指定起止)和bytes=start-(仅指定起始),分别计算对应的end值,确保返回的数据严格匹配请求范围。

2. 精确读取请求范围内的数据

根据计算出的start和end读取对应长度的字节,而不是固定读取1MB数据。

修改后的Flask代码

替换原getMovie函数:

@stream.route("/movie/<id>/<ver>", methods=['GET'])
def getMovie(id, ver):
    range_header = request.headers.get("range")
    if not range_header:
        return Response("Requires Range header", status=400)
    
    videoPath: str = getMovieById(id).get("versions")[int(ver)][1]
    videoSize: int = os.stat(videoPath).st_size

    # 正确解析Range头,兼容两种格式:bytes=start- 或 bytes=start-end
    CHUNK_SIZE = 10**6  # 1MB,仅在未指定end时使用
    range_part = range_header.split("=")[-1]
    start_str, end_str = range_part.split("-", 1)
    
    start = int(start_str) if start_str else 0
    # 处理end的两种情况
    if end_str:
        end = int(end_str)
        end = min(end, videoSize - 1)  # 确保不超过文件边界
    else:
        end = min(start + CHUNK_SIZE, videoSize - 1)

    # 计算要返回的内容长度并精确读取数据
    content_length = end - start + 1
    with open(videoPath, "rb") as v:
        v.seek(start)
        data = v.read(content_length) 

    headers = {
        "Content-Range": f'bytes {start}-{end}/{videoSize}',
        "Accept-Ranges": "bytes",
        "Content-Length": str(content_length),
        "Content-Type": "video/mp4",
    }
    return Response(data, status=206, headers=headers, direct_passthrough=True)

额外检查点

  • MP4文件格式兼容性:苹果设备要求视频的moov元数据原子尽量在文件开头(而非末尾),可以用ffmpeg重新封装修复:
    ffmpeg -i input.mp4 -movflags faststart output.mp4
    
  • 编码格式:确保视频采用苹果原生支持的编码(H.264视频 + AAC音频),避免使用小众编码格式。

内容的提问来源于stack exchange,提问作者LennikGamez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 10:10:31