8

我正在合并多个视频和多首歌曲,我发现代码中有什么问题,因为昨天相同的代码运行得非常好,但今天我得到了以下响应 AVAssetExportSessionStatus = 4,error = Error Domain=AVFoundationErrorDomain Code=-11841 "The operation couldn’t be completed. (AVFoundationErrorDomain error -11841.)" ,我做了一些研究,发现导出失败是由于视频合成无效。请找出视频合成有什么问题。

- (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);
}
4

3 回答 3

7

我在遇到同样问题时发现了您的问题。我在这个问题上的理论是视频合成的所有属性都没有在导出时设置,所以它很糟糕。这是我现在使用的节,它现在导致无错误导出:

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];

就我而言,我错过了指令中的 timeRange 属性。检查您自己的属性以确保它们获得正确的值。祝你好运!这东西很难。

于 2012-11-25T23:37:13.917 回答
1

如果您碰巧将多个主指令传递给 AVMutableVideoComposition 的指令数组,请确保时间范围不重叠,否则会导致此错误。

于 2018-04-13T14:17:13.977 回答
-2

您需要opacity为第一个设置LayerInstruction,例如:

[FirstlayerInstruction setOpacity:0.0 atTime:firstAsset.duration];
于 2013-12-30T01:58:41.013 回答