1

在我的应用程序中,我试图动态合并视频剪辑。我有两个属性保存上一个记录,然后将下一个记录附加到末尾。这基本上是作为一个暂停功能,然后用户可以即时播放。

我让应用程序将第一个剪辑写入 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”处新组合的视频设置为上一次录制,将新录制的剪辑设置为下一次录制,重复整个过程。它们被附加并再次导出以重复该过程。

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

解决了

我阅读了 Apple 的 AVEditDemo,似乎我最初的假设是正确的——当我单独使用 AVMutableComposition 将视频附加在一起时(也就是不创建单独的轨道文件并合并它们),这些轨道的数据在添加到另一个时丢失了作品。

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

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.
}
4

0 回答 0