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

将HLS推送到MediaPackage遇问题:401/404错误排查求助

问题描述
  • 流应用架构:EMX → EML → S3 → LAMBDA → EMP
  • 核心问题1:使用Python向MediaPackage HLS ingest端点发送PUT请求返回201成功,但ingress访问日志显示每个文件被记录两次,一次是401状态码,一次是201状态码
  • 核心问题2:将根清单发送到channel/{根清单名称}.m3u8时返回404;将EML直接连接EMP测试发现,请求格式为:所有文件使用channel_filename、TS文件使用channel_timestamp_sequence.ts、根清单使用.m3u8,但调整后MediaPackage origin端点仍对清单返回404
  • 相关Python代码:
def postStreamToMediaPackage(envVariables, fileName, content, contentType):
    mediaPackageUrl = envVariables["url"]
    username = envVariables["username"]
    password = envVariables["password"]
    ingestUrl = f"{mediaPackageUrl.rstrip('/channel')}/{fileName}" # not sure what mediapackage wants.

    response = requests.put(
        ingestUrl, data=content, headers={
            "ContentType": contentType
        }, auth=HTTPDigestAuth(username, password))
    if response.status_code != 201:
        print(
            f"Error ingesting file {fileName} to {ingestUrl}. error: {response.text}")
    return {"ingestUrl": ingestUrl, "fileName": fileName, "status": response.status_code}
解决方案

一、401+201重复日志问题

这是requests库HTTPDigestAuth的默认行为:库会先发送不带认证信息的请求,触发服务器返回401并携带Digest认证挑战,随后再发送包含正确认证信息的请求,最终返回201成功。该现象不影响实际 ingest 结果,属于正常流程。

如果需要消除日志中的401记录,可以手动构造Digest认证头:

  1. 先发送HEAD请求到目标URL,获取服务器返回的WWW-Authenticate头
  2. 用requests.auth._digest_auth模块生成认证头
  3. 将认证头加入PUT请求的headers中

不过多数场景下无需额外处理,最终 ingest 成功即可。

二、根清单404问题

你的代码存在两个关键错误,导致根清单无法被MediaPackage正确识别:

1. HTTP请求头键名错误

代码中设置的ContentType是错误的HTTP头名称,正确的头应为Content-Type(带横杠)。MediaPackage依赖这个头识别文件类型(HLS清单/TS分片),头名错误会导致服务器无法正确解析根清单。

2. Ingest路径构造错误

根据你测试的EML直接连接EMP的请求格式,根清单的正确路径是{mediaPackageUrl}/.m3u8,而不是去掉/channel后拼接自定义文件名。代码中mediaPackageUrl.rstrip('/channel')错误移除了路径中的channel部分,导致请求发送到了错误端点。

修正后的代码:

def postStreamToMediaPackage(envVariables, fileName, content, contentType):
    mediaPackageUrl = envVariables["url"]
    username = envVariables["username"]
    password = envVariables["password"]
    
    # 根据文件类型构造正确的ingest路径
    if fileName.endswith('.m3u8') and "root" in fileName:  # 假设根清单文件名包含root标识,可根据实际调整判断逻辑
        ingestUrl = f"{mediaPackageUrl.rstrip('/')}/.m3u8"
    else:
        ingestUrl = f"{mediaPackageUrl.rstrip('/')}/{fileName}"

    response = requests.put(
        ingestUrl, 
        data=content, 
        headers={
            "Content-Type": contentType  # 修正HTTP头名称
        }, 
        auth=HTTPDigestAuth(username, password)
    )
    
    if response.status_code != 201:
        print(f"Error ingesting file {fileName} to {ingestUrl}. error: {response.text}")
    
    return {"ingestUrl": ingestUrl, "fileName": fileName, "status": response.status_code}

额外注意事项

  • 根清单必须发送到{mediaPackageUrl}/.m3u8,不能带自定义文件名,MediaPackage会以此作为HLS流的根入口
  • TS分片和子清单的路径应为{mediaPackageUrl}/{文件名},文件名格式需与EML输出一致(如timestamp_sequence.ts)
  • 确保contentType参数正确:清单文件用application/vnd.apple.mpegurl,TS分片用video/MP2T

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 06:55:06