How to convert m4a file to aac adts file in Xcode?
- by Bird Hsuie
I have a mp4 file copied from iPod lib and saved to my Document
for my next step, I need it to convert to .mp3 or .aac(ADTS type)
I use this code and failed...
-(IBAction)compressFile:(id)sender{
NSLog (@"handleConvertToPCMTapped");
// open an ExtAudioFile
NSLog (@"opening %@", exportURL);
ExtAudioFileRef inputFile;
CheckResult (ExtAudioFileOpenURL((__bridge CFURLRef)exportURL, &inputFile),
             "ExtAudioFileOpenURL failed");
// prepare to convert to a plain ol' PCM format
AudioStreamBasicDescription myPCMFormat;
myPCMFormat.mSampleRate = 44100; // todo: or use source rate?
myPCMFormat.mFormatID = kAudioFormatMPEGLayer3 ;
myPCMFormat.mFormatFlags =  kAudioFormatFlagsCanonical; 
myPCMFormat.mChannelsPerFrame = 2;
myPCMFormat.mFramesPerPacket = 1;
myPCMFormat.mBitsPerChannel = 16;
myPCMFormat.mBytesPerPacket = 4;
myPCMFormat.mBytesPerFrame = 4;
CheckResult (ExtAudioFileSetProperty(inputFile, kExtAudioFileProperty_ClientDataFormat,
                                     sizeof (myPCMFormat), &myPCMFormat),
             "ExtAudioFileSetProperty failed");
// allocate a big buffer. size can be arbitrary for ExtAudioFile.
// you have 64 KB to spare, right?
UInt32 outputBufferSize = 0x10000;
void* ioBuf = malloc (outputBufferSize);
UInt32 sizePerPacket = myPCMFormat.mBytesPerPacket; 
UInt32 packetsPerBuffer = outputBufferSize / sizePerPacket;
// set up output file
NSString *outputPath = [myDocumentsDirectory()   stringByAppendingPathComponent:@"m_export.mp3"];
NSURL *outputURL = [NSURL fileURLWithPath:outputPath];
NSLog (@"creating output file %@", outputURL);
AudioFileID outputFile;
CheckResult(AudioFileCreateWithURL((__bridge CFURLRef)outputURL,
                                   kAudioFileCAFType,
                                   &myPCMFormat, 
                                   kAudioFileFlags_EraseFile, 
                                   &outputFile),
            "AudioFileCreateWithURL failed");
// start convertin'
UInt32 outputFilePacketPosition = 0; //in bytes
while (true) {
    // wrap the destination buffer in an AudioBufferList
    AudioBufferList convertedData;
    convertedData.mNumberBuffers = 1;
    convertedData.mBuffers[0].mNumberChannels = myPCMFormat.mChannelsPerFrame;
    convertedData.mBuffers[0].mDataByteSize = outputBufferSize;
    convertedData.mBuffers[0].mData = ioBuf;
    UInt32 frameCount = packetsPerBuffer;
    // read from the extaudiofile
    CheckResult (ExtAudioFileRead(inputFile,
                                  &frameCount,
                                  &convertedData),
                 "Couldn't read from input file");
    if (frameCount == 0) {
        printf ("done reading from file");
        break;
    }
    // write the converted data to the output file
    CheckResult (AudioFileWritePackets(outputFile,
                                       false,
                                       frameCount,
                                       NULL,
                                       outputFilePacketPosition / myPCMFormat.mBytesPerPacket, 
                                       &frameCount,
                                       convertedData.mBuffers[0].mData),
                 "Couldn't write packets to file");
    NSLog (@"Converted %ld bytes", outputFilePacketPosition);
    // advance the output file write location
    outputFilePacketPosition += (frameCount * myPCMFormat.mBytesPerPacket);
}
// clean up
ExtAudioFileDispose(inputFile);
AudioFileClose(outputFile);
// show size in label
NSLog (@"checking file at %@", outputPath);
[self transMitFile:outputPath];
if ([[NSFileManager defaultManager] fileExistsAtPath:outputPath]) {
    NSError *fileManagerError = nil;
    unsigned long long fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:outputPath
                                                                                    error:&fileManagerError]
                                   fileSize];
}
any suggestion?.......thanks for your great help!