From: "McGrath, Christopher" <email@hidden>
To: cocell <email@hidden>
Sent: Tue, March 8, 2011 9:24:37 PM
Subject: RE: Convert Kills App
Hi there,
I suggest you look at (and even use) the source code from TSLibraryImport.
https://bitbucket.org/artgillespie/tslibraryimport
I use this in my app, to export songs from the iPod library, and it works well.
Chris.
-----Original Message-----
From: coreaudio-api-bounces+cmcgr=email@hidden on behalf of cocell
Sent: Wed 3/9/2011 8:58 AM
To: apple coreaudio
Subject: Convert Kills App
When adding songs from iPod Library and converting it to .caf, the conversion
kills the app. I used instruments and Still can't figure out why it's not
working correctly. Any someone plz help? There are also a lot of memory leaks
that I can't seem to fix.
#defineEXPORT_NAME
@"exported.caf"
@implementationVTM_AViPodReaderViewController
@synthesizesongLabel;
@synthesizeartistLabel;
@synthesizesizeLabel;
@synthesizecoverArtView;
@synthesizeconversionProgress;
#pragmamark event handlers
-(IBAction)convertTapped:(id)sender {
// set up an AVAssetReader to read from the iPod Library
NSURL *assetURL =[song valueForProperty:MPMediaItemPropertyAssetURL];
AVURLAsset*songAsset =[AVURLAssetURLAssetWithURL:assetURL options:nil];
NSError*assetError =nil;
AVAssetReader*assetReader =[[AVAssetReaderassetReaderWithAsset:songAsset
error:&assetError]
retain];
if(assetError){
NSLog(@"error: %@",assetError);
return;
}
AVAssetReaderOutput*assetReaderOutput =[[AVAssetReaderAudioMixOutput
assetReaderAudioMixOutputWithAudioTracks:songAsset.tracks
audioSettings:nil]
retain];
if(![assetReader canAddOutput:assetReaderOutput]){
NSLog(@"can't add reader output... die!");
return;
}
[assetReader addOutput:assetReaderOutput];
NSArray*dirs
=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString*documentsDirectoryPath =[dirs objectAtIndex:0];
NSString*exportPath =[[documentsDirectoryPath
stringByAppendingPathComponent:EXPORT_NAME]retain];
if([[NSFileManagerdefaultManager]fileExistsAtPath:exportPath]){
[[NSFileManagerdefaultManager]removeItemAtPath:exportPath error:nil];
}
NSURL *exportURL =[NSURL fileURLWithPath:exportPath];
AVAssetWriter*assetWriter =[[AVAssetWriterassetWriterWithURL:exportURL
fileType:AVFileTypeCoreAudioFormat
error:&assetError]
retain];
if(assetError){
NSLog(@"error: %@",assetError);
return;
}
AudioChannelLayoutchannelLayout;
memset(&channelLayout,0,sizeof(AudioChannelLayout));
channelLayout.mChannelLayoutTag =kAudioChannelLayoutTag_Stereo;
NSDictionary*outputSettings =[NSDictionarydictionaryWithObjectsAndKeys:
[NSNumbernumberWithInt:kAudioFormatLinearPCM],AVFormatIDKey,
[NSNumbernumberWithFloat:44100.0],AVSampleRateKey,
[NSNumbernumberWithInt:2],AVNumberOfChannelsKey,
[NSDatadataWithBytes:&channelLayout
length:sizeof(AudioChannelLayout)],AVChannelLayoutKey,
[NSNumbernumberWithInt:16],AVLinearPCMBitDepthKey,
[NSNumbernumberWithBool:NO],AVLinearPCMIsNonInterleaved,
[NSNumbernumberWithBool:NO],AVLinearPCMIsFloatKey,
[NSNumbernumberWithBool:NO],AVLinearPCMIsBigEndianKey,
nil];
AVAssetWriterInput*assetWriterInput
=[[AVAssetWriterInputassetWriterInputWithMediaType:AVMediaTypeAudio
outputSettings:outputSettings]
retain];
if([assetWriter canAddInput:assetWriterInput]){
[assetWriter addInput:assetWriterInput];
}else{
NSLog(@"can't add asset writer input... die!");
return;
}
assetWriterInput.expectsMediaDataInRealTime =NO;
[assetWriter startWriting];
[assetReader startReading];
AVAssetTrack*soundTrack =[songAsset.tracks objectAtIndex:0];
CMTimestartTime =CMTimeMake(0,soundTrack.naturalTimeScale);
[assetWriter startSessionAtSourceTime:startTime];
__block UInt64convertedByteCount =0;
dispatch_queue_t mediaInputQueue
=dispatch_queue_create("mediaInputQueue",NULL);
[assetWriterInput requestMediaDataWhenReadyOnQueue:mediaInputQueue
usingBlock:^
{
// NSLog (@"top of block");
while(assetWriterInput.readyForMoreMediaData){
CMSampleBufferRefnextBuffer =[assetReaderOutput
copyNextSampleBuffer];
if(nextBuffer){
// append buffer
[assetWriterInput appendSampleBuffer:nextBuffer];
// NSLog (@"appended a buffer (%d bytes)",
// CMSampleBufferGetTotalSampleSize
(nextBuffer));
convertedByteCount
+=CMSampleBufferGetTotalSampleSize(nextBuffer);
// oops, no
// sizeLabel.text = [NSString stringWithFormat: @"%ld bytes
converted", convertedByteCount];
NSNumber*convertedByteCountNumber
=[NSNumbernumberWithLong:convertedByteCount];
[self performSelectorOnMainThread:@selector(updateSizeLabel:)
withObject:convertedByteCountNumber
waitUntilDone:NO];
}else{
// done!
[assetWriterInput markAsFinished];
[assetWriter finishWriting];
[assetReader cancelReading];
NSDictionary*outputFileAttributes
=[[NSFileManagerdefaultManager]
attributesOfItemAtPath:exportPath
error:nil];
NSLog(@"done. file size is %ld",
[outputFileAttributes fileSize]);
NSNumber*doneFileSize
=[NSNumbernumberWithLong:[outputFileAttributes fileSize]];
[self
performSelectorOnMainThread:@selector(updateCompletedSizeLabel:)
withObject:doneFileSize
waitUntilDone:NO];
// release a lot of stuff
[assetReader release];
[assetReaderOutput release];
[assetWriter release];
[assetWriterInput release];
[exportPath release];
break;
}
}
}];
NSLog(@"bottom of
convertTapped:");
}
-(void)updateSizeLabel:(NSNumber*)convertedByteCountNumber {
UInt64convertedByteCount =[convertedByteCountNumber longValue];
sizeLabel.text =[NSStringstringWithFormat:@"%ld bytes
converted",convertedByteCount];
}
-(void)updateCompletedSizeLabel:(NSNumber*)convertedByteCountNumber {
UInt64convertedByteCount =[convertedByteCountNumber longValue];
sizeLabel.text =[NSStringstringWithFormat:@"done. file size is
%ld",convertedByteCount];
}
@end