如何为 AVAudioEngine 设置完成处理程序
How to set a completionhandler for AVAudioEngine
我正在使用此方法播放音频文件;
-(void)playOnMainThread:(id)参数
{
[self playAudio];
AVAudioEngine *engine = [[AVAudioEngine alloc] init];
AVAudioPlayerNode *node = [[AVAudioPlayerNode alloc] init];
[engine attachNode:node];
AVAudioUnitTimePitch *pitch = [[AVAudioUnitTimePitch alloc] init];
pitch.pitch = 100;
pitch.rate = 2;
[engine attachNode:pitch];
AVAudioMixerNode *mixerNode = engine.mainMixerNode;
[engine connect:node to:pitch format:[mixerNode outputFormatForBus:0]];
[engine connect:pitch to:mixerNode format:[mixerNode outputFormatForBus:0]];
AVAudioFile *audioFile = [[AVAudioFile alloc] initForReading:recorder.url error:&error];
if (error)
NSLog(@"AVAudioPlayer error %@, %@", error, [error userInfo]);
if (audioFile != nil) {
[node scheduleFile:audioFile atTime:nil completionHandler:nil];
[engine startAndReturnError:nil];
[node play];
}
}
但是我需要设置一个completionhandler,这是我试过的;
-(void)stopTalking:(AVAudioNodeCompletionHandler)handler
//-(void)stopTalking
{
isPlaying = NO;
[self unschedule:@selector(RepeatSpeackAction)];
[self schedule:@selector(StartGAmeCall)];
[stand setDisplayFrame:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"Turn1.png"]];
if(video==true) {
cases=1;
[self addaudiotoDict];
}
}
我试图通过这样使用它来调用它;
[node scheduleFile:audioFile atTime:nil completionHandler:stopTalking];
没有成功,如何调用完成处理程序?
您需要使用 GCD 块,而不是方法,作为 completionHandler
参数:
[node scheduleFile:audioFile atTime:nil completionHandler:^{
// Your "stopTalking" code goes here...
}];
none 以上答案对我有用,所以这里是我从搜索解决方案中得到的
// audioFile here is our original audio
audioPlayerNode.scheduleFile(audioFile, at: nil, completionHandler: {
print("scheduleFile Complete")
var delayInSeconds: Double = 0
if let lastRenderTime = self.audioPlayerNode.lastRenderTime, let playerTime = self.audioPlayerNode.playerTime(forNodeTime: lastRenderTime) {
if let rate = rate {
delayInSeconds = Double(audioFile.length - playerTime.sampleTime) / Double(audioFile.processingFormat.sampleRate) / Double(rate!)
} else {
delayInSeconds = Double(audioFile.length - playerTime.sampleTime) / Double(audioFile.processingFormat.sampleRate)
}
}
// schedule a stop timer for when audio finishes playing
DispatchTime.executeAfter(seconds: delayInSeconds) {
audioEngine.mainMixerNode.removeTap(onBus: 0)
// Playback has completed
}
})
我正在使用此方法播放音频文件;
-(void)playOnMainThread:(id)参数
{
[self playAudio];
AVAudioEngine *engine = [[AVAudioEngine alloc] init];
AVAudioPlayerNode *node = [[AVAudioPlayerNode alloc] init];
[engine attachNode:node];
AVAudioUnitTimePitch *pitch = [[AVAudioUnitTimePitch alloc] init];
pitch.pitch = 100;
pitch.rate = 2;
[engine attachNode:pitch];
AVAudioMixerNode *mixerNode = engine.mainMixerNode;
[engine connect:node to:pitch format:[mixerNode outputFormatForBus:0]];
[engine connect:pitch to:mixerNode format:[mixerNode outputFormatForBus:0]];
AVAudioFile *audioFile = [[AVAudioFile alloc] initForReading:recorder.url error:&error];
if (error)
NSLog(@"AVAudioPlayer error %@, %@", error, [error userInfo]);
if (audioFile != nil) {
[node scheduleFile:audioFile atTime:nil completionHandler:nil];
[engine startAndReturnError:nil];
[node play];
}
}
但是我需要设置一个completionhandler,这是我试过的;
-(void)stopTalking:(AVAudioNodeCompletionHandler)handler
//-(void)stopTalking
{
isPlaying = NO;
[self unschedule:@selector(RepeatSpeackAction)];
[self schedule:@selector(StartGAmeCall)];
[stand setDisplayFrame:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"Turn1.png"]];
if(video==true) {
cases=1;
[self addaudiotoDict];
}
}
我试图通过这样使用它来调用它;
[node scheduleFile:audioFile atTime:nil completionHandler:stopTalking];
没有成功,如何调用完成处理程序?
您需要使用 GCD 块,而不是方法,作为 completionHandler
参数:
[node scheduleFile:audioFile atTime:nil completionHandler:^{
// Your "stopTalking" code goes here...
}];
none 以上答案对我有用,所以这里是我从搜索解决方案中得到的
// audioFile here is our original audio
audioPlayerNode.scheduleFile(audioFile, at: nil, completionHandler: {
print("scheduleFile Complete")
var delayInSeconds: Double = 0
if let lastRenderTime = self.audioPlayerNode.lastRenderTime, let playerTime = self.audioPlayerNode.playerTime(forNodeTime: lastRenderTime) {
if let rate = rate {
delayInSeconds = Double(audioFile.length - playerTime.sampleTime) / Double(audioFile.processingFormat.sampleRate) / Double(rate!)
} else {
delayInSeconds = Double(audioFile.length - playerTime.sampleTime) / Double(audioFile.processingFormat.sampleRate)
}
}
// schedule a stop timer for when audio finishes playing
DispatchTime.executeAfter(seconds: delayInSeconds) {
audioEngine.mainMixerNode.removeTap(onBus: 0)
// Playback has completed
}
})