17

I'm trying to play multiple sounds at the same time.

The approach initially I've taken was to create several players , but it seems wrong one.

What's the best way to play several audio files at the same time.

Is it through making them AVAssets, but in this case how would I stop and play them whenever I want.

Really appreciate your help.

The reason I need AVPlayer is to fetch sounds from the iPod Library.

I finally got an answer from TechSupport of Apple Dev Team and it seems I'm on the right track when I decided to use several AVPlayer.

Rouslan Karimov
  • 585
  • 2
  • 7
  • 19
  • I'm pretty sure that multiple AVAudioPlayers is the way to go if you have to use AVAudioPlayers. Just set them up and trigger them at the same time. Remember to release any allocations and you should be fine. Just keep in mind that AVAudio is kind of slow as compared to something like openAL. – Daniel G. Wilson Jun 01 '11 at 03:43
  • 1
    the problem with 2 players I'm facing is that . Once I'm starting to play the second player while first one is on, the first one stops for fraction of second and than they continue playing. – Rouslan Karimov Jun 01 '11 at 08:57
  • I haven't tried implementing openAL with the iphone library yet, but there is an excellent free openAL sound manager that is already set up and optimized. See if it helps: http://www.71squared.com/2011/01/latest-sound-manager/ – Daniel G. Wilson Jun 01 '11 at 14:50
  • Rouslan, any update on how you fixed this? – David Morton Jul 20 '12 at 02:57
  • 2
    Hi David it should be multiple AVPlayers at the end of the day, and the problem with stopping is the actual bit rate of the file , if they are different than there is an issue, if not everything plays nicely. In other words files should be in the same bit rate. – Rouslan Karimov Jul 22 '12 at 10:18
  • Interesting. Turns out that for my situation, it had more to do with the number of volume ramps I was applying to the mix. More than about 1000 or so, and I would hear the bobble. Once I refactored to get far fewer, everything worked great. http://stackoverflow.com/questions/11183820/audio-glitch-when-playing-two-avplayer-audio-files-simultaneously – David Morton Jul 22 '12 at 20:47

5 Answers5

9

For every sound you want to make make a new AVPlayer.

NSURL *url = [NSURL URLWithString:pathToYourFile];
AVPlayer *audioPlayer = [[AVPlayer alloc] initWithURL:url];
[audioPlayer play];

Sam Baumgarten
  • 2,231
  • 3
  • 21
  • 46
  • @David Morton, as the original post described at the bottom of his own question, and as this answer suggests, you would use a different AVPlayer for every sounds. if you don't need your sounds to be streamed and can use sounds in your sandbox, you can use multiple AVAudioPlayer instances, which is what my app does. – john.k.doe Jul 18 '12 at 23:18
  • 1
    I do use multiple instances. The glitch still exists. – David Morton Jul 19 '12 at 22:53
  • @john.k.doe can you help me out? I am using multiple players as you're suggesting and the sound still gets interrupted. – bibscy Feb 06 '19 at 15:50
1

I have never answered a question here and I don't know in anyone is still waiting for an answer to this but heres my take... Try this and it should work, I am currently using it to play 12 plus simultaneous audio samples. I apologize if I am doing something newbish..

You press a button and you run this code...

But first you need to:

  1. Need to import AVFoundation to project and #import into .h file as well then we can play sound with this.
  2. Need to put "AVAudioPlayer *myAudio;" without quotation marks of course somewhere on top (usually on top of viewDidLoad).

Then just...

-(IBAction)playButtonPressed:(id)sender {

    NSURL *yourMusicFile;
    yourMusicFile = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"your_Song_Name" ofType:@"mp3"]];

    myAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:musicFile error:nil];
    [myAudio play];
    NSLog(@"Button -playButtonPressed- has been pressed!");
}
Chitra Khatri
  • 1,260
  • 2
  • 14
  • 31
DotSlash
  • 53
  • 8
  • could you please help me out? https://stackoverflow.com/questions/54345702 – bibscy Feb 06 '19 at 15:57
  • It looks like if you push a button twice, new audio player will be initiated and you will lose the last audio player which is already playing. – AsifHabib Oct 02 '20 at 13:02
0

Well, my solution comes out of experience. I can quickly cook up a project if needed. But also, it requires the use of an MoMu API at Stanford. It involves creating WvIn and WvOut objects for reading the files. The audio samples of these objects simply need to be fed to the output buffer to play the files simultaneously. Although the API uses AVFoundation, there is no explicit use of AVFoundation in this project.

Ravi
  • 7,929
  • 6
  • 38
  • 48
0

Basically what everyone else is saying, make sure you create an audio player for each source.

What you also must do is KEEP A STRONG REFERENCE TO ALL THE PLAYER OBJECTS.

If you don't do this they get released and playback stops.

I had this issue when I was only keeping a reference to the last source I wanted to play back. This meant that I would only hear the last data source and I thought the issue was something to do with the simultaneous playback configuration - but in reality it was just the other players were being dealloc'd and thus playback would stop.

 try? AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, options: .mixWithOthers)
            try? AVAudioSession.sharedInstance().setActive(true)

I also used the above snippet before creating and playing back my audio sources.

Rufus Mall
  • 569
  • 4
  • 14
0

We can make mixComposition with AVMutableComposition with multiple audio asset, then play on AVPlayer. like as:

var player: AVPlayer?

func addMultipleTrack(videoURL1: URL, videoURL2: URL, videoURL3: URL) {
    
    let asset1 = AVURLAsset(url: videoURL1)
    let asset2 = AVURLAsset(url: videoURL2)
    let asset3 = AVURLAsset(url: videoURL3)
   
    
    let composition = AVMutableComposition()
    var timeRange = CMTimeRange(start: .zero, duration: asset1.duration)
    
    if let audioAssetTrack1 = asset1.tracks(withMediaType: .audio).first,
       let compositionAudioTrack1 = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid) {
        
        do {
            try compositionAudioTrack1.insertTimeRange(timeRange, of: audioAssetTrack1, at: .zero)
        }catch {
            print(error)
            return
        }
    }
    
    
    timeRange = CMTimeRange(start: .zero, duration: asset2.duration)
    
    if let audioAssetTrack2 = asset2.tracks(withMediaType: .audio).first,
       let compositionAudioTrack2 = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid) {
        
        do {
            try compositionAudioTrack2.insertTimeRange(timeRange, of: audioAssetTrack2, at: .zero)
        }catch {
            print(error)
            return
        }
    }
    
    
    timeRange = CMTimeRange(start: .zero, duration: asset3.duration)
    if let audioAssetTrack3 = asset3.tracks(withMediaType: .audio).first,
       let compositionAudioTrack3 = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid) {
        
        do {
            try compositionAudioTrack3.insertTimeRange(timeRange, of: audioAssetTrack3, at: .zero)
        }catch {
            print(error)
            return
        }
        
    }
    
    let item = AVPlayerItem(asset: composition)
    
    player = AVPlayer(playerItem: item)
    
    let layer = AVPlayerLayer(player: player!)
    
    tempView.layer.addSublayer(layer) // it just hold layer but not need to show ,So you can hide in your won way
    player?.play()
    
}
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Mahbeer
  • 1
  • 1
  • 1