简体   繁体   English

iPhone - 同时启动AVAudioPlayer的多个实例

[英]iPhone - start multiple instances of AVAudioPlayer simultaneously

I am using multiple instances of AVAudioPlayer to play multiple audio files simultaneously. 我正在使用AVAudioPlayer的多个实例同时播放多个音频文件。 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) 我运行循环开始播放音频文件(预先调用prepareToPlay,循环只调用play方法)

But invariably, one of the players does not play in sync. 但总是,其中一名球员没有同步进行比赛。 How can I ensure that all the 4 players start playing audio simultaneously? 如何确保所有4名玩家同时开始播放音频?

Thanks. 谢谢。

The Apple docs talk about how you can "Play multiple sounds simultaneously, one sound per audio player, with precise synchronization". Apple文档讨论了如何“同时播放多个声音,每个音频播放器一个声音,精确同步”。 Perhaps you need to call playAtTime: eg [myAudioPlayer playAtTime: myAudioPlayer.deviceCurrentTime + playbackDelay]; 也许你需要调用playAtTime:例如[myAudioPlayer playAtTime: myAudioPlayer.deviceCurrentTime + playbackDelay];

In fact, the Apple docs for playAtTime: contain the following code snippet: 实际上, playAtTimeApple文档包含以下代码片段:

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). 它们应该同时播放(假设你为shortStartDelay选择了一个足够大的值 - 不是很快就会在这个线程返回之前发生或者其他什么)。

Unfortunately, you can't. 不幸的是,你做不到。 AVAudioPlayer doesn't provide any mechanism for fine-grained control of start time. AVAudioPlayer不提供任何机制来细粒度控制开始时间。 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. currentTime属性设置要读取的文件中的点,它不保证AVAudioPlayer实例何时开始在系统时间内播放,这是您需要同步多个音频流。

When I need this behavior, I use the RemoteIO Audio Unit + the 3D Mixer Audio Unit + ExtAudioFile. 当我需要这种行为时,我使用RemoteIO Audio Unit + 3D Mixer Audio Unit + ExtAudioFile。

EDIT 编辑

Note that as of iOS 4, you can synchronize multiple AVAudioPlayer instances using playAtTime: 请注意,从iOS 4开始,您可以使用playAtTime:同步多个AVAudioPlayer实例playAtTime:

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. 您可以将targetTime作为时间戳传递给您想要听到声音的时间。 The trick is to make use of time-stamps and the delay functionality of NSObject. 诀窍是利用时间戳和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];
}

尝试为每个AVAudioPlayer对象设置相同的currentTime属性值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM