iPhone - start multiple instances of AVAudioPlayer simultaneously

一个人想着一个人 提交于 2019-12-07 08:43:01

问题


I am using multiple instances of AVAudioPlayer to play multiple audio files simultaneously. I run a loop to start playing the audio files (prepareToPlay is called beforehand and the loop only makes a call to the play method)

But invariably, one of the players does not play in sync. How can I ensure that all the 4 players start playing audio simultaneously?

Thanks.


回答1:


Unfortunately, you can't. AVAudioPlayer doesn't provide any mechanism for fine-grained control of start time. The currentTime property sets the point in the file to read from, it doesn't guarantee when the AVAudioPlayer instance will start playing in system time, which is what you need to sync multiple audio streams.

When I need this behavior, I use the RemoteIO Audio Unit + the 3D Mixer Audio Unit + ExtAudioFile.

EDIT

Note that as of iOS 4, you can synchronize multiple AVAudioPlayer instances using playAtTime:




回答2:


The Apple docs talk about how you can "Play multiple sounds simultaneously, one sound per audio player, with precise synchronization". Perhaps you need to call playAtTime: e.g. [myAudioPlayer playAtTime: myAudioPlayer.deviceCurrentTime + playbackDelay];

In fact, the Apple docs for playAtTime: contain the following code snippet:

NSTimeInterval shortStartDelay = 0.01;            // seconds
NSTimeInterval now = player.deviceCurrentTime;

[player       playAtTime: now + shortStartDelay];
[secondPlayer playAtTime: now + shortStartDelay];

They should play simultaneously (assuming you choose a large enough value for shortStartDelay -- not so soon that it happens before this thread returns or whatever).




回答3:


This code segment of mine allows you to do this as long as you don't have to do it instantly. You can pass in the targetTime as a timestamp for when you want to hear the sounds. The trick is to make use of time-stamps and the delay functionality of NSObject. Also, it utilizes the fact that it takes way less time to change the volume of the player than it does to change the current time. Should work almost perfectly precisely.

- (void) moveTrackPlayerTo:(double) timeInSong atTime:(double) targetTime {
 [trackPlayer play];
 trackPlayer.volume = 0;

 double timeOrig = CFAbsoluteTimeGetCurrent();
 double delay = targetTime - CFAbsoluteTimeGetCurrent();
 [self performSelector:@selector(volumeTo:) 
      withObject:[NSNumber numberWithFloat:single.GLTrackVolume] 
      afterDelay:delay];
 trackPlayer.currentTime = timeInSong - delay - (CFAbsoluteTimeGetCurrent() - timeOrig);
}

- (void) volumeTo:(NSNumber *) volNumb {
 trackPlayer.volume = [volNumb floatValue];
}



回答4:


Try to set same currentTime property value for every AVAudioPlayer object.



来源:https://stackoverflow.com/questions/1687613/iphone-start-multiple-instances-of-avaudioplayer-simultaneously

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!