title: How to play multiple Audio Files simultaneously using AVPlayer?
body: <p>I am trying to play multiple audio files using 2 AVPlayer instances, but one of the player stops for a fraction of a second rather than playing all audio files simultaneously. 
  The logic of the program is as follows:    </p>
  
  <p><code>var player: AVPlayer?</code> will stream an audio file from my database. On its own is playing perfectly.    </p>
  
  <p><code>fileprivate var countPlayer: AVPlayer?</code> plays the count number of the current item being played by <code>var player</code>. The count is a sequence of 1 to 8 and for each digit I am storing/sandobxing a .wav file locally such as 1.wav, 2.wav...8.wav. </p>
  
  <p>When current time of <code>var player</code> is at a certain time, <code>countPlayer</code> is triggered and it plays one of the local file 1.wav, 2.wav..etc. </p>
  
  <p>The problem is that when the <code>var countPlayer</code> starts playing, it causes the background AVPlayer, namely <code>var player</code> to stop for a fraction of a second, similar to what's described in this comment:</p>
  
  <p><a href="https://stackoverflow.com/questions/6193844/play-multiple-audio-files-with-avplayer#comment7213305_6193844">Play multiple Audio Files with AVPlayer</a></p>
  
  <pre><code>   var player: AVPlayer? //plays the song
     fileprivate var countPlayer: AVPlayer?  // plays the count number of song
  
  
  
     private func addBoundaryTimeObserver(tableIndexPath: IndexPath) {
  
  
      let mediaItem = mediaArray[tableIndexPath.row]
  
      guard let url = URL(string: mediaItem.mediaAudioUrlStringRepresentation ?? "") else {return}
      let playerItem = AVPlayerItem(url: url)
      player = AVPlayer(playerItem: playerItem)
  
      var timesToTransverse = [NSValue]()
  
      //convert string representation of times elements to array
      let timesRecorded: [String] = mediaItem.timesRecorded.components(separatedBy: ",")
  
      // Build boundary times from arrayOfBeats keys
      let timeDoubles: [Double] = timesRecorded.compactMap {timeString in
          if let second = Double("\(timeString)") {
              return second
          }
          return nil
      }
  
      guard timeDoubles.count &gt; 0 else {return} //unexpected
  
       timesToTransverse = timeDoubles.map { second in
          let cmtime = CMTime(seconds: second, preferredTimescale: CMTimeScale(NSEC_PER_SEC))
          return NSValue(time: cmtime)
      }
  
      guard timesToTransverse.count != 0 else {return}
  
          guard let playerCell = tableView.cellForRow(at: IndexPath(row: 0, section: 0)) as? PlayerCell else {return}
  
         startTime = Date().timeIntervalSinceReferenceDate
  
      timeIndex = 0
      player?.play()
      player?.rate = Float(initialPlaybackRate)
  
  
  
      // find the index of time
      //reset timeObserverToken
      // call a function with the new times sorted
  
  
      // Queue on which to invoke the callback
      let mainQueue = DispatchQueue.main
      // Add time observer
      timeObserverToken =
          player?.addBoundaryTimeObserver(forTimes: timesToTransverse, queue: mainQueue) {
              [weak self] in
  
  
              //because there are no time signature changes, we can simply increment  timeIndex with + 1 every time `addBoundaryTimeObserver` completion handler is called and subscript timesToTransverse with timeIndex in order to get the subsequent timeInSeconds
              guard let strongSelf = self, strongSelf.timeIndex &lt; timesToTransverse.count else {return}
  
              let timeElement = timesToTransverse[strongSelf.timeIndex]
              strongSelf.timeInSeconds = CMTimeGetSeconds(timeElement.timeValue)
  
                  //show progress in progressView
                  let duration = CMTimeGetSeconds(playerItem.duration)
                  let cmtimeSeconds = CMTime(seconds: strongSelf.timeInSeconds, preferredTimescale: CMTimeScale(NSEC_PER_SEC))
  
              //Total time since timer started, in seconds
              strongSelf.timeInSeconds = Date().timeIntervalSinceReferenceDate - strongSelf.startTime
  
              let timeString = String(format: "%.2f", strongSelf.timeInSeconds)
              strongSelf.timeString = timeString
  
  
              //use reminder operator to determine the beat count
              let beat = (strongSelf.timeIndex + 1) % 8 == 0 ? 8 : ((strongSelf.timeIndex + 1) % 8)
  
  
              //play the beat count : 1, 2, ...8
            self.preapareToPlayAudio(beatCount: beat) 
  
              /*
               0: (0 + 1) % 8 = 1
               1: (1 + 1) % 8 = 2
               6: (6 + 1) % 8 = 7
               7: (7 + 1) % 8 = 0
               */
  
              strongSelf.timeIndex += 1
      }
  }//end addBoundaryTimeObserver
  
  
   //prepare determine what wav file to play 
     private func preapareToPlayAudio(beatCount: Int) {
  
    switch beatCount {  
      case 1:
          guard let url = Bundle.main.url(forResource: "1", withExtension: "wav") else {return}
          playWith(beatCountURL: url)
  
          //7 more cases go here .....
      default: print("unexpected case here")
      }   
  }//end play(beatCount: Int)
  
  
  
       private func playWith(beatCountURL: URL) {
  
          let playerItem = AVPlayerItem(url: beatCountURL)
          countPlayer = AVPlayer(playerItem: playerItem)
          countPlayer?.play()
        }
  </code></pre>