2017-04-06 26 views
1

我正在使用此方法播放音频文件;如何为AVAudioEngine设置完成处理程序

- (空)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]; 

没有成功,我该如何调用完成处理程序?

回答

1

您需要使用GCD块,而不是一种方法,作为completionHandler参数:

[node scheduleFile:audioFile atTime:nil completionHandler:^{ 

    // Your "stopTalking" code goes here... 

}]; 
+0

非常感谢你 - 完美的工作! – Hypergater

0

没有上述答案为我工作,所以在这里我从寻找解决方案得到了

// 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 
    } 

})