iOS HLS视频播放

2024-12-05  本文已影响0人  OrrHsiao

采用系统AVPlayer组件来播放,对于需要手动处理加密的hls视频,通过AVAssetResourceLoader拦截代理方法来手动代理系统的m3u8文件下载、解密key下载等。
苹果的hls有自己的标准,注意参考标准来实现,否则可能播不出来,而且很难排查原因,参考文档:https://developer.apple.com/documentation/http-live-streaming/hls-authoring-specification-for-apple-devices?language=objc

我们如何去主动控制播放过程中m3u8文件下载、解密key下载等逻辑呢?

  1. 通常情况下,只要你设置了正确的播放url,AVAssetResourceLoader怎么都不会调用下面的代理方法,即使url报错也不会,无法访问也不会。不知道为什么这么设计😊
    想要触发下面的代理调用,只有把设置进去的url改成非url的形式才行,比如去掉url前面http/https,这样系统就会调用下面代理方法了,就有操作空间了
func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool
  1. 通过let url = loadingRequest.request.url?.absoluteString拿到系统当前要执行的url,判断url的后缀来实现逻辑扭转。
  2. 判断如果是播放url
    // 自己下载m3u8文件,
    下载完成block里面的代码: {
      // 下载完成后塞给系统
      loadingRequest.dataRequest?.respond(with: newData!)
      // 通知系统请求结束
      loadingRequest.finishLoading()
    }
    // 通知系统等待
    return true
  1. 如果你的hls视频加密是自定义的,比如秘钥下载完是加密的,那就要在m3u8文件里面#EXT-X-KEY:METHOD:后面的URI给改成非url,这样系统就会调用这个代理,你自己去处理秘钥下载然后解密的逻辑,自己下载完以上面同样方式塞给系统。

  2. 视频切片文件下载的逻辑不能用上面方式来实现,采用同样方式,塞Data给系统,系统也不会播放,原因未知。系统只接受url重定向。
    因此碰到因为音视频编码问题,直接播放视频切片文件播放不了的时候,目前我采用的是本地服务器的形式实现,即把切片的url给改成非url,然后采用上面同样的方式,手动把视频下载下来,如果加密了还需要解密,然后使用ffmpeg转码,转码完成后,如果m3u8包含加密的,还需要再加密回去,(因为AVAssetResourceLoader解密逻辑是内部进行的),然后启动本地服务器,把url重定向到本地视频切片文件url

    // 下载切片文件完成回调: {
      let localUrl = "http://localhost:port/" + fileName
      if let u = URL(string: localUrl) {
        let redirect = URLRequest(url: u)
        loadingRequest.redirect = redirect
        //设置需要重定向
        loadingRequest.response = HTTPURLResponse(url: u, statusCode: 301, httpVersion: nil, headerFields: nil)
        loadingRequest.finishLoading()
       }
    }
上一篇 下一篇

猜你喜欢

热点阅读