AVFoundation – AVVideoComposition AVMutableVideoComposition 管理所有视频轨道

AVFoundation – AVVideoComposition AVMutableVideoComposition 管理所有视频轨道

零基础 Object-C 学习路线推荐 : Object-C 学习目录 >> Object-C 基础

零基础 Object-C 学习路线推荐 : Object-C 学习目录 >> Object-C 线程

零基础 Object-C 学习路线推荐 : Object-C 学习目录 >> OpenGL ES

零基础 Object-C 学习路线推荐 : Object-C 学习目录 >> GPUImage

零基础 Object-C 学习路线推荐 : Object-C 学习目录 >> AVFoundation

零基础 Object-C 学习路线推荐 : Object-C 学习目录 >> CocoaPods


一.前言

1.AVAsset

Assets 可以来自一个文件或用户的相册,可以理解为多媒体资源,通过 URL 作为一个 asset 对象的标识. 这个 URL 可以是本地文件路径或网络流;


2.AVAssetTrack

AVAsset 包含很多轨道 AVAssetTrack 的结合,如 audio, video, text, closed captions, subtitles…


3.AVComposition / AVMutableComposition

使用 AVMutableComposition 类可以增删 AVAsset 来将单个或者多个 AVAsset 集合到一起,用来合成新视频。除此之外,若想将集合到一起的视听资源以自定义的方式进行播放,需要使用 AVMutableAudioMix 和 AVMutableVideoComposition 类对其中的资源进行协调管理;


4.AVMutableVideoComposition

AVFoundation 类 API 中最核心的类是 AVVideoComposition / AVMutableVideoComposition 。

AVVideoComposition / AVMutableVideoComposition 对两个或多个视频轨道组合在一起的方法给出了一个总体描述。它由一组时间范围和描述组合行为的介绍内容组成。这些信息出现在组合资源内的任意时间点。

AVVideoComposition / AVMutableVideoComposition 管理所有视频轨道,可以决定最终视频的尺寸,裁剪需要在这里进行;


5.AVMutableCompositionTrack

多个 AVAsset 集合到一起合成新视频中轨道信息,有音频轨、视频轨等,里面可以插入各种对应的素材(画中画,水印等);


6.AVMutableVideoCompositionLayerInstruction

AVMutableVideoCompositionLayerInstruction 主要用于对视频轨道中的一个视频处理缩放、模糊、裁剪、旋转等;


7.AVMutableVideoCompositionInstruction

表示一个指令,决定一个 timeRange 内每个轨道的状态,每一个指令包含多个 AVMutableVideoCompositionLayerInstruction ;而 AVVideoComposition 由多个 AVVideoCompositionInstruction 构成;

AVVideoCompositionInstruction 所提供的最关键的一段数据是组合对象时间轴内的时间范围信息。这一时间范围是在某一组合形式出现时的时间范围。要执行的组全特质是通过其 AVMutableVideoCompositionLayerInstruction 集合定义的。


8.AVAssetExportSession

AVAssetExportSession 主要用于导出视频;


二.AVMutableVideoComposition简介


1.创建视频合成对象

/*
*函数描述:返回一个新的可变视频合成
*/
+ (AVMutableVideoComposition *)videoComposition;

2.指定媒体,创建视频组合对象

/*
*函数描述:创建并返回配置为显示指定AVAsset的视频轨道的视频合成对象
*
*函数参数:
*    asset:配置与视频合成的预期使用相匹配的资源
*/
+ (AVVideoComposition *)videoCompositionWithPropertiesOfAsset:(AVAsset *)asset;

此方法创建 AVVideoComposition 对象,并使用适合于呈现指定资产的视频轨道的值和指令对其进行配置。 返回的对象包含遵循指定资产的视频轨道的空间属性和时间范围的指令。


3.frameDuration

@property (nonatomic) CMTime frameDuration;

视频合成应该渲染合成视频帧的时间间隔;


4.renderSize

@property (nonatomic) CGSize renderSize;

视频合成渲染的大小,如果 asset 是 AVComposition 对象,则将值设置为合成的 naturalSize 属性的值;如果不是,则将该值设置为包含所有资产视频轨道的值;


5.instructions

@property (nonatomic, copy) NSArray<id <AVVideoCompositionInstruction>> *instructions;

视频合成说明;该数组包含 AVVideoCompositionInstruction 的实例。对于数组中的第一条指令,timeRange.start 必须小于或等于将尝试播放或其他处理的最早时间,通常为 kCMTimeZero 。对于后续指令,timeRange.start 必须等于先前指令的结束时间。最后一条指令的结束时间必须大于或等于将尝试播放或其他处理的最新时间,通常是与 AVVideoComposition 实例关联的资产的持续时间。


6.animationTool

@property (nonatomic, retain, nullable) AVVideoCompositionCoreAnimationTool *animationTool;

在离线渲染中与 Core Animation 一起使用的视频合成工具;这个属性可能是nil。如果将合成与 AVAssetExportSession 一起用于离线渲染,而不是与 AVPlayer 一起,则可以设置一个动画工具。


7.renderScale

@property (nonatomic) float renderScale;

视频合成渲染的比例。这个值必须是 1.0,除非合成设置在 AVPlayerItem 上。


8.customVideoCompositorClass

@property (nonatomic, retain, nullable) Class<AVVideoCompositing> customVideoCompositorClass; 

要使用的自定义合成器类;默认为 nil ,表示使用的是内部视频合成程序。 customVideoCompositorClass 必须实现 AVVideoCompositing 协议。


9.验证时间范围

/*
*函数描述:检查合成指令的时间范围是否符合验证要求
*
*参数描述:
*   asset:根据资产的持续时间验证指令的时间范围,并根据资产的轨道验证层指令的trackID;如果nil则跳过验证;
*   timeRange:一个时间范围;只有那些时间范围与此时间范围重叠的指令才会被验证。
*              要验证所有可能用于回放或其他处理的指令,不管时间范围如何,
*              请通过CMTimeRangeMake(kCMTimeZero, kCMTimePositiveInfinity)。
*   validationDelegate:表示实现AVVideoCompositionValidationHandling协议的对象,
               用于在处理期间接收有关视频合成中有问题部分的详细信息。如果不想被告知细节,请通过nil。
*
*函数返回值:如果合成指令的时间范围符合验证要求,则为YES,否则为NO
*
*/
- (BOOL)isValidForAsset:(AVAsset *)asset 
              timeRange:(CMTimeRange)timeRange
     validationDelegate:(id<AVVideoCompositionValidationHandling>)validationDelegate;

10.创建和配置AVVideoComposition

/******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:AVFoundation – AVVideoComposition AVMutableVideoComposition 管理所有视频轨道
//@Time:2021/08/16 07:30
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/******************************************************************************************/ 


AVMutableVideoComposition* videoComposition = [AVMutableComposition videoComposition];

videoComposition.instructions = compositionInstrutions;
videoComposition.renderSize = CGSizeMake(1280.0f, 720.0f);
videoComposition.frameDuration = CMTimeMake(1, 30);

三.AVMutableVideoComposition 裁剪视频

1.加载媒体

/******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:AVFoundation – AVVideoComposition AVMutableVideoComposition 管理所有视频轨道
//@Time:2021/08/16 07:30
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/******************************************************************************************/ 

1.将素材拖入到素材库中
AVAsset *asset = [AVAsset assetWithURL:outputFileURL];

//素材的视频轨
AVAssetTrack *videoAssetTrack = [[asset tracksWithMediaType:AVMediaTypeVideo]objectAtIndex:0];

//素材的音频轨
AVAssetTrack *audioAssertTrack = [[asset tracksWithMediaType:AVMediaTypeAudio]objectAtIndex:0];

2.插入视频轨/音频轨

/******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:AVFoundation – AVVideoComposition AVMutableVideoComposition 管理所有视频轨道
//@Time:2021/08/16 07:30
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/******************************************************************************************/ 

//重建组合,重构asset
AVMutableComposition *composition = [AVMutableComposition composition];

 //视频轨道
AVMutableCompositionTrack *videoCompositionTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];

 //在视频轨道插入一个时间段的视频
[videoCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAssetTrack.timeRange.duration) ofTrack:videoAssetTrack atTime:kCMTimeZero error:nil];

//音频轨道
AVMutableCompositionTrack *audioCompositionTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];

 //插入音频数据,否则没有声音
[audioCompositionTrack insertTimeRange: CMTimeRangeMake(kCMTimeZero, videoAssetTrack.timeRange.duration) ofTrack:audioAssertTrack atTime:kCMTimeZero error:nil];

3.裁剪视频

将所有视频轨进行裁剪,就需要得到所有的视频轨,而得到一个视频轨就需要得到它上面所有的视频素材

/******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:AVFoundation – AVVideoComposition AVMutableVideoComposition 管理所有视频轨道
//@Time:2021/08/16 07:30
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/******************************************************************************************/ 

AVMutableVideoCompositionLayerInstruction *videoCompositionLayerIns = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoAssetTrack];

[videoCompositionLayerIns setTransform:videoAssetTrack.preferredTransform atTime:kCMTimeZero];

//得到视频素材(这个例子中只有一个视频)
AVMutableVideoCompositionInstruction *videoCompositionIns = [AVMutableVideoCompositionInstruction videoCompositionInstruction];

[videoCompositionIns setTimeRange:CMTimeRangeMake(kCMTimeZero, videoAssetTrack.timeRange.duration)];


//得到视频轨道(这个例子中只有一个轨道)
AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
videoComposition.instructions = @[videoCompositionIns];
videoComposition.renderSize = CGSizeMake(...); //设置裁剪区域
videoComposition.frameDuration = CMTimeMake(1, 30);

4.导出

/******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:AVFoundation – AVVideoComposition AVMutableVideoComposition 管理所有视频轨道
//@Time:2021/08/16 07:30
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/******************************************************************************************/ 


AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetMediumQuality];
exporter.videoComposition = videoComposition;exporter.outputURL = [NSURL fileURLWithPath:_outputFilePath isDirectory:YES];
exporter.outputFileType = AVFileTypeMPEG4;
exporter.shouldOptimizeForNetworkUse = YES;
[exporter exportAsynchronouslyWithCompletionHandler:^{     
    if (exporter.error) {       
    //...    
    }else{        
    //...         
    }   
 }];


四.猜你喜欢


推荐文章

发表评论