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

使用自定义请求在AVPlayer中无法播放视频的问题排查

为AVPlayer添加自定义请求头后无法播放视频的问题排查

问题描述

我尝试给AVPlayer的请求添加自定义请求头,使用了自定义scheme:

let asset = AVURLAsset(url: URL(string: "mycustomscheme://tungsten.aaplimg.com/VOD")!, options: nil)

结果请求失败,触发了shouldWaitForLoadingOfRequestedResource代理方法。

在这个代理方法中,我发起了自定义请求并成功从服务器获取到数据,但AVPlayer仍然无法播放视频。我的代理代码如下:

func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool { 
    resourceLoader.delegateQueue?.async { 
        var request: URLRequest? = loadingRequest.request 
        request?.url = self.url 
        // 添加请求头
        request?.setValue(HeadersForWS.DeviceOS, forHTTPHeaderField: HeadersForWS.DeviceType) 
        request?.setValue(Utility.getUserId(), forHTTPHeaderField:HeadersForWS.UserId ) 
        
        if let aRequest = request { 
            let session = URLSession(configuration: .default, delegate: self, delegateQueue: nil) 
            session.dataTask(with: aRequest as URLRequest) { (data, response, error) in 
                guard let data = data else { 
                    try? loadingRequest.finishLoading() 
                    return 
                } 
                loadingRequest.dataRequest?.respond(with: data) 
                loadingRequest.finishLoading() 
            }.resume() 
        } 
    } 
    return true 
}

将获取到的数据保存为sample.mp4文件后可以正常播放,说明数据本身是没问题的,那问题可能出在哪里呢?


可能的问题及解决办法

  • 未向AVPlayer传递响应元信息
    AVPlayer不仅需要视频数据,还需要服务器返回的响应头(比如Content-Type、Content-Length这类关键信息)来识别数据类型、规划播放逻辑。你现在只把数据传给了dataRequest,但没将服务器返回的response赋值给loadingRequest.response,导致AVPlayer无法正确解析数据。

    修改代码,在拿到有效响应和数据后,先设置响应信息:

    guard let data = data, let response = response else {
        if let error = error {
            loadingRequest.finishLoading(with: error)
        } else {
            loadingRequest.finishLoading()
        }
        return
    }
    loadingRequest.response = response // 新增这一行,传递响应元信息
    loadingRequest.dataRequest?.respond(with: data)
    loadingRequest.finishLoading()
    
  • URLSession实例重复创建+代理处理不规范
    你每次请求都新建URLSession实例,还设置了delegate: self,如果你的类没有正确实现URLSessionDelegate相关方法(比如HTTPS证书验证),可能会出现隐性错误。建议复用一个全局的URLSession实例,同时确保代理回调逻辑完整。

  • 数据传递方式不符合流式播放要求
    如果视频文件较大,一次性把所有数据传给respond(with: data)可能超出AVPlayer的处理预期。可以尝试分块传递数据,或者确保dataRequest的状态被正确设置。另外要注意先判断loadingRequest.dataRequest是否为nil,避免空对象调用。

  • 错误处理不完整
    当前代码在data为空时直接调用finishLoading(),但如果请求过程中有error产生,应该调用finishLoading(with: error)告知AVPlayer具体错误原因,这有助于你排查问题:

    if let error = error {
        loadingRequest.finishLoading(with: error)
        return
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:11:41