Note that there are some explanatory texts on larger screens.

plurals
  1. POVideo Encoding using AVAssetWriter - CRASHES
    primarykey
    data
    text
    <p>I have a function that is supposed to re-encode a video to a manageable bitrate on iphone/ipad. Here it is: <strong>*<em>UPDATED WORKING CODE, NOW WITH AUDIO! :) *</em></strong></p> <pre><code> -(void)resizeVideo:(NSString*)pathy{ NSString *newName = [pathy stringByAppendingString:@".down.mov"]; NSURL *fullPath = [NSURL fileURLWithPath:newName]; NSURL *path = [NSURL fileURLWithPath:pathy]; NSLog(@"Write Started"); NSError *error = nil; AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:fullPath fileType:AVFileTypeQuickTimeMovie error:&amp;error]; NSParameterAssert(videoWriter); AVAsset *avAsset = [[[AVURLAsset alloc] initWithURL:path options:nil] autorelease]; NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys: AVVideoCodecH264, AVVideoCodecKey, [NSNumber numberWithInt:1280], AVVideoWidthKey, [NSNumber numberWithInt:720], AVVideoHeightKey, nil]; AVAssetWriterInput* videoWriterInput = [[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings] retain]; NSParameterAssert(videoWriterInput); NSParameterAssert([videoWriter canAddInput:videoWriterInput]); videoWriterInput.expectsMediaDataInRealTime = YES; [videoWriter addInput:videoWriterInput]; NSError *aerror = nil; AVAssetReader *reader = [[AVAssetReader alloc] initWithAsset:avAsset error:&amp;aerror]; AVAssetTrack *videoTrack = [[avAsset tracksWithMediaType:AVMediaTypeVideo]objectAtIndex:0]; videoWriterInput.transform = videoTrack.preferredTransform; NSDictionary *videoOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange] forKey:(id)kCVPixelBufferPixelFormatTypeKey]; AVAssetReaderTrackOutput *asset_reader_output = [[AVAssetReaderTrackOutput alloc] initWithTrack:videoTrack outputSettings:videoOptions]; [reader addOutput:asset_reader_output]; //audio setup AVAssetWriterInput* audioWriterInput = [[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:nil] retain]; AVAssetReader *audioReader = [[AVAssetReader assetReaderWithAsset:avAsset error:&amp;error] retain]; AVAssetTrack* audioTrack = [[avAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; AVAssetReaderOutput *readerOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:audioTrack outputSettings:nil]; [audioReader addOutput:readerOutput]; NSParameterAssert(audioWriterInput); NSParameterAssert([videoWriter canAddInput:audioWriterInput]); audioWriterInput.expectsMediaDataInRealTime = NO; [videoWriter addInput:audioWriterInput]; [videoWriter startWriting]; [videoWriter startSessionAtSourceTime:kCMTimeZero]; [reader startReading]; dispatch_queue_t _processingQueue = dispatch_queue_create("assetAudioWriterQueue", NULL); [videoWriterInput requestMediaDataWhenReadyOnQueue:_processingQueue usingBlock: ^{ [self retain]; while ([videoWriterInput isReadyForMoreMediaData]) { CMSampleBufferRef sampleBuffer; if ([reader status] == AVAssetReaderStatusReading &amp;&amp; (sampleBuffer = [asset_reader_output copyNextSampleBuffer])) { BOOL result = [videoWriterInput appendSampleBuffer:sampleBuffer]; CFRelease(sampleBuffer); if (!result) { [reader cancelReading]; break; } } else { [videoWriterInput markAsFinished]; switch ([reader status]) { case AVAssetReaderStatusReading: // the reader has more for other tracks, even if this one is done break; case AVAssetReaderStatusCompleted: // your method for when the conversion is done // should call finishWriting on the writer //hook up audio track [audioReader startReading]; [videoWriter startSessionAtSourceTime:kCMTimeZero]; dispatch_queue_t mediaInputQueue = dispatch_queue_create("mediaInputQueue", NULL); [audioWriterInput requestMediaDataWhenReadyOnQueue:mediaInputQueue usingBlock:^ { NSLog(@"Request"); NSLog(@"Asset Writer ready :%d",audioWriterInput.readyForMoreMediaData); while (audioWriterInput.readyForMoreMediaData) { CMSampleBufferRef nextBuffer; if ([audioReader status] == AVAssetReaderStatusReading &amp;&amp; (nextBuffer = [readerOutput copyNextSampleBuffer])) { NSLog(@"Ready"); if (nextBuffer) { NSLog(@"NextBuffer"); [audioWriterInput appendSampleBuffer:nextBuffer]; } }else{ [audioWriterInput markAsFinished]; switch ([audioReader status]) { case AVAssetReaderStatusCompleted: [videoWriter finishWriting]; [self hookUpVideo:newName]; break; } } } } ]; break; case AVAssetReaderStatusFailed: [videoWriter cancelWriting]; break; } break; } } } ]; NSLog(@"Write Ended"); } </code></pre> <p>Unfortunately, if I pass in a video any longer than 2 seconds, the app sucks up memory like crazy and crashes! The code seems fairly simple, but I cannot seem to get it to work!<br> Am I supposed to release the buffer in there somewhere after it is written? I would be most greatful to anyone that has any input.</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.
 

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