使用AVMutableComposition合并视频会导致无音频

3

我有一个包含视频NSURL列表的NSArray,我想将它们合并成一个长的编译。问题在于,当我使用下面的代码时,视频会合并在一起,但没有音频。

- (IBAction)buildVideo {

// 1 - Create AVMutableComposition object. This object will hold your AVMutableCompositionTrack instances.
AVMutableComposition *mixComposition = [[AVMutableComposition alloc] init];

AVMutableCompositionTrack *track = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo
                                                               preferredTrackID:kCMPersistentTrackID_Invalid];

int i = 0;

for (id object in movieArray) {

    AVAsset *asset = [AVAsset assetWithURL:object];

    if(i == 0){

        [track insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration)
                       ofTrack:[[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:kCMTimeZero error:nil];


    }else {

        [track insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration)
                       ofTrack:[[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:[mixComposition duration] error:nil];

    }

    i = i + 1;

}

// 4 - Get path
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *myPathDocs =  [documentsDirectory stringByAppendingPathComponent:
                         [NSString stringWithFormat:@"mergeVideo-%d.mov",arc4random() % 1000]];
NSURL *url = [NSURL fileURLWithPath:myPathDocs];
// 5 - Create exporter
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition
                                                                  presetName:AVAssetExportPresetHighestQuality];
exporter.outputURL=url;
exporter.outputFileType = AVFileTypeQuickTimeMovie;
exporter.shouldOptimizeForNetworkUse = YES;
[exporter exportAsynchronouslyWithCompletionHandler:^{
    dispatch_async(dispatch_get_main_queue(), ^{
        [self exportDidFinish:exporter];
    });
}];

}

1个回答

9

您无法获得音频的原因是未添加音频轨道。您需要创建一个附加的AVMutableCompositionTrack,类型为AVMediaTypeAudio

AVMutableComposition *mixComposition = [[AVMutableComposition alloc] init];

AVMutableCompositionTrack *videoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo
                                                           preferredTrackID:kCMPersistentTrackID_Invalid];

AVMutableCompositionTrack *audioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio
                                                           preferredTrackID:kCMPersistentTrackID_Invalid];

并将源音频和视频轨道的时间范围插入到两个合成轨道中:
CMTime insertTime = kCMTimeZero;

for (id object in movieArray) {

    AVAsset *asset = [AVAsset assetWithURL:object];

    CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration);

    [videoTrack insertTimeRange:timeRange
                        ofTrack:[[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]
                         atTime:insertTime
                          error:nil];

    [audioTrack insertTimeRange:timeRange
                         ofTrack:[[asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]
                          atTime:insertTime
                           error:nil];

    insertTime = CMTimeAdd(insertTime,asset.duration);
}

movieArray 的用途是什么? - Gaurav
@Guarav 在OP的问题中提到了movieArray。我猜它是一个NSURL对象的数组。 - ChrisH
@ChrisH 很棒的答案,救了我的一天。 - Jignesh Chanchiya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接