Note that there are some explanatory texts on larger screens.

plurals
  1. POAVAssetWriter How to write down-sampled/compressed m4a/mp3 files
    primarykey
    data
    text
    <p>I'm trying to take a local m4a or mp3 file and compress/down-sample this file (for the purposes of making a smaller file). </p> <p>Originally, I was using the AVAssetExportSession to export an AVAsset to a temp directory, but I didn't have any control over compression/down-sampling (you can only use presets, which of them, only .wav file formats support quality degradation).</p> <p>Then, following several examples here on SO, I tried using AVAssetReader/AVAssetWriter to preform this 'export'. </p> <p>I create my reader/writer as such:</p> <pre><code>NSString *exportPath = [NSHomeDirectory() stringByAppendingPathComponent:@"out.m4a"]; NSURL *exportURL = [NSURL fileURLWithPath:outPath]; // reader NSError *readerError = nil; AVAssetReader *reader = [[AVAssetReader alloc] initWithAsset:asset error:&amp;readerError]; AVAssetTrack *track = [[asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; AVAssetReaderTrackOutput *readerOutput = [[AVAssetReaderTrackOutput alloc] initWithTrack:track outputSettings:nil]; [reader addOutput:readerOutput]; // writer NSError *writerError = nil; AVAssetWriter *writer = [[AVAssetWriter alloc] initWithURL:exportURL fileType:AVFileTypeAppleM4A error:&amp;writerError]; AudioChannelLayout channelLayout; memset(&amp;channelLayout, 0, sizeof(AudioChannelLayout)); channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo; // use different values to affect the downsampling/compression NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey, [NSNumber numberWithFloat:44100.0], AVSampleRateKey, [NSNumber numberWithInt:2], AVNumberOfChannelsKey, [NSNumber numberWithInt:128000], AVEncoderBitRateKey, [NSData dataWithBytes:&amp;channelLayout length:sizeof(AudioChannelLayout)], AVChannelLayoutKey, nil]; AVAssetWriterInput *writerInput = [[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeAudio outputSettings:outputSettings]; [writerInput setExpectsMediaDataInRealTime:NO]; [writer addInput:writerInput]; </code></pre> <p>And then I start writing...</p> <pre><code>[writer startWriting]; [writer startSessionAtSourceTime:kCMTimeZero]; [reader startReading]; dispatch_queue_t mediaInputQueue = dispatch_queue_create("mediaInputQueue", NULL); [writerInput requestMediaDataWhenReadyOnQueue:mediaInputQueue usingBlock:^{ NSLog(@"Asset Writer ready : %d", writerInput.readyForMoreMediaData); while (writerInput.readyForMoreMediaData) { CMSampleBufferRef nextBuffer; if ([reader status] == AVAssetReaderStatusReading &amp;&amp; (nextBuffer = [readerOutput copyNextSampleBuffer])) { if (nextBuffer) { NSLog(@"Adding buffer"); [writerInput appendSampleBuffer:nextBuffer]; } } else { [writerInput markAsFinished]; switch ([reader status]) { case AVAssetReaderStatusReading: break; case AVAssetReaderStatusFailed: [writer cancelWriting]; break; case AVAssetReaderStatusCompleted: NSLog(@"Writer completed"); [writer endSessionAtSourceTime:asset.duration]; [writer finishWriting]; NSData *data = [NSData dataWithContentsOfFile:exportPath]; NSLog(@"Data: %@", data); break; } break; } } }]; </code></pre> <p>When I'm done writing, the data i've supposedly written to the exportURL is null, and the writer reports a successful completion. Any ideas what might be going wrong?</p> <p><strong>Update</strong> The writer status after calling <code>appendSampleBuffer:</code> is AVAssetWriterStatusFailed, though the readers status is successful, and seems to read through the entire file. </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload