Combined with the previous chapters, we can achieve a simple audio player.

Initialize the

Custom initialization method that requires passing in the path of the audio file.

- (instancetype)initWithFilePath:(NSString *)path;
Copy the code

AUGraph callback

Construct an AURenderCallbackStruct structure and assign a callback function to the input of RemoteIO Unit, which calls PlayCallback frequently when RemoteIO Unit needs data input.

AURenderCallbackStruct playCallback; playCallback.inputProc = PlayCallback; playCallback.inputProcRefCon = (__bridge void *)self; status = AUGraphSetNodeInputCallback(mPlayerGraph, mPlayerIONode, 0, &playCallback); NSAssert(! status, @"AudioUnitSetProperty error"); //7: Graph status = AUGraphInitialize(mPlayerGraph); CheckStatus(status, @"Couldn't Initialize the graph", YES); //8: display Graph structure CAShow(mPlayerGraph); /// OSStatus PlayCallback(void *inRefCon,
                      AudioUnitRenderActionFlags *ioActionFlags,
                      const AudioTimeStamp *inTimeStamp,
                      UInt32 inBusNumber,
                      UInt32 inNumberFrames,
                      AudioBufferList *ioData) {
    NAudioUnit *audioUnit = (__bridge NAudioUnit *)inRefCon;
    
    audioUnit->buffList->mBuffers[0].mDataByteSize = CONST_BUFFER_SIZE;
    OSStatus status = ExtAudioFileRead(audioUnit->exAudioFile, &inNumberFrames, audioUnit->buffList);

    if (status) NSLog(@"Conversion format failed");
    if (!inNumberFrames) NSLog(@"End of playback");

    NSLog(@"total size: %llu,out size: %d", audioUnit->totalSize, audioUnit->buffList->mBuffers[0].mDataByteSize); memcpy(ioData->mBuffers[0].mData, audioUnit->buffList->mBuffers[0].mData, audioUnit->buffList->mBuffers[0].mDataByteSize); ioData->mBuffers[0].mDataByteSize = audioUnit->buffList->mBuffers[0].mDataByteSize; audioUnit->readedSize += audioUnit->buffList->mBuffers[0].mDataByteSize / audioUnit->outputFormat.mBytesPerFrame; //Bytes per Frame = 2, Fwrite (audioUnit->buffList->mBuffers[0]. MData, audioUnit->buffList->mBuffers[0]. MDataByteSize, 1, [audioUnit pcmFile]); /// Callback progress UInt32 byteSize = audioUnit->buffList->mBuffers[0]. audioUnit.progress(byteSize); dispatch_async(dispatch_get_main_queue(), ^{if(byteSize <= 0) { audioUnit->totalSize = 0; audioUnit->readedSize = 0; }});return noErr;
}
Copy the code

PlayCallback: The function reads file data through ExtAudioFileRead, and on the other hand continuously calls back the read progress outward.

Start playing

Call the AUGraphStart method to start playing the audio data.

- (BOOL)play;
Copy the code

Stop playing

Call the AUGraphStop method to stop playing audio data.

- (void)stop;
Copy the code

Gets the current playback time

Data read duration/total file duration

- (double)getCurrentTime;
Copy the code

The sample code

Here (github.com/Nicholas86/…). Is the code