Search code examples
iosswiftaudioavaudioplayer

AVAudioPlayer stops playing after playing a lot of audio files: kAudio_TooManyFilesOpenError


I encountered a similar problem mentioned here. From his findings, apparently, there's a limit to how many files you can play per session.

I tried the method the author posted, but I guess his issue was more to do with simultaneous playback.

What I'm trying to achieve is, I have tons of mp3 files (over 450 files), I'm trying to play each file at a time.

here's the code:

internal class NarrationPlayer {
    public var player: AVAudioPlayer?
    var narrationFile = [URL]()

    deinit {
        print("deinit NarrationPlayer")
    }

    internal func initNarration() {
        if player != nil {
            player = nil
        }
    }

    public func loadNarration(_ filename: String) {

        if narrationFile.count >= 1 {
            narrationFile.removeLast(1)
        }

        let url = Bundle.main.url(forResource: filename, withExtension: "mp3")

        if (url == nil) {
            print("Could not find file: \(filename)")
            return
        }

        do {

            narrationFile.append(url!)
            var error: NSError? = nil
            do {

                player = try AVAudioPlayer(contentsOf: narrationFile[narrationFile.count - 1])

            } catch let error1 as NSError {
                error = error1
                player = nil
            }
            if let player = player {
                player.prepareToPlay()
                player.volume = 1
                player.play()
            } else {
                print("Could not create audio player: \(error!)")
            }

        } catch let error as NSError {
            print("error retrieving data: \(error)")
        }

    }

    internal func clearNarration() {
        print("[clearNarration]")

        if let player = player {
            player.stop()
        }
        narrationFile.removeAll()
        player = nil
    }
}

after a certain number of files, it stops playing with the following error:

Could not create audio player: Error Domain=NSOSStatusErrorDomain Code=-42

AVAudioPlayer works fine until the app hits that threshold of 49 files (or whatever the threshold is), and the problem is not dependent on the actual file, but the total number of files. I've tried SwiftySound as well since the author of that post was using it, but the result was the same.

Is there any way to clean the memory of the loaded files, or can anyone recommend me other ways to load and play a lot of mp3 files?


Solution

  • I tried everything I could find on the internet.

    osstatus was a big help. Apparently, the default limit of audio files AVAudioPlayer can handle is 256.

    In order to change this, I created a function and called it in AppDelegate, func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?)

    func extendAudioFileLimit() {
        var limit:rlimit = rlimit()
        getrlimit(RLIMIT_NOFILE, &limit)
        // change this value to suit your needs
        limit.rlim_cur = 500
        setrlimit(RLIMIT_NOFILE, &limit)
        getrlimit(RLIMIT_NOFILE, &limit)
    }