13
votes

I'm writing an application that works with video using AVFoundation.

The behaviour of my application is simple: I take a video from the camera roll, then I create an AVMutableComposition with some audio tracks. With the mix composition i initialize an AVAssetExportSession that stores the video file in the documents directory of my app.

Until this point everything it's ok: my video is stored and I'm able to play it in another controller. If I take the video that i have just stored in my documents folder to make some editing (in the same way of the first time AVmutableComposition, AVAssetExportSession) it's ok again.

But the third time I do this process to editing a video the AVAssetExportSession status becomes "Fail" and with this error:

"Domain=AVFoundationErrorDomain Code=-11820 "Cannot Complete Export" UserInfo=0x1a9260 {NSLocalizedRecoverySuggestion=Try exporting again., NSLocalizedDescription=Cannot Complete Export}"

I have read that is a general error where the session couldn't be exported. What is the sense of this? Why only the third time that i made the editing process? Could it be a memory management mistake? A bug?. This is the code of my AVAssetExportSession:

 _assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality];   
_assetExport.shouldOptimizeForNetworkUse = YES;

///data odierna
NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:@"ddMMyyyyHHmmss"];

NSDate *now = [[NSDate alloc] init];

NSString *dateString = [format stringFromDate:now];
[now release];
[format release];
NSString* ext = @".MOV";
NSString* videoName=[NSString stringWithFormat:@"%@%@", dateString, ext];

///data odierna
NSString *exportPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:videoName];

if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath]) 
{
    [[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
}


_assetExport.outputFileType = AVFileTypeQuickTimeMovie;

[_assetExport setTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)];
NSURL    *exportUrl = [NSURL fileURLWithPath:exportPath] ;

_assetExport.outputURL = exportUrl ;

[_assetExport exportAsynchronouslyWithCompletionHandler:^
{
    switch (_assetExport.status) 
    {
        case AVAssetExportSessionStatusFailed:
        {
            NSLog (@"FAIL %@",_assetExport.error);
            if ([[NSFileManager defaultManager] fileExistsAtPath:[_assetExport.outputURL path]]) 
            {
                [[NSFileManager defaultManager] removeItemAtPath:[_assetExport.outputURL path] error:nil];
            }

            [self performSelectorOnMainThread:@selector (ritenta)
                                   withObject:nil
                                waitUntilDone:NO];
            break;
        }
        case AVAssetExportSessionStatusCompleted: 
        {
            NSLog (@"SUCCESS");

            [self performSelectorOnMainThread:@selector (saveVideoToAlbum:)
                                   withObject:exportPath
                                waitUntilDone:NO];
            break;
        }
        case AVAssetExportSessionStatusCancelled: 
        {
            NSLog (@"CANCELED");

            break;
        }
    };
}];

I have done many searches on the web, some people have had a problem in the outputURL of the session, but I have tried and seems all ok in my code. To assign a unique name to the file I use a NSDate. For debugging purposes I have tried to restore a standard string name but the problem remains. Any ideas? Can someone suggest to me an alternative method to export to the documents folder an asset with AssetWriter insted the AVassetExportSession?

1
Exporter often fails when u do not provide right AVMutableComposition, so debug ur AVMutableComposition objects third time.BhushanVU
Are you on simulator? I get an error on simulator but on real device it succeedsheyfrank

1 Answers

-1
votes

The problem is _assetExport.outputFileType you have set the type AVFileTypeQuickTimeMovie. Which is not likely to be supported type.

Try to find out what output file types are supported by the _assetExport using the following code and use the suitable one.

NSLog (@"created exporter. supportedFileTypes: %@", exporter.supportedFileTypes);

OR
just change the

_assetExport.outputFileType = AVFileTypeQuickTimeMovie;

TO

exporter.outputFileType = @"com.apple.m4a-audio";

Also dont forget to change the extension from

NSString* ext = @".MOV";  to @".m4a" 

This should work. It worked for me.