全部产品
云市场

导入编辑

更新时间:2019-06-14 09:08:55

功能介绍

短视频SDK提供视频编辑与导出功能,支持视频图片素材混合导入,提供滤镜,配音,时间特效,过渡效果等丰富的编辑效果,编辑核心类AliyunEditor

版本差异

版本 功能描述
专业版 支持所有功能
标准版 支持基础功能,高级功能需要License授权
基础版 不支持

导入编辑

视频导入编辑的流程如下:

编辑时序图

  • startEditstopEdit两者成对出现,调用startEdit方法后SDK内部会创建相关资源,调用stopEdit方法后SDK内部会销毁相关资源,页面销毁前必须调用stopEdit,否则会导致内存泄露。
  • 媒体片段需要在开始编辑前确定,因此媒体片段管理接口AliyunIClipConstructor的调用在startEdit之前。
  • 播放控制,编辑功能和合成导出的接口调用在startEditstopEdit之间。

初始化配置

生成TaskPath

taskPath是一个文件夹路径,文件夹中存放有包含视频素材路径,输出码率,GOP,分辨率等信息的配置文件以及临时文件。AliyunEdit通过taskPath中的配置文件读取参数信息。生成taskPath的方式有两种方法:

  • 录制到编辑的场景下,初始化录制模块AliyunIRecorder,为taskPath属性设置空的文件夹路径,调用录制相关接口将自动创建配置文件并添加视频素材资源。
  • 导入到编辑的场景下,初始化AliyunImporter,为taskPath参数设置空的文件夹路径,调用AliyunIClipConstructor协议方法添加视频素材资源,最后调用- (void)generateProjectConfigure方法创建配置文件。

AliyunImporter负责生成编辑配置文件,主要接口如下:

  • 初始化
  1. /**
  2. 初始化AliyunImporter
  3. @param taskPath taskPath文件夹地址,保证文件夹已存在
  4. @param outputSize 导出视频分辨率设置,必须为偶数
  5. @return AliyunImporter
  6. */
  7. - (instancetype)initWithPath:(NSString *)taskPath outputSize:(CGSize)outputSize;
  • 视频输出参数
  1. /**
  2. 设置视频输出参数
  3. @param videoParam 视频输出参数
  4. */
  5. - (void)setVideoParam:(AliyunVideoParam *)videoParam;
  • 生成配置文件
  1. /**
  2. /**
  3. 在taskPath目录下,生成配置文件
  4. */
  5. - (void)generateProjectConfigure;

AliyunImporter实现了AliyunIClipConstructor协议,用于配置媒体片段,添加媒体片段接口如下:

  1. - (void)addMediaClip:(AliyunClip *)clip;

其中参数AliyunClip代表一个视频或图片对象,我们可以通过初始化方法创建一个AliyunClip对象:

  • 创建视频片段
  1. /**
  2. 创建一个视频片段
  3. @param path 视频路径
  4. @param animDuration 过渡动画时长
  5. @return 视频片段
  6. */
  7. - (instancetype)initWithVideoPath:(NSString *)path
  8. animDuration:(CGFloat)animDuration;
  • 创建图片片段
  1. /**
  2. 创建一个图片片段
  3. @param path 图片路径
  4. @param duration 图片时长
  5. @param animDuration 过渡动画时长
  6. @return 图片片段
  7. */
  8. - (instancetype)initWithImagePath:(NSString *)path
  9. duration:(CGFloat)duration
  10. animDuration:(CGFloat)animDuration;
  • 创建GIF片段
  1. 创建一个gif片段
  2. @param path gif路径
  3. @return gif片段
  4. */
  5. - (instancetype)initWithGifPath:(NSString *)path;

初始化Editor

通过初始化方法创建AliyunEdit对象:

  1. /**
  2. @param taskPath 文件夹路径
  3. @param preview 编辑预览视图
  4. @return Editor
  5. */
  6. - (instancetype)initWithPath:(NSString *)taskPath preview:(UIView *)preview;

taskPath必须是已经生成好配置文件的文件夹路径preview表示预览UIView,预览UIView的长宽比和导出视频分辨率的长宽比需保持一致。如果只用来导出视频无需播放预览,直接传入nil即可。

媒体片段管理

编辑模块可以通过-(id<AliyunIClipConstructor>)getClipConstructor方法获取媒体片段管理器,实现媒体片段管理。AliyunIClipConstructor实现了添加与删除媒体片段的操作,具体接口如下:

  • 增加媒体片段

    1. /**
    2. @param clip 媒体片段
    3. */
    4. - (void)addMediaClip:(AliyunClip *)clip;
  • 设置所有媒体片段

    1. /**
    2. @param clips 媒体片段列表
    3. */
    4. - (void)setMediaClips:(NSArray<AliyunClip *> *)clips;
  • 增加媒体片段

    1. /**
    2. @param clip 媒体片段
    3. @param index index
    4. */
    5. - (void)addMediaClip:(AliyunClip *)clip atIndex:(NSInteger)index;
  • 更新媒体片段

    1. /**
    2. @param clip 媒体片段
    3. @param index index
    4. */
    5. - (void)updateMediaClip:(AliyunClip *)clip atIndex:(NSInteger)index;
  • 删除媒体片段

    1. /**
    2. @param index index
    3. */
    4. - (void)deleteMediaClipAtIndex:(NSInteger)index;
  • 删除所有媒体片段

    1. - (void)deleteAllMediaClips;
  • 获取媒体片段

    1. /**
    2. @param index index
    3. @return 媒体片段
    4. */
    5. - (AliyunClip *)mediaClipAtIndex:(NSInteger)index;
  • 获取所有媒体片段

    1. /**
    2. @return 媒体片段列表
    3. */
    4. - (NSArray<AliyunClip *> *)mediaClips;

    注意修改媒体片段操作需要在调用startEdit方法前,或调用stopEdit方法后执行。

播放控制

播放控制接口

通过接口获取播放器:

  1. - (id<AliyunIPlayer>)getPlayer;

播放器控制接口如下:

  • 开始播放

    1. - (int)play;
  • seek到某一时间点

    1. /**
    2. @param time 时间,单位:秒
    3. */
    4. -(int)seek:(float)time;
  • 绘制一帧

    1. /**
    2. @param time 时间,单位:秒
    3. */
    4. -(int)draw:(float)time;
  • 暂停播放

    1. - (int)pause;
  • 继续播放

    1. - (int)resume;
  • 是否正在播放

    1. /**
    2. @return 正在播放
    3. */
    4. - (BOOL)isPlaying;
  • 重新开始播放

    1. - (int)replay;
  • 停止播放

    1. /**
    2. * 正常返回 ALIVC_COMMON_RETURN_SUCCESS
    3. * 状态不正确 ALIVC_COMMON_INVALID_STATE
    4. */
    5. - (int)stop;
  • 获取总时长(秒)

    1. /**
    2. @return 总时长
    3. */
    4. - (double)getDuration;
  • 获取当前播放时间(秒)

    1. - (double)getCurrentTime;
  • 获取原始视频流时长(秒)

    1. /**
    2. @return 总时长
    3. */
    4. - (double)getStreamDuration;
  • 获取原始视频流播放时间(秒)

    1. - (double)getCurrentStreamTime;
  • 获取视频片段在播放时间轴上开始播放的时间(秒)

    1. /**
    2. @param idx 视频片段序列号
    3. @return 时间,单位:秒
    4. */
    5. - (double)getClipStartTimeAtIndex:(int)idx;
  • 设置播放器的刷新频率

    默认值:30帧/s,最大值:60帧/s,建议设置值不小于20帧/s。

    1. /**
    2. @param fps 帧
    3. */
    4. - (void)setRefreshFps:(double)fps;

播放回调监听

实现播放状态监听,需要实现delegate代理的AliyunIPlayerCallback协议,回调方法定义如下:

  • 开始播放

    1. - (void)playerDidStart;
  • 结束播放

    1. - (void)playerDidEnd;

    播放结束重新播放,需要调用replay方法。

  • seek结束

    1. - (void)seekDidEnd;
  • 播放进度

    1. /**
    2. @param playSec 播放时间
    3. @param streamSec 播放流时间
    4. */
    5. - (void)playProgress:(double)playSec streamProgress:(double)streamSec;
  • 播放异常

    1. /**
    2. @param errorCode 错误码
    3. */
    4. - (void)playError:(int)errorCode;

注意事项

  • 播放器接口调用对应关系:playstop对应,pauseresume对应。
  • 调用seek方法或添加编辑效果(MV、音乐等),播放器将进入pause状态,此时需要调用resume方法后才能继续播放。
  • 时间特效影响播放时间轴,播放器DurationStreamDurationCurrentTimeCurrentStreamTime的区别举例如下:
    • 总时长15s的视频,全程快速2倍播放。此时,getDuration为7.5s,假设getCurrentTime为3.5s,那么getStreamDuration为15s,getCurrentStreamTime为7s。
    • 总时长15s的视频,全程慢速2倍播放。此时,getDuration为30s,假设getCurrentTime为10s,那么 getStreamDuration为15s,getCurrentStreamTime为7.5s。
    • 总时长15s的视频,全程倒播。此时,getDuration为15s,假设getCurrentTime为6s,那么getStreamDuration为15s,getCurrentStreamTime为9s。

设置特效

滤镜

短视频SDK的滤镜资源存放在滤镜文件夹,滤镜文件夹包含配置文件和相关资源。AliyunEffectFilter代表一个滤镜资源,可以通过初始化方法构造一个滤镜实例,参数path是滤镜资源文件夹路径。

  • 生成滤镜对象

    1. - (id)initWithFile:(NSString *)path;
  • 添加一个滤镜

    1. - (int)applyFilter:(AliyunEffectFilter *)filter;

    由于滤镜无法叠加,因此每次调用applyFilter:方法都会替换滤镜。

  • 删除滤镜

    1. - (int)removeFilter;

    时间特效

    时间特效指的是对视频添加反复,变速,倒放等效果。AliyunEffectTimeFilter代表一个时间特效,调用示例如下:

    1. AliyunEffectTimeFilter *timeFilter = [[AliyunEffectTimeFilter alloc] init];
    2. // 时间特效开始时间
    3. timeFilter.startTime = 1;
    4. // 时间特效结束时间
    5. timeFilter.endTime = 2;
    6. // 变速特效
    7. timeFilter.type = TimeFilterTypeSpeed;
    8. // 0.5倍播放
    9. timeFilter.param = 0.5;
    10. // 应用时间特效
    11. [self.editor applyTimeFilter:timeFilter];
    12. // 使用时间特效后,处于暂停状态,调用resume继续播放
    13. [self.player resume];

    时间特效类型支持TimeFilterTypeSpeed变速,TimeFilterTypeRepeat反复,TimeFilterTypeInvert倒播三种。当设置为变速时,需要param属性指定播放速度。当设置为反复时,需要param属性指定反复次数。

倒播,反复特效只支持单段视频,且不支持与其他时间特效叠加。

使用倒播特效前建议先对视频转码,否则可能出现卡段。

MV

短视频SDK的MV资源存放在MV文件夹中,MV文件夹包含了配置文件和相关资源。下载的MV压缩包中有四种长宽比的MV文件夹,用来适配不同的输出分辨率。AliyunEffectMV代表一个MV资源,可以通过初始化方法构造一个MV实例,参数path是MV资源文件夹路径。

  • 生成MV对象

    1. - (id)initWithFile:(NSString *)path;
  • 添加一个MV

    1. - (int)applyMV:(AliyunEffectMV *)mv;

    由于滤镜无法叠加,因此每次调用applyMV:方法都会替换MV。

  • 删除MV

    1. - (int)removeMV;
  • 删除MV音乐

    MV自带音乐,删除音乐的接口如下:

    1. -(int)removeMVMusic;

音乐

AliyunEffectMusic代表一个音乐资源,可以通过初始化方法构造一个音乐实例,参数path是音乐资源文件路径。

  • 生成音乐对象

    1. - (id)initWithFile:(NSString *)path;
  • 添加音乐

    1. - (int)applyMusic:(AliyunEffectMusic *)music;
  • 删除某个音乐

    SDK支持多路音乐叠加,删除某个音乐接口如下:

    1. - (int)removeMusic:(AliyunEffectMusic *)music;
  • 删除所有音乐

    1. - (int)removeMusics;

    音乐支持选取时间段播放,同时支持添加到视频特定时间段播放。属性设置接口如下:

    1. @property (nonatomic, assign) CGFloat startTime; // 选取音乐开始时间点
    2. @property (nonatomic, assign) CGFloat duration; // 选取音乐持续时长
    3. @property (nonatomic, assign) CGFloat streamStartTime; // 音乐添加到播放时间轴的开始时间点
    4. @property (nonatomic, assign) CGFloat streamDuration; // 音乐添加到播放时间轴的持续时长

    例:选择一段音乐的第5-10秒,从视频的8秒开始播放并循环2次,设置如下:

    1. AliyunEffectMusic *music = [[AliyunEffectMusic alloc] initWithFile:`音乐文件路径`];
    2. music.startTime = 5;
    3. music.duration = 5;
    4. music.streamStartTime = 8;
    5. music.streamDuration = 10;

    调用音乐相关接口后,播放器将处于pause状态,此时需要调用resume方法后才能继续播放。

配音

AliyunEffectDub表示配音资源,继承AliyunEffectMusic,配音用法和音乐基本一致。相关接口如下:

  • 添加配音

    1. - (int)applyDub:(AliyunEffectDub *)dub;
  • 删除配音

    1. - (int)removeDub:(AliyunEffectDub *)dub;
  • 移除所有配音

    1. - (int)removeDubs;

    配音和音乐的区别:配音支持变速功能,音乐不支持。比如,视频全程快速2倍播放,那么配音也会以2倍速播放,但是音乐却以正常速度播放。

音效

SDK支持对每路音频流设置音效,目前提供的音效包括萝莉,大叔,混响,回声等。

  • 设置单路流音效

AliyunAudioEffectType音效类型。weight音效权重,范围0-100。streamId流id,音乐的streamId存放在AliyunEffectMusiceffectVid属性中,MV存放在AliyunEffectMVaudioEffectVid属性中,主流存放在AliyunClipstreamId属性中。

  1. - (int)setAudioEffect:(AliyunAudioEffectType)type weight:(int)weight streamId:(int)streamId;
  • 删除单路流音效

音效支持叠加操作,想要切换音效需要先删除上次设置的音效。

  1. - (int)removeAudioEffect:(AliyunAudioEffectType)type streamId:(int)streamId;
  • 设置主流音效

除了设置单路流音效,SDK还提供了便捷方法设置主流音效。

  1. - (int)setMainStreamsAudioEffect:(AliyunAudioEffectType)type weight:(int)weight;
  • 去除主流音效
  1. - (int)removeMainStreamsAudioEffect:(AliyunAudioEffectType)type;

其他音频设置

  • 设置静音

    1. - (int)setMute:(BOOL)mute;
  • 设置音量

    默认值:100,如果设置的volume值大于100可能导致破音,建议设置范围:0-100。

    1. - (int)setVolume:(int)volume;
  • 设置主流音频大小

    主流指导入编辑添加的一段或多段视频。

    1. - (int)setMainStreamsAudioWeight:(int)weight;
  • 设置任意流音频大小

    无论视频、音乐、配乐或MV,添加后都会分配唯一的streamId。音乐的streamId存放在AliyunEffectMusiceffectVid属性中,MV存放在AliyunEffectMVaudioEffectVid属性中,主流存放在AliyunClipstreamId属性中。

    1. - (int)setAudioWeight:(int)weight streamId:(int)streamId;
  • 设置主流去噪

    1. - (int)setMainStreamsAudioDenoise:(BOOL)denoise;
  • 设置任意音频流去噪

    1. - (int)setAudioDenoise:(BOOL)denoise streamId:(int)streamId;

动图贴纸

SDK提供普通贴纸、纯字幕和气泡字幕三种类型贴图。提供添加贴图两种方式,一种是采用pasterManager接口,另一种是采用pasterRender底层接口。

pasterManager方式

相关类功能如下表:| 类 | 功能 ||———|———||AliyunPasterManager|负责创建AliyunPasterController对象||AliyunPasterBaseView|获取上层UI的状态||AliyunPasterBaseView|将用户交互对UI的修改反馈到控制层,控制层再同步UI状态到渲染层,从而完成贴纸的渲染|

通过AliyunPasterManager可以添加贴纸,MVC设计示意图如下:

贴图MVC示意图

上面的示意图中我们看到AliyunPasterManager负责创建AliyunPasterController对象,控制器中定义了AliyunPasterBaseView接口来获取上层UI的状态,用户交互对UI的修改会通过AliyunPasterBaseView反馈到控制层,控制层再同步UI状态到渲染层,从而完成了贴纸的编辑渲染,这样UI层可以自由定制,只要实现AliyunPasterViewUIEventProtocol即可。

AliyunPasterViewUIEventProtocol协议主要有:

  1. - (void)eventBoundsDidChanged:(CGRect)aBounds;//大小同步给控制器,用来渲染
  2. - (void)eventCenterDidChanged:(CGPoint)aCenter;//中心点同步给控制器,用来渲染
  3. - (void)eventRotateDidChanged:(CGFloat)aRotate;//旋转角度同步给控制器,用来渲染
  4. - (void)eventTextBoundsDidChanged:(CGRect)aBounds;//文字大小同步给控制器,用来渲染
  5. - (void)eventTextCenterDidChanged:(CGPoint)aCenter;//文字位置同步给控制器,用来渲染
  6. - (void)eventMirrorChanged:(BOOL)isMirror;//是否镜像
  7. - (void)eventPasterViewClosed:(UIView *)pasterView;//动图UI关闭
  8. - (void)eventEditDidEnd;//编辑完成

pasterManager管理整个动图,为了确保最终渲染的贴图位置和大小正确,需要优先设置编辑区域和渲染区域。相关接口如下:

  • 设置编辑区域

    1. /**
    2. 通常,编辑区域需要铺满整个视频区域,所有的上层动图加在该区域内。
    3. */
    4. @property (nonatomic, assign) CGSize displaySize;
  • 设置视频输出分辨率

    1. /**
    2. 合成时需要根据输出分辨率计算贴图的渲染区域大小。
    3. */
    4. @property (nonatomic, assign) CGSize outputSize;
  • 设置渲染区域

    渲染区域指将相对物理像素区域的逻辑像素区域进行转化。

    1. /**
    2. 该渲染区域是将逻辑像素区域对物理像素区域进行过转化,通过 [_editor getPreviewRenderSize]获取
    3. */
    4. @property (nonatomic, assign) CGSize previewRenderSize;
  • 添加动图

    1. /**
    2. @param filePath 动图资源路径
    3. @param st 动图开始时间
    4. @param duration 动图持续时间
    5. @return 返回动图控制器
    6. */
    7. - (AliyunPasterController *)addPaster:(NSString *)filePath startTime:(double)st duration:(double)duration;
  • 添加字幕

    1. /**
    2. @param text 文字 如果为空 则会第一次会进入编辑 如果不为空 则直接显示 不会进入编辑状态
    3. @param bounds 大小
    4. @param st 字幕开始时间
    5. @param duration 字幕持续时间
    6. @return 返回动图控制器
    7. */
    8. - (AliyunPasterController *)addSubtitle:(NSString *)text bounds:(CGRect)bounds startTime:(CGFloat)st duration:(CGFloat)duration;
  • 获取全部动图控制器

    1. /**
    2. @return 动图控制器数组
    3. */
    4. - (NSArray *)getAllPasterControllers;
  • 通过id获取pasterController

    1. /**
    2. @param obj id
    3. @return pasterController
    4. */
    5. - (AliyunPasterController *)getPasterControllerByObj:(id)obj;
  • 动图上某个位置是否存在动图

    1. /**
    2. @param point 点击的位置
    3. @param time 当前视频播放的当前时间
    4. @return 若当前时刻该位置有动图,则返回动图控制器,否则,返回nil
    5. */
    6. - (AliyunPasterController *)touchPoint:(CGPoint)point atTime:(double)time;
  • 删除全部动图

    1. - (void)removeAllPasterControllers;
  • 移除pasterController

    1. /**
    2. API_AVAILABLE(3.7.0)
    3. @param pasterController 动图控制器对象
    4. */
    5. - (void)removePasterController:(AliyunPasterController *)pasterController;
  • 删除全部普通动图

    1. - (void)removeAllNormalPasterControllers;
  • 删除全部字幕动图

    1. - (void)removeAllCaptionPasterControllers;
  • 删除全部纯文字动图

    1. - (void)removeAllSubtitlePasterControllers;
  • 获取编辑中的动图控制器

    1. /**
    2. @return 动图控制器
    3. */
    4. - (AliyunPasterController *)getCurrentEditPasterController;

addPasteraddSubtitle 表示创建贴图的接口,返回的AliyunPasterController表示贴图控制器,内部渲染贴图用到的参数是从AliyunPasterController里面读取的,AliyunPasterController定义了贴图的位置,大小,显示起止时间等相关信息。

pasterController相关接口如下:

  • 设置动图view

    1. /**
    2. @warning:一定要设置
    3. */
    4. @property (nonatomic, strong) UIView *pasterView;
  • 设置动图类型

    1. @property (nonatomic, assign, readonly) AliyunPasterEffectType pasterType;
  • 设置动图旋转角度(弧度)

    1. @property (nonatomic, assign) CGFloat pasterRotate;

    所有涉及到位置和大小的具体数值指考逻辑像素,内部在渲染时会统一转化为物理像素值进行计算。

  • 设置动图位置(x,y)

    1. @property (nonatomic, assign) CGPoint pasterPosition;
  • 设置动图宽高

    1. @property (nonatomic, assign) CGSize pasterSize;
  • 设置动图位置大小

    1. @property (nonatomic, assign) CGRect pasterFrame;
  • 设置动图镜像

    1. @property (nonatomic, assign) BOOL mirror;
  • 设置文字内容

    1. @property (nonatomic, copy) NSString *subtitle;
  • 设置文字位置

    文字位置指相对于动图本身位置。

    1. @property (nonatomic, assign) CGRect subtitleFrame;
  • 设置文字的后台配置字体

    1. @property (nonatomic, copy, readonly) NSString *subtitleConfigFontName;
  • 设置文字的后台配置字体的id

    1. @property (nonatomic, assign, readonly) NSInteger subtitleConfigFontId;
  • 设置文字是否描边

    1. @property (nonatomic, assign) BOOL subtitleStroke;
  • 设置文字颜色

    1. @property (nonatomic, strong) UIColor *subtitleColor;
  • 设置文字描边颜色

    1. @property (nonatomic, strong) UIColor *subtitleStrokeColor;
  • 设置文字的背景颜色

    1. @property (nonatomic, strong) UIColor *subtitleBackgroundColor;
  • 设置文字字体

    1. @property (nonatomic, copy) NSString *subtitleFontName;
  • 设置关键帧图片

    1. @property (nonatomic, strong, readonly) UIImage *kernelImage;
  • 设置动图开始时间(秒)

    1. @property (nonatomic, assign) CGFloat pasterStartTime;
  • 设置动图结束时间(秒)

    1. @property (nonatomic, assign) CGFloat pasterEndTime;
  • 设置动图持续时间(秒)

    1. @property (nonatomic, assign) CGFloat pasterDuration;
  • 设置动图最小持续时间(秒)

    1. @property (nonatomic, assign) CGFloat pasterMinDuration;
  • 设置编辑区域

    1. @property (nonatomic, assign) CGSize displaySize;
  • 设置视频输出分辨率

    1. @property (nonatomic, assign) CGSize outputSize;
  • 设置预览大小

    1. @property (nonatomic, assign) CGSize previewRenderSize;

    表示动图位置和大小的具体值为逻辑像素值,内部渲染时将统一转化为物理像素值进行计算。

PasterController具有编辑状态的属性,用户开始或结束编辑需要手动调用相关方法通知PasterController切换状态,具体方法如下:

  • 准备进入编辑状态

    1. /**
    2. 进入编辑状态前,内部将移除当前渲染的动图。
    3. */
    4. - (void)editWillStart;
  • 进入编辑状态

    1. - (void)editDidStart;
  • 开始编辑

    1. - (void)editProcess;
  • 完成编辑

    1. /**
    2. 完成编辑后,内部将同步pasterController属性信息并渲染。
    3. */
    4. - (void)editCompleted;
  • 完成字幕编辑

    1. /**
    2. 此接口上面的接口功能一致,SDK后续版本将丢弃此接口。
    3. @param image 字幕的图片
    4. */
    5. - (void)editCompletedWithImage:(UIImage *)image;

通过AliyunPasterControllerDelegate可以监听动图的状态,相关接口如下:

  • 移除动图控制器
  1. /**
  2. @param obj 动图控制器
  3. */
  4. - (void)onRemove:(id)obj;
  • 准备进入编辑

    1. /**
    2. @param obj 动图控制器
    3. */
    4. - (void)onEditWillBegin:(id)obj;
  • 开始编辑

    1. /**
    2. @param obj 动图控制器
    3. */
    4. - (void)onEditDidBegin:(id)obj;
  • 完成编辑

    1. /**
    2. @param obj 动图控制器
    3. */
    4. - (void)onEditEnd:(id)obj;
  • 完成图片渲染

    1. /**
    2. @param obj 动图控制器
    3. @param image 需要渲染的图片
    4. */
    5. - (void)onEditEnd:(id)obj image:(UIImage *)image;
  • 示例

  1. AliyunPasterController *pasterController = [self.pasterManager addPaster:pasterInfo.resourcePath startTime:range.startTime duration:range.duration]; //初始化pasterController
  2. AliyunPasterView *pasterView = [[AliyunPasterView alloc] initWithPasterController:pasterController]; //通过pasterController生成pasterView
  3. pasterController.subtitleFontName = pasterView.textFontName;//设置文字字体
  4. pasterController.subtitleStroke = pasterView.textColor.isStroke;//设置文字是否描边
  5. pasterController.subtitleColor = [pasterView contentColor];//设置文字颜色
  6. pasterController.subtitleStrokeColor = [pasterView strokeColor];//设置文字描边颜色
  7. pasterController.subtitleBackgroundColor = [pasterView textBackgroundColor];//设置文字背景颜色
  8. pasterView.delegate = (id)pasterController;
  9. pasterView.actionTarget = (id)self;
  10. [pasterController setPasterView:pasterView];
  11. [pasterController editCompleted];//编辑完成,进行渲染

pasterRender方式

pasterManager添加动图的方式包含了SDK中默认UI,如果您需要完全自定义UI,可以直接调用pasterRender来实现。相关接口如下:

  • 获取AliyunPasterRender实例

    1. - (AliyunPasterRender *)getPasterRender;
  • 添加动图

    1. @param paster 动图对象
    2. * 正常返回 ALIVC_COMMON_RETURN_SUCCESS
    3. * 状态不正确 ALIVC_COMMON_INVALID_STATE
    4. * 文件不存在 ALIVC_SVIDEO_EDITOR_FILE_NOT_EXIST
    5. * 解析动图失败 ALIVC_SVIDEO_EDITOR_PARSE_RESOURCE_FAILED
    6. * ALIVC_FRAMEWORK_RENDER_ERROR_SCENE_INVALID
    7. */
    8. - (int)addGifPaster:(AliyunEffectPaster *)paster;
  • 添加纯文字

    1. @param subtitle 纯文字动图对象
    2. @param textImage 文字截图
    3. * 正常返回 ALIVC_COMMON_RETURN_SUCCESS
    4. * 状态不正确 ALIVC_COMMON_INVALID_STATE
    5. * ALIVC_FRAMEWORK_RENDER_ERROR_SCENE_INVALID
    6. */
    7. - (int)addSubtitlePaster:(AliyunEffectSubtitle *)subtitle textImage:(UIImage *)textImage;
  • 添加字幕动图

    1. @param caption 字幕动图对象
    2. @param textImage 文字截图
    3. * 状态不正确 ALIVC_COMMON_INVALID_STATE
    4. * 文件不存在 ALIVC_SVIDEO_EDITOR_FILE_NOT_EXIST
    5. * 解析动图失败 ALIVC_SVIDEO_EDITOR_PARSE_RESOURCE_FAILED
    6. * ALIVC_FRAMEWORK_RENDER_ERROR_SCENE_INVALID
    7. */
    8. - (int)addCaptionPaster:(AliyunEffectCaption *)caption textImage:(UIImage *)textImage;
  • 移除动图

    1. @param basePaster 动图对象
    2. * 正常返回 ALIVC_COMMON_RETURN_SUCCESS
    3. * 状态不正确 ALIVC_COMMON_INVALID_STATE
    4. * ALIVC_FRAMEWORK_RENDER_ERROR_SCENE_INVALID
    5. */
    6. - (int)removePaster:(AliyunEffectPasterBase *)basePaster;

涂鸦

涂鸦主要涉及两个类:AliyunIPaintAliyunICanvasViewAliyunIPaint表示画笔,AliyunICanvasView表示画布。

AliyunIPaint相关接口如下:

  • 设置线条颜色

    1. @property (nonatomic, strong) UIColor *lineColor;
  • 设置线条宽度

    1. @property (nonatomic, assign) CGFloat lineWidth;
  • 设置线条阴影颜色

    1. @property (nonatomic, strong) UIColor *shadowColor;
  • 设置线条阴影宽度

    1. @property (nonatomic, assign) CGFloat shadowWidth;
  • 初始化线条宽度和颜色

    1. /**
    2. @param lineWidth 线条宽度
    3. @param lineColor 线条颜色
    4. @return self
    5. */
    6. - (instancetype)initWithLineWidth:(CGFloat)lineWidth
    7. lineColor:(UIColor *)lineColor;

    画笔目前支持设置线条颜色、宽度、线条阴影颜色和阴影宽度。

AliyunICanvasView相关接口如下:

  • 回调

    1. @property (nonatomic, weak) id<AliyunICanvasViewDelegate> delegate;
  • 是否允许越界画图

    默认:不允许。

    1. @property (nonatomic, assign) BOOL enableCrossBorder;
  • 设置画笔

    1. @property (nonatomic, strong) AliyunIPaint *paint;
  • 初始化画笔和画板

    1. /**
    2. @param frame 画板
    3. @param paint 画笔
    4. @return self
    5. */
    6. - (instancetype)initWithFrame:(CGRect)frame
    7. paint:(AliyunIPaint *)paint;
  • 更改画笔配置

    1. /**
    2. @param paint 画笔
    3. */
    4. - (void)changePaint:(AliyunIPaint *)paint;
  • 清空所有线条(不可恢复)

    1. - (void)remove;
  • 撤销上一步

    1. - (void)undo;
  • 恢复上一步

    1. - (void)redo;
  • 撤销本次涂鸦所有的操作

    1. - (void)undoAllChanges;
  • 设置完成

    1. /**
    2. @return 涂鸦图片
    3. */
    4. - (UIImage *)complete;

涂鸦提供的回调接口如下:

  • 开始画图

    1. /**
    2. @param startPoint 开始point
    3. */
    4. - (void)startDrawingWithCurrentPoint:(CGPoint)startPoint;
  • 结束画图

    1. /**
    2. @param endPoint 结束point
    3. */
    4. - (void)endDrawingWithCurrentPoint:(CGPoint)endPoint;

水印

AliyunEffectImage表示一个图片资源,您可以通过初始化方法构造一个水印图片实例,参数path为水印图片文件路径。

  • 初始化

    1. - (instancetype)initWithFile:(NSString *)path;

    初始化完成后,需要设置frame属性指定水印相对输出分辨率outputSize的大小位置,水印大小长宽比和原始图片长宽比保持一致。

  • 设置水印

    1. - (int)setWaterMark:(AliyunEffectImage *)waterMark;
  • 设置片尾水印

    1. - (int)setTailWaterMark:(AliyunEffectImage *)waterMark;

    您可以通过AliyunEffectMusicendTime属性设置片尾水印的持续时长。

转场

SDK 3.7.0版本开始支持转场功能,转场的基类是:AliyunTransitionEffect

AliyunTransitionEffect相关接口如下:

  • 设置转场时间

    1. /**
    2. 请确保转场时间大于等于视频片段时长
    3. */
    4. @property (nonatomic, assign) float overlapDuration;
  • 自定义转场效果

    1. @property (nonatomic, copy) NSString *customShader;
  • 设置转场自定义字段

    1. @property (nonatomic, strong) NSDictionary *transitionParam;

目前SDK包含的转场种类如下:

  1. AliyunTransitionEffectShuffer:百叶窗转场
  2. AliyunTransitionEffectTranslate:平移转场 支持上下左右四个方向平移
  3. AliyunTransitionEffectCircle:圆形转场
  4. AliyunTransitionEffectPolygon:多边形转场 可以支持N变形 N > 2
  5. AliyunTransitionEffectFade:淡入淡出转场

如果您熟悉OpenGL Shading Language,可以使用transitionParamcustomShader自定义转场的相关设置。

  • 示例构建AliyunImporter时,为视频clip加转场特效如下:
  1. AliyunClip *clip = [[AliyunClip alloc] initWithImagePath:info.sourcePath duration:info.duration animDuration:i == 0 ? 0 : 1];
  2. AliyunTransitionEffectFade *transitionEffect = [[AliyunTransitionEffectFade alloc] init];
  3. transitionEffect.overlapDuration = 2;
  4. clip.transitionEffect = transitionEffect;
  5. //clip中带有transitionEffect属性,可以通过此属性进行设置

转场配置不仅能在AliyunImportor中进行,还可以在编辑模块中直接使用。

AliyunEditor相关接口如下:

  • 添加转场

    1. /**
    2. API_AVAILABLE(3.7.0)
    3. 注意:
    4. ① 如果只有一个视频片段,不可调用此接口。
    5. ② 转场的时长不能超过前后两段视频中最短的视频时长。
    6. ③ 使用此接口前,先调用[_editor stopEdit],然后调用此接口,接着调用 [_editor startEdit] 和[_player play]。
    7. [----A视频段----] [----B视频段----] [----C视频段----]...[----N段视频----]
    8. ^ ^ ^
    9. clipIndex: 0 1 N-1
    10. @param transition 具体的转场
    11. @param clipIdx 视频片段交叉序列点
    12. @return 返回值为ALIVC_COMMON_RETURN_FAILED失败
    13. ALIVC_COMMON_RETURN_SUCCESS成功
    14. */
    15. - (int)applyTransition:(AliyunTransitionEffect *)transition atIndex:(int)clipIdx;
  • 删除某个转场效果

    1. /**
    2. API_AVAILABLE(3.7.0)
    3. 注意:使用此接口前,先调用[_editor stopEdit],然后调用此接口,接着调用 [_editor startEdit] 和[_player play]。
    4. @param clipIdx 序列号
    5. */
    6. - (int)removeTransitionAtIndex:(int)clipIdx;
  • 示例

  1. AliyunTransitionEffectFade *fade = [[AliyunTransitionEffectFade alloc] init];
  2. fade.overlapDuration = 10;
  3. [self.editor applyTransition:fade atIndex:idx];

动画效果

3.7.0版本开始,继承AliyunClipAliyunEffectPasterBase的对象都具有增加动画功能,动画的基类是AliyunAction

当前版本SDK子类动画如下:

  1. AliyunMoveAction //移动动画
  2. AliyunScaleAction //缩放动画
  3. AliyunRotateAction //旋转动画
  4. AliyunRotateToAction //旋转到某个弧度的动画
  5. AliyunRotateByAction //从当前弧度旋转某个弧度的动画
  6. AliyunRotateRepeatAction //重复旋转动画
  7. AliyunAlphaAction //透明度动图
  8. AliyunCustomAction //自定义动画

动画相关的具体类包含的接口请参考接口文档。

AliyunEditor中提供增删动画的相关接口如下:

  • 添加帧动画

    1. /**
    2. API_AVAILABLE(3.7.0)
    3. 注意:主流不支持alpha帧动画
    4. @param obj 动画作用的对象
    5. @param action 动画
    6. */
    7. - (void)add:(id<AliyunActionProtocol>)obj withFrameAnimation:(AliyunAction *)action;
  • 删除帧动画

    1. /**
    2. API_AVAILABLE(3.7.0)
    3. @param obj 动画作用的对象
    4. @param action 动画
    5. */
    6. - (void)remove:(id<AliyunActionProtocol>)obj withFrameAnimation:(AliyunAction *)action;

AliyunClip中提供的动画接口如下:

  • 添加动画

    1. /**
    2. API_AVAILABLE(3.7.0)
    3. 注意:主流不支持alpha帧动画。
    4. @param action 动画
    5. */
    6. - (void)runAction:(AliyunAction *)action;
  • 停止动画

    1. /**
    2. API_AVAILABLE(3.7.0)
    3. @param action 动画
    4. */
    5. - (void)stopAction:(AliyunAction *)action;
  • 获取全部动画

    1. /**
    2. API_AVAILABLE(3.7.0)
    3. @return 动画数组
    4. */
    5. - (NSArray *)allActions;

AliyunEffectPasterBase中提供的动画接口如下:

  • 添加动画

    1. /**
    2. API_AVAILABLE(3.7.0)
    3. @param action 动画
    4. */
    5. - (void)runAction:(AliyunAction *)action;
  • 停止动画

    1. /**
    2. API_AVAILABLE(3.7.0)
    3. @param action 动画
    4. */
    5. - (void)stopAction:(AliyunAction *)action;
    6. - (void)stopAllActions;
  • 示例通过编辑接口将一张静态贴纸透明处理如下:

  1. AliyunAlphaAction *alphaAction = [[AliyunAlphaAction alloc] init];
  2. alphaAction.targetID = [_staticImage effectVid]; //必须要设置左右对象的id
  3. alphaAction.startTime = 3;
  4. alphaAction.duration = 2;
  5. alphaAction.fromAlpha = 0.0;
  6. alphaAction.toAlpha = 1.0;
  7. [self.editor add:_staticImage withFrameAnimation:alphaAction];

通过AliyunClipAliyunEffectPasterBase处理的示例如下:

  1. AliyunAlphaAction *alphaAction = [[AliyunAlphaAction alloc] init];
  2. alphaAction.startTime = [pasterController pasterStartTime];
  3. alphaAction.duration = 1;
  4. alphaAction.fromAlpha = 0.0f;
  5. alphaAction.toAlpha = 1.0f;
  6. [effectPaster runAction:alphaAction];

如果您熟悉OpenGL Shading Language,可以使用AliyunCustomAction自定义动画,示例如下:

  1. AliyunCustomAction *customAction = [[AliyunCustomAction alloc] init];
  2. customAction.startTime = [pasterController pasterStartTime];
  3. customAction.duration = 0.5;
  4. customAction.fragmentShader = @"precision mediump float; uniform sampler2D inputImageTexture; uniform float uAlpha; varying vec2 textureCoordinate; uniform float offset; float w = 0.2; float g = 1.0; uniform int direction; uniform int wipeMode;const int LEFT = 0;const int TOP = 1;const int RIGHT = 2;const int BOTTOM = 3;const int APPEAR = 0;const int DISAPPEAR = 1;void main(){vec4 gamma = vec4(g, g, g, 1.0);vec4 color0 = pow(texture2D(inputImageTexture, textureCoordinate), gamma);float correction = mix(w, -w, offset);float coord = textureCoordinate.x;if(direction == LEFT){coord = 1.0 - textureCoordinate.x;}else if(direction == RIGHT){coord = textureCoordinate.x;}else if(direction == TOP){coord = 1.0 - textureCoordinate.y;}else if(direction == BOTTOM){coord = textureCoordinate.y;}float choose = smoothstep(offset - w, offset + w, coord + correction); float alpha = choose;if(wipeMode == APPEAR){alpha = 1.0 - choose;}else if(wipeMode == DISAPPEAR){alpha = choose;}gl_FragColor = vec4(color0.r,color0.g,color0.b,color0.a*alpha);}";
  5. customAction.customUniformsMapper = @{@"direction": @[@0],
  6. @"wipeMode":@[@0],
  7. @"offset":@[@0.0,@1.0],
  8. };
  9. [effectPaster runAction:customAction];

示例中自定义的fragmentShadercustomUniformsMapper,表示进行“线性擦除”的动画效果。

自定义渲染

短视频SDK通过接口提供原始和渲染后的纹理id,您可以在渲染流程中加入自定义渲染。如需自定义渲染,需实现shader,反之不需要。

实现自定渲染需要实现AliyunIRenderCallback代理回调:

  1. /**
  2. 自定义渲染接口,SDK渲染前纹理回调
  3. @param srcTexture 原始视频帧纹理id
  4. @param size 原始视频帧纹理size
  5. @return 返回纹理id
  6. */
  7. - (int)customRender:(int)srcTexture size:(CGSize)size;
  1. /**
  2. 自定义渲染接口,SDK渲染后纹理回调
  3. @param srcTexture 原始视频帧纹理id
  4. @param size 原始视频帧纹理size
  5. @return 返回纹理id
  6. */
  7. - (int)textureRender:(int)srcTexture size:(CGSize)size;

填充裁剪模式

通过AliyunEffectRunningDisplayMode,可以实现播放器进行播放时动态切换填充模式或裁剪模式。相关接口如下:

  1. @property(nonatomic, assign) float streamStartTime; //开始时间
  2. @property(nonatomic, assign) float streamEndTime; //结束时间
  3. @property(nonatomic, assign) AliyunRunningMode mode;//AliyunRunningModeFit:裁剪 AliyunRunningModeFill:填充
  4. @property(nonatomic, assign) int targetStreamId;//作用的目标流的id
  • 示例
  1. AliyunEffectRunningDisplayMode *displayMode = [[AliyunEffectRunningDisplayMode alloc ] init];
  2. displayMode.streamStartTime = 0; //设置播放模式的开始时间
  3. displayMode.streamEndTime = 4; //设置播放模式的结束时间
  4. displayMode.mode = AliyunRunningModeFill;//设置播放的模式 填充或者裁剪
  5. displayMode.targetStreamId = clip.streamId; //设置作用的流的id
  6. [self.editor applyRunningDisplayMode:displayMode];

合成导出

  • 获取导出实例

    1. - (id<AliyunIExporter>)getExporter;
  • 合成导出

  1. - (int)startExport:(NSString *)outputPath;
  • 取消导出
  1. -(int)cancelExport;

实现合成导出状态的监听,需要实现delegate代理的AliyunIExporterCallback协议,回调方法如下:

  • 导出开始

    1. - (void)exporterDidStart;
  • 导出结束

    1. /**
    2. @param outputPath 输出文件路径
    3. */
    4. - (void)exporterDidEnd:(NSString *)outputPath;
  • 导出取消

    1. - (void)exporterDidCancel;
  • 导出进度

    1. /**
    2. @param progress 0-1
    3. */
    4. - (void)exportProgress:(float)progress;
  • 导出异常

    1. /**
    2. @param errorCode 错误码
    3. */
    4. - (void)exportError:(int)errorCode;