在我的应用程序中,我试图动态合并视频剪辑 . 我有两个属性保存前一个录音,然后下一个录音将附加到结尾 . 这基本上充当了暂停功能,然后用户可以即时播放 .

我让应用程序将第一个剪辑写入docs目录中的“video.mp4” . 这被设置为先前的录制 . 然后我将下一个剪辑写入“video2.mp4”,将其设置为下一个录制,并使用AVMutableComposition将它们合并在一起:

AVMutableComposition *mashVideosTogether = [AVMutableComposition composition];
NSError *error;

if([mashVideosTogether insertTimeRange:
                 CMTimeRangeMake(kCMTimeZero, [self.previousRecording duration])
                 ofAsset:self.previousRecording 
                 atTime:kCMTimeZero 
                 error:&error]) NSLog(@"Successfully added one");
else NSLog(@"error: %@", error.description);

if([mashVideosTogether insertTimeRange:
                 CMTimeRangeMake(kCMTimeZero, [self.nextRecording duration])
                 ofAsset:self.nextRecording 
                 atTime:CMTimeAdd(kCMTimeZero, [self.previousRecording duration])
                 error:&error]) NSLog(@"Success on 2");
else NSLog(@"error: %@", error.description);

这会附加第一个和第二个视频 . 然后我将视频导出到“combined.mp4”,当成功完成后,我将删除“video.mp4”中的文件,并将组合视频导出到“video.mp4”(所以此时组合的视频存在在两个地方) . 这在我的播放器中播放得很好 . 如果用户再次点击记录,则将“video.mp4”处的新组合视频设置为先前记录,并将新记录的剪辑设置为下一记录,并重复整个过程 . 它们被重新附加和导出以重复该过程 .

但是,一旦我添加了第三个(或更多)剪辑,创建的合成中的第一个剪辑在播放时变为黑色 . 它们的持续时间仍然存在,但没有视频或声音 . 基本上,每当我从一个旧作品创建一个新的作品时,第一个作品就会显示为空白,然后唯一保留的是它们的持续时间和新的录音 . 当组合物再制成另一种组合物时,这些数据会丢失吗?我需要手动将它们添加为曲目吗?任何帮助表示赞赏!

SOLVED

我读过Apple的AVEditDemo,好像我原来的假设是正确的 - 当我单独使用AVMutableComposition将视频附加在一起时(AKA没有创建单独的轨道文件并合并它们),这些轨道的数据在添加到另一个轨道时丢失了组成 .

所以我只创建了每个剪辑的音频和视频的单独轨道以合并它们,现在我有一个工作设置,我可以动态地拍摄视频,停止,然后再次开始拍摄,它们将在运行中连接 .

if(self.previousRecording && self.nextRecording) {
    NSArray *assetArray = [NSArray arrayWithObjects:
                           self.previousRecording, self.nextRecording, nil];
    NSURL *fileURL = [self getURLWithPathComponent:@"combined.mp4"];

    AVMutableComposition *mashVideosTogether = [AVMutableComposition composition];
    NSError *error;

    CMTime nextClipStartTime = kCMTimeZero;

    AVMutableCompositionTrack *compositionVideoTrack = 
    [mashVideosTogether addMutableTrackWithMediaType:AVMediaTypeVideo
    preferredTrackID:kCMPersistentTrackID_Invalid];

    AVMutableCompositionTrack *compositionAudioTrack = 
    [mashVideosTogether addMutableTrackWithMediaType:AVMediaTypeAudio 
    preferredTrackID:kCMPersistentTrackID_Invalid];

    for(int i=0; i<[assetArray count]; i++) {
        AVURLAsset *asset = [assetArray objectAtIndex:i];

        CMTimeRange timeRangeInAsset = CMTimeRangeMake(kCMTimeZero, [asset duration]);

        AVAssetTrack *clipVideoTrack = 
        [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];

        [compositionVideoTrack insertTimeRange:timeRangeInAsset 
        ofTrack:clipVideoTrack atTime:nextClipStartTime error:nil];

        AVAssetTrack *clipAudioTrack = 
        [[asset tracksWithMediaType:AVMediaTypeAudio]objectAtIndex:0];

        [compositionAudioTrack insertTimeRange:timeRangeInAsset 
        ofTrack:clipAudioTrack atTime:nextClipStartTime error:nil];

        nextClipStartTime = CMTimeAdd(nextClipStartTime, timeRangeInAsset.duration);
    }

    //do exports down here and then reset previous recording, etc.
}