在 AVPlayer 中,可以使用 AVAssetResourceLoaderDelegate 来处理受保护的 HLS 流。当播放器需要获取资源时,会调用 resourceLoader(_:shouldWaitForLoadingOfRequestedResource:) 方法,我们可以在这个方法中获取到请求的 URL,并根据业务逻辑判断是否需要更新 token。
更新 token 的具体方法可以根据业务逻辑进行调整,这里给出一个示例代码:
class HLSResourceLoaderDelegate: NSObject, AVAssetResourceLoaderDelegate {
var token: String
init(token: String) {
self.token = token
}
func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool {
guard let url = loadingRequest.request.url, url.scheme == "https" else {
// 非受保护的流,交由系统处理
return false
}
// 根据业务逻辑判断是否需要更新 token
let updatedURL = url.appendingQueryParameter(name: "token", value: token)
let newRequest = URLRequest(url: updatedURL)
loadingRequest.redirect = newRequest
// 继续处理请求
loadingRequest.continueLoading()
return true
}
}
extension URL {
func appendingQueryParameter(name: String, value: String) -> URL {
guard var urlComponents = URLComponents(url: self, resolvingAgainstBaseURL: false) else { return self }
var queryItems = urlComponents.queryItems ?? []
queryItems.append(URLQueryItem(name: name, value: value))
urlComponents.queryItems = queryItems
return urlComponents.url ?? self
}
}
在创建 AVPlayerItem 时,需要指定资源加载器的代理,示例代码如下:
let hlsURL = URL(string: "https://example.com/hls.m3u8")!
let asset = AVURLAsset(url: hlsURL)
let resourceLoaderDelegate = HLSResourceLoaderDelegate(token: "initial