stackich
stackich

Reputation: 5207

Issues when previewing .flac files with AVPlayerViewController

I am using AVPlayerViewController to preview all formats of audio in my app.
Everything was working fine but after I added support for .flac files, it became buggy.

Sometimes the player loads the video correctly, and sometimes does not. This never happens for other formats, for example .mp3.

This is how it looks like when video is loaded correctly and when it is not (first image is when everything is fine):
1image 2image

The logic is the same for all audio formats:

private lazy var _player = AVPlayer()
private lazy var _playerViewController = AVPlayerViewController()

func playAudio(correctUrl: URL) {
    var item = AVPlayerItem(url: correctUrl)
    self._player.replaceCurrentItem(with: item)
    self._playerViewController.player = self._player
    self.registerForAVPlayerNotifications()
    self._playerViewController.player?.play()
}

Upvotes: 0

Views: 176

Answers (1)

Mr.SwiftOak
Mr.SwiftOak

Reputation: 1834

Try loading asset as AVURLAsset and check the possible loading error.

func loadAsset(_ streamUrl: URL,completionAfterLoad: ((AVPlayerItem) -> Void)? = nil) {
    let asset = AVURLAsset(url: streamUrl, options: nil)
    let assetKeys = [
        "playable",
        "tracks",
        "duration"
    ]
    // Create a new AVPlayerItem with the asset and an
    // array of asset keys to be automatically loaded
    
    asset.loadValuesAsynchronously(forKeys: assetKeys, completionHandler: {
        
        DispatchQueue.main.async {
                var error: NSError? = nil
                var status = asset.statusOfValue(forKey: "playable", error: &error)
                switch status {
                case .loaded:
                    print("loaded\n\(String(describing: error?.localizedDescription))")
                case .failed:
                    print("failed\n\(String(describing: error?.localizedDescription))")
                case .cancelled:
                    print("cancelled\n\(String(describing: error?.localizedDescription))")
                default:
                    print("default\n\(String(describing: error?.localizedDescription))")
                }
                
                status = asset.statusOfValue(forKey: "tracks", error: &error)
                switch status {
                case .loaded:
                    print("loaded\n\(asset.tracks)")
                case .failed:
                    print("failed\n\(String(describing: error?.localizedDescription))")
                case .cancelled:
                    print("cancelled\n\(String(describing: error?.localizedDescription))")
                default:
                    print("default\n\(String(describing: error?.localizedDescription))")
                }
                // If loading of duration fails, stream plylist is in wrong format (e.g. missing version number etc.)
                status = asset.statusOfValue(forKey: "duration", error: &error)
                switch status {
                case .loaded:
                    print("loaded\n\(asset.tracks)")
                    
                case .failed:
                    print("failed\n\(String(describing: error?.localizedDescription))")
                    
                case .cancelled:
                    print("cancelled\n\(String(describing: error?.localizedDescription))")
                default:
                    print("default\n\(String(describing: error?.localizedDescription))")
                }
                
                print("tracks\n\(asset.tracks(withMediaType: .audio))")
                
                let playerItem = AVPlayerItem(asset: asset, automaticallyLoadedAssetKeys: assetKeys)
                completionAfterLoad?(playerItem) // perform any action to happen after playlist is completed loading
        }
    })
}

// Usage:
let avPLayer = AVPlayer()
let url = URL(string: "")!
loadAsset(url,completionAfterLoad: { playerItem in
  avPLayer.replaceCurrentItem(with: playerItem)
})

Upvotes: 0

Related Questions