iOS

最近更新时间:2025-03-21 11:36:12

我的收藏

功能概览

视频编辑包括视频裁剪、时间特效(慢动作、倒放、重复)、滤镜特效(动感光波、暗黑幻影、灵魂出窍、画面分裂)、滤镜风格(唯美、粉嫩、蓝调等)、音乐混音、动态贴纸、静态贴纸、气泡字幕等功能。

相关类介绍

类名
功能
TXVideoInfoReader.h
媒体信息获取
TXVideoEditer.h
视频编辑

视频编辑基本使用流程

1. 设置视频预览参数及视频路径。
2. 开始预览
3. 添加效果。
4. 生成视频到指定文件
5. 监听和处理生成事件

示例

// 这以使用了 Demo 中的 Common/UGC/VideoPreview 来做预览的视图
#import "VideoPreview.h"

@implementation EditViewController
{
TXVideoEditer *editor;
VideoPreview *_videoPreview;
}

- (void)viewDidLoad {
[super viewDidLoad];
_videoPreview = [[VideoPreview alloc] initWithFrame:self.view.bounds];
[self.view addSubview:_videoPreview];
// 编辑预览参数
TXPreviewParam *param = [[TXPreviewParam alloc] init];
param.videoView = _videoPreview.renderView;
param.renderMode = PREVIEW_RENDER_MODE_FILL_EDGE;

// 1. 初始化编辑器, 如无需预览,可以传 nil 或直接调用 init 方法
TXVideoEditer *editor = [[TXVideoEditer alloc] initWithPreview:param];

// 设置源视频路径
NSString *path = [[NSBundle mainBundle] pathForResource:@"demo" ofType:@"mp4"]
[editor setVideoPath: path];

// 配置代理
editor.generateDelegate = self; // 设置生成事件的回调委托对象,可以获取生成进度与结果

// 2. 对视频进行处理,这里以添加水印为例
[editor setWaterMark:[UIImage imageNamed:@"water_mark"]
normalizationFrame:CGRectMake(0,0,0.1,0)];
}

// 3. 生成视频, 以响应用户点击为例
- (IBAction)onGenerate:(id)sender {
NSString *output = [NSTemporaryDirectory() stringByAppendingPathComponent:@"temp.mp4"];
[editor generateVideo:VIDEO_COMPRESSED_720P videoOutputPath:output];
}

// 4. 获取生成进度
-(void) onGenerateProgress:(float)progress
{
}

// 获取生成结果
-(void) onGenerateComplete:(TXGenerateResult *)result
{
if (result.retCode == 0) {
// 生成成功
} else {
// 生成失败,原因可以查看 result.descMsg
}
}
@end

视频信息获取

TXVideoInfoReadergetVideoInfo方法可以获取指定视频文件的一些基本信息,相关接口如下:
// 获取视频文件的信息
+ (TXVideoInfo *)getVideoInfo:(NSString *)videoPath;

/** 获取视频文件信息
* @param videoAsset 视频文件属性
* @return 视频信息
*/
+ (TXVideoInfo *)getVideoInfoWithAsset:(AVAsset *)videoAsset;

返回的TXVideoInfo定义如下:
/// 视频信息
@interface TXVideoInfo : NSObject
/// 视频首帧图片
@property (nonatomic, strong) UIImage* coverImage;
/// 视频时长(s)
@property (nonatomic, assign) CGFloat duration;
/// 视频大小(byte)
@property (nonatomic, assign) unsigned long long fileSize;
/// 视频fps
@property (nonatomic, assign) float fps;
/// 视频码率 (kbps)
@property (nonatomic, assign) int bitrate;
/// 音频采样率
@property (nonatomic, assign) int audioSampleRate;
/// 视频宽度
@property (nonatomic, assign) int width;
/// 视频高度
@property (nonatomic, assign) int height;
/// 视频旋转角度
@property (nonatomic, assign) int angle;
@end

缩略图获取

缩略图的接口主要用于生成视频编辑界面的预览缩略图,或获取视频封面等。

1. 按个数平分时间获取缩略图

TXVideoInfoReadergetSampleImages可以获取按指定数量,时间间隔相同的预览图:
/** 获取视频的采样图列表
* @param count 获取的采样图数量(均匀采样)
* @param maxSize 缩略图的最大大小,生成的缩略图大小不会超出这个宽高
* @param videoAsset 视频文件属性
* @param sampleProcess 采样进度
*/
+ (void)getSampleImages:(int)count
maxSize:(CGSize)maxSize
videoAsset:(AVAsset *)videoAsset
progress:(sampleProcess)sampleProcess;

+ (void)getSampleImages:(int)count
videoPath:(NSString *)videoPath
progress:(sampleProcess)sampleProcess;


+ (void)getSampleImages:(int)count
videoAsset:(AVAsset *)videoAsset
progress:(sampleProcess)sampleProcess;

开发包中的VideoRangeSlider是用了getSampleImages获取了10张缩略图来构建一个由视频预览图组成的进度条。

2. 根据时间列表获取缩略图

/**
* 根据时间列表获取缩略图列表
* @param asset 视频文件对象
* @param times 获取的时间列表
* @param maxSize 缩略图大小
*/
+ (UIImage *)getSampleImagesFromAsset:(AVAsset *)asset
times:(NSArray<NSNumber*> *)times
maxSize:(CGSize)maxSize
progress:(sampleProcess)sampleProcess;

/* 根据时间获取单帧图片
* @param time 获取图片的时间
* @param videoPath 视频文件路径*/
+ (nullable UIImage *)getSampleImage:(float)time videoPath:(NSString *)videoPath;

+ (nullable UIImage *)getSampleImage:(float)time videoAsset:(AVAsset *)videoAsset;

编辑预览

视频编辑提供了定点预览(将视频画面定格在某一时间点)与区间预览(循环播放某一时间段 A<=>B 内的视频片段)两种效果预览方式,使用时需要给 SDK 绑定一个 UIView 用于显示视频画面。

1. 设置预览播放的 UIView

TXVideoEditerinitWithPreview函数用于绑定一个 UIView 给 SDK 来渲染视频画面,通过控制TXPreviewParamrenderMode来设置自适应填充两种模式。
/** 默认初始化方法
* @param param 编辑器画面预览参数
* @see TXPreviewParam
*/
- (instancetype)initWithPreview:(TXPreviewParam *)param;


@interface TXPreviewParam : NSObject
@property(nonatomic, strong) UIView* videoView; // 视频预览View
@property(nonatomic, assign) TXPreviewRenderMode renderMode; // 填充模式
@end


PREVIEW_RENDER_MODE_FILL_SCREEN - 填充模式,尽可能充满屏幕不留黑边,所以可能会裁剪掉一部分画面。
PREVIEW_RENDER_MODE_FILL_EDGE - 适应模式,尽可能保持画面完整,但当宽高比不合适时会有黑边出现。

2. 定点预览

TXVideoEditerpreviewAtTime函数用于定格显示某一个时间点的视频画面。
/** 渲染某一时刻的视频画面
* @param time 预览帧时间(s)
*/
- (void)previewAtTime:(CGFloat)time;

3. 区间预览

TXVideoEditerstartPlayFromTime函数用于循环播放某一时间段 A<=>B 内的视频片段。
/** 播放某一时间段的视频
* @param startTime 播放起始时间(s)
* @param endTime 播放结束时间(s)
*/
- (void)startPlayFromTime:(CGFloat)startTime
toTime:(CGFloat)endTime;

4. 预览的暂停与恢复

// 暂停播放
- (void)pausePlay;
// 继续播放
- (void)resumePlay;
// 停止播放
- (void)stopPlay;

美颜滤镜

您可以给视频添加滤镜效果,例如美白、浪漫、清新等滤镜。另外您还可以设置组合滤镜,组合滤镜一般用于两个滤镜切换过程中。
// 其中 image 为滤镜映射图,image 设置为 nil,会清除滤镜效果。
- (void) setFilter:(UIImage *)image;


// 设置滤镜效果程度从0到1,越大滤镜效果越明显,默认取值0.5
- (void)setSpecialRatio:(float)specialRatio;

/**
* 设置两个滤镜效果
* @param leftFilter 左滤镜图片(nil代表无左滤镜)
* @param leftIntensity 左滤镜浓度
* @param rightFilter 右滤镜图片(nil代表无右滤)
* @param rightIntensity 右滤镜浓度
* @param leftRatio 左滤镜所占比例
*/

- (void)setFilter:(UIImage *)leftFilter
leftIntensity:(CGFloat)leftIntensity
rightFilter:(UIImage *)rightFilter
rightIntensity:(CGFloat)rightIntensity
leftRatio:(CGFloat)leftRatio;
Demo 示例:
TXVideoEditer *_ugcEdit;
NSString * path = [[NSBundle mainBundle] pathForResource:@"FilterResource" ofType:@"bundle"];
path = [path stringByAppendingPathComponent:@"langman.png"];
UIImage* image = [UIImage imageWithContentsOfFile:path];
[_ugcEdit setFilter:image];
[_ugcEdit setSpecialRatio:0.5];

水印

1. 设置全局水印

您可以为视频设置水印图片,并且可以指定图片的位置。 设置水印的方法为:
- (void) setWaterMark:(UIImage *)waterMark normalizationFrame:(CGRect)normalizationFrame;
其中 waterMark 表示水印图片,normalizationFrame 是相对于视频图像的归一化 frame,frame 的 x、y、width、height 的取值范围都为0 - 1。

Demo 示例:

UIImage *image = [UIImage imageNamed:@"watermark"];
[_ugcEdit setWaterMark:image normalizationFrame:CGRectMake(0, 0, 0.3 , 0.3 * image.size.height / image.size.width)];//水印大小占视频宽度的30%,高度根据宽度自适应

2. 设置片尾水印

您可以为视频设置片尾水印,并且可以指定片尾水印的位置。 设置片尾水印的方法为:
- (void) setTailWaterMark:(UIImage *)tailWaterMark normalizationFrame:(CGRect)normalizationFrame
duration:(CGFloat)duration;
其中 tailWaterMark 表示片尾水印图片,normalizationFrame 是相对于视频图像的归一化 frame,frame 的 x、y、width、height 的取值范围都为0 - 1,duration 为水印的持续时长。

Demo 示例:

设置水印在片尾中间,持续时间1s。
UIImage *tailWaterimage = [UIImage imageNamed:@"tcloud_logo"];
float w = 0.15;
float x = (1.0 - w) / 2.0;
float width = w * videoMsg.width;
float height = width * tailWaterimage.size.height / tailWaterimage.size.width;
float y = (videoMsg.height - height) / 2 / videoMsg.height;
[_ugcEdit setTailWaterMark:tailWaterimage normalizationFrame:CGRectMake(x,y,w,0) duration:1];

编辑添加 BGM

//初始化编辑器
TXPreviewParam *param = [[TXPreviewParam alloc] init];
param.videoView = videoView;
param.renderMode = PREVIEW_RENDER_MODE_FILL_EDGE;
ugcEdit = [[TXVideoEditer alloc] initWithPreview:param];

//设置 BGM 路径
[ugcEdit setBGMAsset:fileAsset result:^(int result) {
}];

//设置 BGM 开始和结束时间
[ugcEdit setBGMStartTime:0 endTime:5];

//设置 BGM 是否循环
[ugcEdit setBGMLoop:YES];

//设置 BGM 在视频添加的起始位置
[ugcEdit setBGMAtVideoTime:0];

//设置视频声音大小
[ugcEdit setVideoVolume:1.0];

//设置 BGM 声音大小
[ugcEdit setBGMVolume:1.0];

压缩裁剪

1. 视频压缩

视频压缩调可以调用如下接口:
/**
* 优点:兼容性好,支持各种操作类型的视频生成,生成的视频文件在各个平台播放的兼容性好
* 缺点:生成视频速度稍慢
* 调用之后在TXVideoGenerateListener里面监听结果回调
* @param videoCompressed 视频压缩质量
* @param videoOutputPath 视频操作之后存储路径
*/

- (void)generateVideo:(TXVideoCompressed)videoCompressed
videoOutputPath:(NSString *)videoOutputPath;

/**
* 优点:生成视频速度快
* 缺点:1,剪切出来的视频在各个平台播放的兼容性稍差
* 2,只有剪切和压缩操作才会使用系统函数,其他情况系统不支持,SDK内部会自动走正常视频生成的逻辑
*/

- (void)quickGenerateVideo:(TXVideoCompressed)videoCompressed
videoOutputPath:(NSString *)videoOutputPath;

/**
* 两次扫描生成视频(Two-Pass Encoding) [精简版不支持]
* 优点:兼容性好,在同等码率下视频更加清晰,可以在较低码率下保持视频质量,
支持各种操作类型的视频生成,生成的视频文件在各个平台播放的兼容性好
* 缺点:生成视频慢
*/

- (void)generateVideoWithTwoPass:(TXVideoCompressed)videoCompressed
videoOutputPath:(NSString *)videoOutputPath;
参数 videoCompressed 在 TXVideoCompressed 中可选常量,定义如下:
typedef NS_ENUM(NSInteger, TXVideoCompressed) {
// 压缩至360P分辨率
VIDEO_COMPRESSED_360P = 0,
// 压缩至480P分辨率
VIDEO_COMPRESSED_480P = 1,
// 压缩至540P分辨率
VIDEO_COMPRESSED_540P = 2,
// 压缩至720P分辨率
VIDEO_COMPRESSED_720P = 3,
// 压缩至1080P分辨率
VIDEO_COMPRESSED_1080P = 4,
};
如果源视频的分辨率小于设置的常量对应的分辨率,按照原视频的分辨率。
如果源视频的分辨率大于设置的常量对象的分辨率,进行视频压缩至相应分辨率。

2. 裁剪区域设置

在调用generateVideo压缩视频的同时可以指定裁剪区域,如果未指定,则压缩整个文件。指定裁剪区域调用setCutFromTime接口。
/**
* 设置视频剪裁
* @param startTime 视频起始时间(s)
* @param endTime 视频结束时间(s)
*/
- (void)setCutFromTime:(float)startTime toTime:(float)endTime;

3. 视频码率设置

支持自定义视频的码率,这里建议设置的范围600 - 12000kbps,注意码率不要太大或太小,码率太大,视频的体积会很大,码率太小,视频会模糊不清。如果没有调用这个接口,SDK 内部会根据压缩质量自动计算码率。
- (void)setVideoBitrate:(int)bitrate;

4. 视频帧率设置

调用setVideoFrameRate接口可以设置视频帧率:
- (void)setVideoFramerate:(TXVideoFramerateLevel)framerate;

typedef NS_ENUM(NSInteger, TXVideoFramerateLevel) {
// 保持原帧率
VIDEO_FRAMERATE_ORIGIN = 0,
// 根据视频的分辨率和码率自动选择帧率
VIDEO_FRAMERATE_AUTO = -1,
// 15fps
VIDEO_FRAMERATE_15FPS = 15,
// 25fps
VIDEO_FRAMERATE_25FPS = 25,
// 30fps
VIDEO_FRAMERATE_30FPS = 30,
// 60fps
VIDEO_FRAMERATE_60FPS = 60,
};
VIDEO_FPS_ORIGIN 使用原始视频的帧率,未调用setVideoFrameRate接口时,默认是使用视频原始帧率。
VIDEO_FPS_AUTO 根据用户生成视频的分辨率,码率,SDK内部决策出一个合适的帧率。
VIDEO_FPS_15,VIDEO_FPS_25,VIDEO_FPS_30,VIDEO_FPS_60指定帧率为15,25,30,60。
如论用户传递的参数为什么,最终生成视频的帧率不会高于原始视频帧率。
如果您设置的帧率过小,最终导致生成的视频帧率过小,可能会让视频看起来不是很流畅。

高级功能