1

I use AVQueuePlayer in my app and I need to have an array with my tracks with type [AVPlayerItem]. Array must creates every time when TableView loads. Also I have an array "content" with elements in current folder to create a table view cells. How can I add these elements to array "playerQueue"?

class TableViewController: UITableViewController {
    
    var currentDirectory: String?
    var content: [String] = []
    var player: AVQueuePlayer!
    var playerQueue: [AVPlayerItem] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        reloadData()
    }
    
    func reloadData(needsReload: Bool = true) {
     
        if currentDirectory == nil {
            currentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
        }
        do {
            content = try FileManager.default.contentsOfDirectory(atPath: currentDirectory! )
        } catch {
            content = []
        }
        if needsReload {
            tableView.reloadData()
        }
    }
VyacheslavB
  • 181
  • 9

2 Answers2

1

If you have for example .m4v files in your documents folder you should find all of them then convert your file paths to AVPlayerItem ones (URL -> AVURLAsset -> AVPlayerItem) e.g.:

if let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
    if let content = try? FileManager.default.contentsOfDirectory(at: documentsUrl, includingPropertiesForKeys: nil) {
        let items = content
            .filter { $0.pathExtension == "m4v" }
            .map { AVURLAsset(url: $0)}
            .map { AVPlayerItem(asset: $0) }
        
        player = AVQueuePlayer(items: items)
        player?.play()
    }
}
iUrii
  • 11,742
  • 1
  • 33
  • 48
0

I think I get it. Need to create a support function:

func createPlayerQueue(with content: [String], from directory: String?) -> [AVPlayerItem] {
        var playerQueue: [AVPlayerItem] = []
        
        content.forEach { (url) in
            let fileUrl = directory! + "/" + url
            let asset = AVAsset(url: URL(fileURLWithPath: fileUrl))
            let item = AVPlayerItem(asset: asset)
            playerQueue.append(item)
        }
        
        return playerQueue
    }

And call it in func reloadData:

...
player = AVQueuePlayer(items: createPlayerQueue(with: content, from: currentDirectory))
...

It works.

VyacheslavB
  • 181
  • 9
  • You should filter your list of files by media extension for example to avoid the future problems with other kinds of files. – iUrii Jul 15 '20 at 14:53