AVF 10 - 音视频组合编辑

AVF 10 - 音视频组合编辑


一、简要说明

相关类

  • AVMutableComposition
  • AVMutableCompositionTrack

二、使用

1、音频和视频合成

- (void)testCom1{
  
    AVMutableComposition *mutableComposition = [AVMutableComposition composition];
     
    AVMutableCompositionTrack *compositionVideoTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo
                                                                                       preferredTrackID:kCMPersistentTrackID_Invalid];
  
    AVMutableCompositionTrack *compositionAudioTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio
                                                                                       preferredTrackID:kCMPersistentTrackID_Invalid];
    
  // 获取资源
    AVURLAsset *asset1 = [[AVURLAsset alloc] initWithURL:self.movieFile1 options:nil];
    AVURLAsset *asset2 = [[AVURLAsset alloc] initWithURL:self.musicFile1 options:nil];
 
    AVAssetTrack *videoAssetTrack  = [asset1 tracksWithMediaType:AVMediaTypeVideo][0];
    AVAssetTrack *audioAssetTrack  = [asset2 tracksWithMediaType:AVMediaTypeAudio][0];
     
     
    // 指定位置放入 视频和 音频
    [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAssetTrack.timeRange.duration)
                                   ofTrack:videoAssetTrack
                                    atTime:kCMTimeZero
                                     error:nil];
 
    [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAssetTrack.timeRange.duration)
                                   ofTrack:audioAssetTrack
                                    atTime:kCMTimeZero
                                     error:nil]; 
  
  
    AVAssetExportSession *assetExportSession = [[AVAssetExportSession alloc] initWithAsset:mutableComposition
                                                                                presetName:AVAssetExportPreset1280x720]; 
    NSTimeInterval timestamp = [NSDate timeIntervalSinceReferenceDate];
    NSString *filename = [NSString stringWithFormat:@"%f.m4a", timestamp];
    NSString *docsDir = NSSearchPathForDirectoriesInDomains(NSDesktopDirectory, NSUserDomainMask, YES).firstObject;
    NSString *destPath = [docsDir stringByAppendingPathComponent:filename];
    NSString *composedMoviePath = [NSURL fileURLWithPath:destPath];
    
    
    // 导出
    NSURL *composedMovieUrl = [NSURL fileURLWithPath:composedMoviePath];
    assetExportSession.outputFileType              = AVFileTypeQuickTimeMovie;
    assetExportSession.outputURL                   = composedMovieUrl;
    assetExportSession.shouldOptimizeForNetworkUse = YES;
    
    NSLog(@"composedMovieUrl : %@",composedMovieUrl);
    
  
    [assetExportSession exportAsynchronouslyWithCompletionHandler:^{
        switch (assetExportSession.status) {
            case AVAssetExportSessionStatusFailed: {
                NSLog(@"生成失敗");
                break;
            }
            case AVAssetExportSessionStatusCancelled: {
                NSLog(@"生成会话被取消");
                break;
            }
            default: {
                NSLog(@"生成完了");
                [[NSWorkspace sharedWorkspace] selectFile:composedMovieUrl.path inFileViewerRootedAtPath:nil];
                break;
            }
        }
    }];
}


2、视频的拼接

#pragma mark - 视频的拼接
- (void)testCom2
{
    AVMutableComposition *mutableComposition = [AVMutableComposition composition];
     
    AVURLAsset *videoAsset1 = [[AVURLAsset alloc] initWithURL:self.movieFile1 options:nil];  // URLHookmark
    AVURLAsset *videoAsset2 = [[AVURLAsset alloc] initWithURL:self.movieFile2 options:nil];  // FurShader 无声
     
    AVAssetTrack *videoAssetTrack1 = [videoAsset1 tracksWithMediaType:AVMediaTypeVideo][0];
    AVAssetTrack *audioAssetTrack1 = [videoAsset1 tracksWithMediaType:AVMediaTypeAudio][0];
    
    AVAssetTrack *videoAssetTrack2 = [videoAsset2 tracksWithMediaType:AVMediaTypeVideo][0];
    AVAssetTrack *audioAssetTrack2 = [videoAsset2 tracksWithMediaType:AVMediaTypeAudio][0];
     
    AVMutableCompositionTrack *compositionVideoTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo
                                                                                       preferredTrackID:kCMPersistentTrackID_Invalid];
    // 音声合成用の`AVMutableCompositionTrack`を生成
    AVMutableCompositionTrack *compositionAudioTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio
                                                                                       preferredTrackID:kCMPersistentTrackID_Invalid];
     
    [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAssetTrack1.timeRange.duration)
                                   ofTrack:videoAssetTrack1
                                    atTime:kCMTimeZero
                                     error:nil];
 
    [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAssetTrack1.timeRange.duration)
                                   ofTrack:audioAssetTrack1
                                    atTime:kCMTimeZero
                                     error:nil];
    
    // 追加
    [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAssetTrack2.timeRange.duration)
                                   ofTrack:videoAssetTrack2
                                    atTime:videoAssetTrack1.timeRange.duration
                                     error:nil];
    [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAssetTrack2.timeRange.duration)
                                   ofTrack:audioAssetTrack2
                                    atTime:audioAssetTrack1.timeRange.duration
                                     error:nil];
   
  
    AVAssetExportSession *assetExportSession = [[AVAssetExportSession alloc] initWithAsset:mutableComposition
                                                                                presetName:AVAssetExportPreset1280x720];
 
    
    // エクスポートファイルの設定
    NSString *composedMovieDirectory = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
    NSString *composedMoviePath      = [NSString stringWithFormat:@"%@/%@", composedMovieDirectory, @"test.mp4"];
    
    // すでに合成動画が存在していたら消す
    NSFileManager *fileManager = NSFileManager.defaultManager;
    if ([fileManager fileExistsAtPath:composedMoviePath]) {
        [fileManager removeItemAtPath:composedMoviePath error:nil];
    }
    
    // 保存設定
    NSURL *composedMovieUrl = [NSURL fileURLWithPath:composedMoviePath];
    assetExportSession.outputFileType              = AVFileTypeQuickTimeMovie;
    assetExportSession.outputURL                   = composedMovieUrl;
    assetExportSession.shouldOptimizeForNetworkUse = YES;
    
    NSLog(@"composedMovieUrl : %@",composedMovieUrl);
    
    // 動画をExport
    [assetExportSession exportAsynchronouslyWithCompletionHandler:^{
        
                switch (assetExportSession.status) {
                    case AVAssetExportSessionStatusFailed: {
                        NSLog(@"生成失敗");
                        break;
                    }
                    case AVAssetExportSessionStatusCancelled: {
                        NSLog(@"生成会话被取消");
                        break;
                    }
                    default: {
                        NSLog(@"生成完了");
        //                if (self.handler) {
        //                    self.handler(composedMovieUrl);
        //                }
                        [[NSWorkspace sharedWorkspace] selectFile:composedMovieUrl.path inFileViewerRootedAtPath:nil];
                        break;
                    }
                }
    }];
}
发布了43 篇原创文章 · 获赞 8 · 访问量 4556

猜你喜欢

转载自blog.csdn.net/weixin_45390999/article/details/104608697
今日推荐