2012-10-12 180 views
7

estoy fusión de varios vídeos y varias canciones y estoy bot recibiendo lo que está mal en el código debido a que el mismo código se ejecuta absolutamente bien ayer, pero hoy estoy recibiendo la siguiente respuesta AVAssetExportSessionStatus = 4,error = Error Domain=AVFoundationErrorDomain Code=-11841 "The operation couldn’t be completed. (AVFoundationErrorDomain error -11841.)" he hecho un poco Investigue y descubrió que la exportación está fallando debido a una composición de video no válida. Descubra qué está mal con la composición del video.AVErrorInvalidVideoComposition = -11.841

- (void)mergeAllselectedVideos 
{ 
    NSArray *pathArray = [DocumentDirectory getUrlFromDocumentDirectoryOfList:self.selectedClipsArray]; 
    AVMutableComposition *mixComposition = [[AVMutableComposition alloc]init]; 
    NSMutableArray *layerinstructions = [[NSMutableArray alloc]init]; 
    CMTime time = kCMTimeZero; 
    CMTime previousSongDuration = kCMTimeZero; 
    for (int i = 0 ; i < pathArray.count; i++) 
    { 
     //VIDEO TRACK// 
     time = CMTimeAdd(time, previousSongDuration); 
     NSURL *url = [NSURL URLWithString:[pathArray objectAtIndex:i]]; 
     AVAsset *avAsset = [AVAsset assetWithURL:url]; 
     AVMutableCompositionTrack *track = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 
     [track insertTimeRange:CMTimeRangeMake(kCMTimeZero, avAsset.duration) ofTrack:[[avAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:time error:nil]; 
    previousSongDuration = avAsset.duration; 
    } 
    CMTime audioTime = kCMTimeZero; 
    for (int i = 0; i < self.selectedSongsArray.count; i++) 
    { 
     MPMediaItem * songItem = [self.selectedSongsArray objectAtIndex:i]; 
     NSURL *songURL = [songItem valueForProperty: MPMediaItemPropertyAssetURL]; 
     AVAsset *audioAsset = [AVAsset assetWithURL:songURL]; 
     AVMutableCompositionTrack *AudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 
     CMTimeRange timeRange = CMTimeRangeMake(audioTime, audioAsset.duration); 
     if(CMTimeGetSeconds(CMTimeAdd(audioTime, audioAsset.duration)) > CMTimeGetSeconds(time)) 
     { 
      timeRange = CMTimeRangeMake(audioTime, CMTimeSubtract(time,audioTime)); 
     } 
     [AudioTrack insertTimeRange:timeRange ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:kCMTimeZero error:nil]; 
     audioTime = CMTimeAdd(audioTime, audioAsset.duration); 
    } 

    AVMutableVideoCompositionInstruction * MainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; 
    MainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, time); 
    MainInstruction.layerInstructions = layerinstructions; 

    AVMutableVideoComposition *MainCompositionInst = [AVMutableVideoComposition videoComposition]; 
    MainCompositionInst.instructions = [NSArray arrayWithObject:MainInstruction]; 
    MainCompositionInst.frameDuration = CMTimeMake(1, 30); 
    MainCompositionInst.renderSize = CGSizeMake(320.0, 480.0); 

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    movieName = [CoreDataFunctions getNameForMovieForDate:[CalendarFunctions getCurrentDateString]]; 
    self.moviePlayButton.titleLabel.text = movieName; 
    NSString *myPathDocs = [documentsDirectory stringByAppendingPathComponent:movieName]; 

    NSURL *url = [NSURL fileURLWithPath:myPathDocs]; 

    AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality]; 
    exporter.outputURL=url; 
    exporter.outputFileType = AVFileTypeQuickTimeMovie; 
    exporter.videoComposition = MainCompositionInst; 
    exporter.shouldOptimizeForNetworkUse = YES; 
    [exporter exportAsynchronouslyWithCompletionHandler:^{dispatch_async(dispatch_get_main_queue(), ^{[self exportDidFinish:exporter];});}]; 
} 
- (void)exportDidFinish:(AVAssetExportSession*)session 
{ 
    //Printing error 
    NSLog(@"AVAssetExportSessionStatus = %i,error = %@",session.status,session.error); 
} 

Respuesta

6

He encontrado su pregunta al tener el mismo problema. Mi teoría sobre este tema es que todas las propiedades de la composición del video no están configuradas en el momento de la exportación, por lo que se trata de una excepción. Aquí está la estrofa que estoy usando ahora que ahora está dando lugar a una exportación sin errores:

AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition]; 
videoComposition.frameDuration = CMTimeMake(1,30); 
videoComposition.renderScale = 1.0; 
videoComposition.renderSize = CGSizeMake(352.0, 288.0); 
instruction.layerInstructions = [NSArray arrayWithObject: layerInstruction]; 
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, videoAsset.duration); 
videoComposition.instructions = [NSArray arrayWithObject: instruction]; 

En mi caso, me estaba perdiendo la propiedad TimeRange en la instrucción. Verifique sus propias propiedades para asegurarse de que obtengan los valores correctos. ¡Buena suerte! Esto es difícil.

+0

Aaron, tengo el mismo problema con no ser capaz de crear un vídeo. He especificado todo lo que dijiste anteriormente. Lo único que puedo pensar es que mi entrada de video es la salida de otra sesión. ¿Tendría alguna idea sobre cómo eso podría importar? –

+0

Esto no resuelve el problema para mí tampoco :( –

-1

Es necesario configurar opacity por primera LayerInstruction, por ejemplo .:

[FirstlayerInstruction setOpacity:0.0 atTime:firstAsset.duration];