ioshttp-live-streamingavassetavurlasset

AVAssetResourceLoaderDelegate and HLS does not work?


For me it's not working with "m3u8" url both on Simulator and real device (iPhone 5S). In the same time, Apple demo working good, but I don't see any difference. And with other url extensions it's ok (e.g., "m3u9" on the end of the url)

import UIKit
import AVKit
import AVFoundation

class ViewController: UIViewController, AVAssetResourceLoaderDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        // if I change m3u8 to different file extension, it's working good
        let url = NSURL(string: "cplp://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8") 

        let asset = AVURLAsset(URL: url!, options: nil)
        asset.resourceLoader.setDelegate(self, queue: dispatch_queue_create("AVARLDelegateDemo loader", nil))

        let item = AVPlayerItem(asset: asset)
        let player = AVPlayer(playerItem: item)
        player.play()
    }

    func resourceLoader(resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool {

        NSLog("This method is never called in case of m3u8 url")

        return true
    }
}

Solution

  • Ok, I've found how to fix it, but still don't understand why it's happening only for "m3u8" links.

    Need to save strong player or, at least, item reference. Thanks, Apple, for the docs. :sarcasm:

    import UIKit
    import AVKit
    import AVFoundation
    
    class ViewController: UIViewController, AVAssetResourceLoaderDelegate {
        var player: AVPlayer! // <-- the fix
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // if I change m3u8 to different file extension, it's working good
            let url = NSURL(string: "cplp://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8") 
    
            let asset = AVURLAsset(URL: url!, options: nil)
            asset.resourceLoader.setDelegate(self, queue: dispatch_queue_create("AVARLDelegateDemo loader", nil))
    
            let item = AVPlayerItem(asset: asset)
            player = AVPlayer(playerItem: item) // <-- the fix
            player.play()
        }
    
        func resourceLoader(resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool {
    
            NSLog("This method is never called in case of m3u8 url")
    
            return true
        }
    }