互联网不可用时无法播放下载的 HLS 内容
Posted
技术标签:
【中文标题】互联网不可用时无法播放下载的 HLS 内容【英文标题】:Unable to play downloaded HLS content while internet is not available 【发布时间】:2020-03-10 01:30:30 【问题描述】:我正在下载和播放 HLS 内容,要下载 HLS,我正在使用以下代码
func downloadTask()
let videoUrl = URL(string: "https://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8")!
configuration = URLSessionConfiguration.background(withIdentifier: downloadIdentifier)
downloadSession = AVAssetDownloadURLSession(configuration: configuration!, assetDownloadDelegate: self, delegateQueue: OperationQueue.main)
let documentsDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
destinationUrl = documentsDirectoryURL.appendingPathComponent(videoUrl.lastPathComponent)
var urlComponents = URLComponents(
url: videoUrl,
resolvingAgainstBaseURL: false
)!
urlComponents.scheme = "https"
do
let asset = try AVURLAsset(url: urlComponents.url!)
asset.resourceLoader.setDelegate(self, queue: DispatchQueue(label: "com.example.AssetResourceLoaderDelegateQueue"))
if #available(ios 10.0, *)
assetDownloadTask = downloadSession!
.makeAssetDownloadTask(
asset: asset,
assetTitle: "RG-TVVideo",
assetArtworkData: nil,
options: nil
)
APP_DELEGATE.isProgressRunning = true
assetDownloadTask?.resume()
else
// Fallback on earlier versions
catch print("Erorr while parsing the URL.")
下载完成
func urlSession(_ session: URLSession, assetDownloadTask: AVAssetDownloadTask, didFinishDownloadingTo location: URL)
if #available(iOS 11.0, *)
let storageManager = AVAssetDownloadStorageManager.shared()
let newPolicy = AVMutableAssetDownloadStorageManagementPolicy()
newPolicy.expirationDate = Date()
newPolicy.priority = .important
let baseURL = URL(fileURLWithPath: NSHomeDirectory())
let assetURL = baseURL.appendingPathComponent(location.relativePath)
storageManager.setStorageManagementPolicy(newPolicy, for: assetURL)
UserDefaults.standard.set(location.relativePath, forKey: "videoPath")
strDownloadStatus = "5"
let dictVideoInfo = ["strDownloadStatus" : "5","VideoID":self.strID]
// Here I am Storing Downloaded location in to database
DBManager.shared.updateVideoStatus(strVideoID: APP_DELEGATE.arrTempVideoIds.object(at: 0) as! String, strStatus: "5", strSavePath: location.relativePath) (status) in
DispatchQueue.main.async
NotificationCenter.default.post(name: NSNotification.Name.init("UpdateProgress"), object: self.percentageComplete, userInfo: dictVideoInfo)
现在我正在尝试从存储在数据库中的位置获取视频路径并尝试使用以下代码离线播放(没有互联网)
func setLocalPlayer(strDownloadPath: String)
let strDownloadPath = “”
//Getting path from database
DBManager.shared.getDownloadedPath(videoID: VideoID) (strPath) in
strDownloadPath = strPath
activityIndicator.isHidden = false
let baseURL = URL(fileURLWithPath: NSHomeDirectory())
let assetURL = baseURL.appendingPathComponent(strDownloadPath)
let asset = AVURLAsset(url: assetURL)
// if let cache = asset.assetCache, cache.isPlayableOffline
// let videoAsset = AVURLAsset(url: assetURL)
asset.resourceLoader.preloadsEligibleContentKeys = true
asset.resourceLoader.setDelegate(self, queue: DispatchQueue(label: "com.example.AssetResourceLoaderDelegateQueue"))
let playerItem = AVPlayerItem(asset: asset)
avPlayer = AVPlayer(playerItem: playerItem)
avPlayerLayer = AVPlayerLayer()
avPlayerLayer.frame = CGRect(x: 0, y: 0, width: playerContainer.frame.width, height: playerContainer.frame.height)
avPlayerLayer.videoGravity = .resize
avPlayerLayer.player = avPlayer
playerContainer.layer.addSublayer(avPlayerLayer)
let interval = CMTime(seconds: 0.01, preferredTimescale: CMTimeScale(NSEC_PER_SEC))
timeObserver = avPlayer?.addPeriodicTimeObserver(forInterval: interval, queue: DispatchQueue.main, using: elapsedTime in
self.updateVideoPlayerState()
if self.avPlayer != nil
self.bufferState()
)
self.slider.setThumbImage(UIImage(named: "slider_dot"), for: UIControl.State.normal)
resetTimer()
avPlayer.play()
isPlaying = true
//
注意:此代码在互联网开启时工作正常
我参考了以下链接
https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/MediaPlaybackGuide/Contents/Resources/en.lproj/HTTPLiveStreaming/HTTPLiveStreaming.html
https://assist-software.net/snippets/how-play-encrypted-http-live-streams-offline-avfoundation-ios-using-swift-4
Downloading and playing offline HLS Content - iOS 10
请指导我做错了什么。
谢谢
【问题讨论】:
嗨@Khush,我知道我迟到了,但你有哪个错误?您可以使用命令检查 AVPlayer 错误:po avPlayer.currentItem?.errorLog()
【参考方案1】:
好吧,我不知道这是否是你的错误,但为了进一步阅读:
不要这样做newPolicy.expirationDate = Date()
这是一个错误。根据Advances in HTTP Live Streaming 2017 WWDC session,它将尽快删除您的文件。
在播放离线播放之前,您可以在“设置”->“常规”->“存储”->“我的应用”中检查它是否仍在您的设备上
到期日期属性存在,以防您的资产在某个时候 不再有资格被播放。例如,您可能会发现 您可能处于某个特定节目可能要离开的情况 您的目录,您不再有权流式传输它。
如果是这种情况,您可以设置到期日期,它会有所增加 在删除队列中。所以,使用它是相当简单的。
【讨论】:
以上是关于互联网不可用时无法播放下载的 HLS 内容的主要内容,如果未能解决你的问题,请参考以下文章