Demo中视频编辑的Activity流程为
MovieAlbumActivity  视频选择页面MovieEditorCutActivity 视频编辑-裁剪页面MovieEditorActivity 视频编辑页面| 类名 | 功能说明 | 
|---|---|
| MovieAlbumActivity | 对视频列表进行选择 | 
其中需要说明这几个参数
/* 最小视频时长(单位:ms) */
private static int MIN_VIDEO_DURATION = 3000;
/* 最大视频时长(单位:ms) */
private static int MAX_VIDEO_DURATION = 60000;
/** 最大边长限制 **/
private static final int MAX_SIZE = 3840;
最大边长限制,我们限制在了4K以下,因为不同的厂商的手机对4K的支持不同,我们统一限制视频为4K以下的视频可以编辑
| 类名 | 功能说明 | 
|---|---|
| MovieEditorCutActivity | 编辑-裁剪页面 | 
| TuSdkMediaMutableFilePlayer | 视频播放器(支持多文件) | 
| TuSdkMediaFilesCuterImpl | 裁剪器(支持多文件) | 
| TuSdkVideoImageExtractor | 封面抽取(支持多文件) | 
进入MovieEditorCutActivity需要在打开这个activity的时候通过Bundle 传入视频路径,SerializableExtr的name为videoPaths
    /** 加载视频缩略图 */
    public void loadVideoThumbList() {
        List<TuSdkMediaDataSource> sourceList = new ArrayList<>();
        for (MovieInfo movieInfo : mVideoPaths)
            sourceList.add(TuSdkMediaDataSource.create(movieInfo.getPath()).get(0));
        /** 准备视频缩略图抽取器 */
        final TuSdkVideoImageExtractor imageThumbExtractor = new TuSdkVideoImageExtractor(sourceList);
        imageThumbExtractor
               //.setOutputImageSize(TuSdkSize.create(50,50)) // 设置抽取的缩略图大小
                .setExtractFrameCount(20) // 设置抽取的图片数量
                .setImageListener(new TuSdkVideoImageExtractorListener() {
                    /**
                     * 输出一帧略图信息
                     *
                     * @param videoImage 视频图片
                     * @since v3.2.1
                     */
                    public void onOutputFrameImage(final TuSdkVideoImageExtractor.VideoImage videoImage) {
                        ThreadHelper.post(new Runnable() {
                            @Override
                            public void run() {
                                mEditorCutView.addBitmap(videoImage.bitmap);
                                if(!isSetDuration) {
                                    float duration = mVideoPlayer.durationUs() / 1000000.0f;
                                    mEditorCutView.setRangTime(duration);
                                    mEditorCutView.setTotalTime(mVideoPlayer.durationUs());
                                    if(duration >0)
                                    isSetDuration = true;
                                }
                                mEditorCutView.setMinCutTimeUs(mMinCutTimeUs/(float)mDurationTimeUs);
                            }
                        });
                    }
                    /**
                     * 抽取器抽取完成
                     *
                     * @since v3.2.1
                     */
                    @Override
                    public void onImageExtractorCompleted(List<TuSdkVideoImageExtractor.VideoImage> videoImagesList) {
                        /** 注意: videoImagesList 需要开发者自己释放 bitmap */
                        imageThumbExtractor.release();
                    }
                 })
                .extractImages(); // 抽取图片
    }
    /**
     * 开始合成视频
     */
    private void startCompound(){
        if (cuter != null) {
            return;
        }
        isCutting = true;
        List<TuSdkMediaDataSource> sourceList = new ArrayList<>();
        // 遍历视频源
        for (MovieInfo movieInfo : mVideoPaths) {
            sourceList.add(TuSdkMediaDataSource.create(movieInfo.getPath()).get(0));
        }
        // 准备切片时间
        TuSdkMediaTimeSlice tuSdkMediaTimeSlice = new TuSdkMediaTimeSlice(mLeftTimeRangUs,mRightTimeRangUs);
        tuSdkMediaTimeSlice.speed = mVideoPlayer.speed();
        // 准备裁剪对象
        cuter = new TuSdkMediaFilesCuterImpl();
        // 设置裁剪切片时间
        cuter.setTimeSlice(tuSdkMediaTimeSlice);
        // 设置数据源
        cuter.setMediaDataSources(sourceList);
        // 设置文件输出路径
        cuter.setOutputFilePath(getOutputTempFilePath().getPath());
        // 准备视频格式
        MediaFormat videoFormat = TuSdkMediaFormat.buildSafeVideoEncodecFormat( cuter.preferredOutputSize().width,  cuter.preferredOutputSize().height,
                30, TuSdkVideoQuality.RECORD_MEDIUM2.getBitrate(), MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface, 0, 0);
        // 设置视频输出格式
        cuter.setOutputVideoFormat(videoFormat);
        // 设置音频输出格式
        cuter.setOutputAudioFormat(TuSdkMediaFormat.buildSafeAudioEncodecFormat());
        // 开始裁剪
        cuter.run(new TuSdkMediaProgress() {
            /**
             *  裁剪进度回调
             * @param progress        进度百分比 0-1
             * @param mediaDataSource 当前处理的视频媒体源
             * @param index           当前处理的视频索引
             * @param total           总共需要处理的文件数
             */
            @Override
            public void onProgress(final float progress, TuSdkMediaDataSource mediaDataSource, int index, int total) {
                ThreadHelper.post(new Runnable() {
                    @Override
                    public void run() {
                        mLoadContent.setVisibility(View.VISIBLE);
                        mLoadProgress.setValue(progress * 100);
                    }
                });
            }
            /**
             *  裁剪结束回调
             * @param e 如果成功则为Null
             * @param outputFile 输出文件路径
             * @param total 处理文件总数
             */
            @Override
            public void onCompleted(Exception e, TuSdkMediaDataSource outputFile, int total) {
                isCutting = false;
                ThreadHelper.post(new Runnable() {
                    @Override
                    public void run() {
                        setEnable(true);
                        mLoadContent.setVisibility(View.GONE);
                        mLoadProgress.setValue(0);
                        mPlayBtn.setVisibility(mVideoPlayer.isPause()?View.VISIBLE:View.GONE);
                    }
                });
                Intent intent = new Intent(MovieEditorCutActivity.this,MovieEditorActivity.class);
                intent.putExtra("videoPath", outputFile.getPath());
                startActivity(intent);
                cuter = null;
            }
        });
    }
// 设置裁剪切片
public void setTimeSlice(TuSdkMediaTimeSlice slice)
// 设置数据源
public final void setMediaDataSources(List<TuSdkMediaDataSource> mediaDataSources) 
// 设置输出文件路径
public void setOutputFilePath(String filePath)
// 设置输出视频格式
public int setOutputVideoFormat(MediaFormat videoFormat)
// 设置输出音频格式
public int setOutputAudioFormat(MediaFormat audioFormat)
// 进行裁剪
public boolean run(TuSdkMediaProgress progress)
裁剪的回调为
/** 媒体处理进度接口 */
public interface TuSdkMediaProgress {
    /**
     * 执行进度 [主线程]
     *
     * @param progress        进度百分比 0-1
     * @param mediaDataSource 当前处理的视频媒体源
     * @param index           当前处理的视频索引
     * @param total           总共需要处理的文件数
     */
    void onProgress(float progress, TuSdkMediaDataSource mediaDataSource, int index, int total);
    /***
     * 完成转码 [主线程]
     * @param e 如果成功则为Null
     * @param outputFile 输出文件路径
     * @param total 处理文件总数
     */
    void onCompleted(Exception e, TuSdkMediaDataSource outputFile, int total);
}
由MovieEditorCutActivity 转码后,进入了视频编辑MovieEditorActivity页面,
| 类名 | 功能描述 | 
|---|---|
| MovieEditorActivity | 视频编辑页面 | 
| MovieEditorController | 视频编辑控制器 | 
| TuSdkMovieEditor | 视频编辑器 | 
视频编辑的功能是由TuSdkMovieEditor 提供,Demo界面以及相关操作,都在MovieEditorController里以操作组件的方式封装
| 类名 | 功能描述 | 
|---|---|
| EditorHomeComponent | 视频编辑主页面组件 | 
| EditorFilterComponent | 滤镜效果组件 | 
| EditorMVComponent | MV效果组件 | 
| EditorMusicComponent | 配音效果组件 | 
| EditorTextComponent | 文字效果组件 | 
| EditorEffectComponent | 特效组件(包括场景特效、时间特效、魔法特效) | 
| EditorEffectTransitionsComponent | 转场特效组件 | 
| EditorStickerComponent | 图片贴纸组件 | 
| EditorTrimComponent | 视频裁剪组件 | 
在MovieEditorController 的构造方法中需要初始化视频编辑器,以下是一个最简单的视频加载逻辑。
    /**
    * context 当前context
    * holderView 视频播放器的父容器
    * options 视频配置项
    **/
    TuSdkMovieEditor mMovieEditor = new TuSdkMovieEditorImpl(context, holderView, options);
    //之前经历过MovieEditorCutActivity裁剪加载 则不用开启转码
    mMovieEditor.setEnableTranscode(false);
    //加载视频
    mMovieEditor.loadVideo();
接口描述:
    /**
     * 是否开启转码
     *
     * @param isEnableTranscode true 开启 false 不开启 默认开启
     */
    public void setEnableTranscode(boolean isEnableTranscode);
    /**
     * 加载视频
     *
     * @since 3.0
     */
    void loadVideo();
    /**
     * 保存视频
     *
     * @since 3.0
     */
    void saveVideo();
简单使用方式如下:
    TuSdkMovieEditor.TuSdkMovieEditorOptions defaultOptions = TuSdkMovieEditor.TuSdkMovieEditorOptions.defaultOptions();
    defaultOptions
        // 设置视频数据源
        .setVideoDataSource(new TuSdkMediaDataSource(mVideoPath))
        // 设置是否保存或者播放原音
        .setIncludeAudioInVideo(true) 
        // 设置MovieEditor销毁时是否自动清除缓存音频解码信息
        .setClearAudioDecodeCacheInfoOnDestory(false)
        // 设置时间线模式
        .setPictureEffectReferTimelineType(TuSdkMediaEffectReferInputTimelineType)
        // 设置水印
        .setWaterImage(BitmapHelper.getBitmapFormRaw(this, R.raw.sample_watermark), TuSdkWaterMarkOption.WaterMarkPosition.TopRight, true);
接口描述:
public TuSdkMovieEditorOptions setVideoDataSource(TuSdkMediaDataSource videoDataSource);
 public TuSdkMovieEditorOptions setMovieOutputFilePath(File movieOutputFilePath);
public TuSdkMovieEditorOptions setCutTimeRange(TuSDKTimeRange cutTimeRange);
public TuSdkMovieEditorOptions setCanvasRectF(RectF canvasRect);
public TuSdkMovieEditorOptions setIncludeAudioInVideo(boolean includeAudioInVideo);
public TuSdkMovieEditorOptions setPictureEffectReferTimelineType(TuSdkMediaPictureEffectReferTimelineType timelineType);
public TuSdkMovieEditorOptions setOutputSize(TuSdkSize outputSize);
public TuSdkMovieEditorOptions setSaveToAlbum(Boolean saveToAlbum);
public TuSdkMovieEditorOptions setSaveToAlbumName(String saveToAlbumName);
public TuSdkMovieEditorOptions setClearAudioDecodeCacheInfoOnDestory(boolean clearAudioDecodeCacheInfoOnDestory);
/**
* waterImage          水印图片 (Bitmap)
* watermarkPosition   水印的位置
* isRecycleWaterImage 是否回收水印图片(Bitmap)
**/
public TuSdkMovieEditorOptions setWaterImage(Bitmap waterImage, TuSdkWaterMarkOption.WaterMarkPosition watermarkPosition, boolean isRecycleWaterImage)
视频编辑TuSdkMovieEditor 中由一下几个组件组成,调用的时候通过一下不同的功能组件调用不同的API
TuSdkEditorTranscoder转码器 如果没有预转码或者开启了转码,则由此转码器进行视频的裁剪与处理TuSdkEditorPlayer 播放器 编辑内的播放器,负责控制时间特效,以及相关播放的APITuSdkEditorEffector 特效器 负责特效 添加 删除相关的APITuSdkEditorAudioMixer混音器 混音相关的APITuSdkEditorSaver 保存器  最后保存视频的相关API相关特效分为普通特效和时间特效两种 普通特效:
| 特效类名 | 功能描述 | 
|---|---|
| TuSDKMediaTextEffectData | 文字贴纸特效 | 
| TuSDKMediaParticleEffectData | 魔法特效 | 
| TuSDKMediaStickerAudioEffectData | MV特效 | 
| TuSDKMediaFilterEffectData | 滤镜效果 | 
| TuSDKMediaStickerEffectData | 贴纸特效 | 
| TuSDKMediaAudioEffectData | 配音特效 | 
| TuSDKMediaSceneEffectData | 场景特效 | 
| TuSDKMediaComicEffectData | 卡通特效 | 
| TuSdkMediaTransitionEffectData | 转场特效 | 
| TuSdkMediaStickerImageEffectData | 图片贴纸特效 | 
上述特效由TuSdkEditorEffector 特效器进行添加 、删除的操作,下列三种是时间特效,由TuSdkEditorPlayer管理
| 特效类名 | 功能描述 | 
|---|---|
| TuSDKMediaReversalTimeEffect | 倒序时间特效 | 
| TuSDKMediaRepeatTimeEffect | 反复时间特效 | 
| TuSDKMediaSlowTimeEffect | 慢动作时间特效 | 
在EditorFilterComponent中mFilterRecyclerView的Item点击回调内,回去到当前点击的滤镜的code(通过mFilterRecyclerAdapter.setFilterList(filterList)设置)
滤镜列表,获取滤镜前往 TuSDK.bundle/others/lsq_tusdk_configs.json
TuSDK 滤镜信息介绍 @see-https://tusdk.com/docs/image-android/customize-filter
TuSDKMediaFilterEffectData mediaFilterEffectData = new TuSDKMediaFilterEffectData(code);
getMovieEditor().getEditorEffector().addMediaEffectData(filterEffectData);
滤镜的改变回调可以通过TuSdkEditorEffector 来设置
//设置滤镜改变的回调
getEditorEffector().setFilterChangeListener(mFilterChangeListener);
在EditorMVComponent中的mMvRecyclerView的Item点击回调内
/*********************  添加  *************/
 if (mMusicMap != null && mMusicMap.containsKey(groupId)) {
    //带音效的MV
    Uri uri = Uri.parse("android.resource://" + getEditorController().getActivity().getPackageName() + "/" + mMusicMap.get(groupId));
   //创建MV数据类
    TuSDKMediaStickerAudioEffectData stickerAudioEffectDat = new TuSDKMediaStickerAudioEffectData(new TuSdkMediaDataSource(context, uri), itemData);
     //设置时间范围
    stickerAudioEffectDat.setAtTimeRange(TuSDKTimeRange.makeRange(0, Float.MAX_VALUE));
    //设置MV的背景音效是否循环播放
    stickerAudioEffectDat.getMediaAudioEffectData().getAudioEntry().setLooping(true);
    //添加MV效果
    getEditorEffector().addMediaEffectData(stickerAudioEffectDat);
} else {
    //纯贴纸的MV
    TuSDKMediaStickerEffectData stickerEffectData = new TuSDKMediaStickerEffectData(itemData);
    //设置时间范围
    stickerEffectData.setAtTimeRange(TuSDKTimeRange.makeRange(0, Float.MAX_VALUE));
    //添加MV效果
    getMovieEditor().getEditorEffector().addMediaEffectData(stickerEffectData);
 }
在EditorMusicComponent中的mMusicRecycle的Item点击中
//创建音频特效对象
TuSDKMediaAudioEffectData audioEffectData = new TuSDKMediaAudioEffectData(new TuSdkMediaDataSource(context, audioPathUri));
//设置时间
audioEffectData.setAtTimeRange(TuSDKTimeRange.makeTimeUsRange(0,   getEditorPlayer().getOutputTotalTimeUS()));
加载音频回调是在混音器中加入
getEditorMixer().addTaskStateListener(mAudioDecoderTask);
回调的状态有
/**
 * 当前执行类状态
 */
public enum State {
    /** 空闲状态 **/
    Idle,
    /** 正在解码 **/
    Decoding,
    /** 解码完成 **/
    Complete,
    /** 已取消  **/
    Cancelled
}
音频录音回调
/**
 * 录音裁剪进度监听
 */
public interface OnAudioRecordCuterListener {
    /**
     * 当前执行的进度
     *
     * @param percent       当前进度的百分比 (0 ~ 1)
     * @param currentTimeUS 当前执行的时间(微秒)
     * @param totalTimeUS   总时长 (微秒)
     */
    void onProgressChanged(float percent, long currentTimeUS, long totalTimeUS);
    /**
     * 输出完毕
     *
     * @param outputFile 输出完成的文件
     */
    void onComplete(File outputFile);
}
文字功能在EditorTextComponent 中,添加一个文字特效
/**
 * 将数据转成公用的 TuSDKMediaEffectData
 *
 * @param sticker     贴纸数据
 * @param bitmap      文字生成的图片
 * @param offsetX     相对视频左上角X轴的位置
 * @param offsetY     相对视频左上角Y轴的位置
 * @param rotation    旋转的角度
 * @param startTimeUs 文字特效开始的时间
 * @param stopTimeUs  文字特效结束的时间
 * @param stickerSize 当前StickerView的宽高(计算比例用)
*/
//创建一个文字贴纸包装类
TuSDKTextStickerImage stickerImage = new TuSDKTextStickerImage();
//创建文字贴纸数据类
TextStickerData stickerData = new TextStickerData(bitmap, bitmap.getWidth(), bitmap.getHeight(), 0, offsetX, offsetY, rotation);
stickerImage.setCurrentSticker(stickerData);
//设置设计画布的宽高
stickerImage.setDesignScreenSize(stickerSize);
//创建文字特效类
TuSDKMediaTextEffectData mediaTextEffectData = new TuSDKMediaTextEffectData(stickerImage);
//设置当前文字特效的时间
mediaTextEffectData.setAtTimeRange(TuSDKTimeRange.makeTimeUsRange(startTimeUs, stopTimeUs
//添加特效
getEditorEffector().addMediaEffectData(textMediaEffectData)
特效里分为场景特效 、 时间特效、魔法特效 三种,在EditorEffectComponent中,分为三个Fragment
ScreenEffectFragment场景特效FragmentTimeEffectFragment 时间特效FragmentMagicEffectFragment 魔法特效Fragment添加一个场景特效
//创建一个场景特效数据类
TuSDKMediaSceneEffectData mediaSceneEffectData = new TuSDKMediaSceneEffectData(mScreenCode);
//设置场景特效的时间
mediaSceneEffectData.setAtTimeRange(TuSDKTimeRange.makeTimeUsRange(starTimeUs, endTimeUs));
//添加当前场景特效
getEditorEffector().addMediaEffectData(mediaSceneEffectData);
删除一个场景特效
getEditorEffector().removeMediaEffectData(mediaEffectData);
//实例化反复特效数据类
TuSDKMediaRepeatTimeEffect repeatTimeEffect = new TuSDKMediaRepeatTimeEffect();
//设置开始与结束的时间范围
repeatTimeEffect.setTimeRange(startTimeUS, endTimeUS);
//设置反复的次数
repeatTimeEffect.setRepeatCount(2);
//是否裁剪多余的时间 
repeatTimeEffect.setDropOverTime(false);
//应用时间特效
getEditorPlayer().setTimeEffect(repeatTimeEffect);
//实例化慢动作特效数据
TuSDKMediaSlowTimeEffect slowTimeEffect = new TuSDKMediaSlowTimeEffect();
//设置慢动作的时间范围
slowTimeEffect.setTimeRange(startTimeUS, endTimeUS);
//设置慢动作的速率
slowTimeEffect.setSpeed(0.6f);
//应用时间特效
getEditorPlayer().setTimeEffect(slowTimeEffect);
//实例化时光倒流特效数据
TuSDKMediaReversalTimeEffect reversalTimeEffect = new TuSDKMediaReversalTimeEffect();
//应用时间特效
getEditorPlayer().setTimeEffect(reversalTimeEffect);
getEditorPlayer().clearTimeEffect();
//实例化魔法效果
TuSDKMediaParticleEffectData effectModel = new TuSDKMediaParticleEffectData(mCurrentMagicCode);
//设置粒子大小
effectModel.setSize(mMagicConfig.getSize());
//设置粒子颜色
effectModel.setColor(mMagicConfig.getColor());   
//设置粒子位置(持续的移动不断的put 参考Demo中的MagicEffectFragment)
effectModel.putPoint(getEditorPlayer().getCurrentTimeUs(), pointF);
//预览魔法特效
getEditorEffector().addMediaEffectData(effectModel);
转场特效功能在EditorEffectTransitionsComponent 中,添加一个转场特效
    /** 转场特效类型枚举 */
    public enum TuSDKMediaTransitionType{
        /** 转场 - 淡入  @since v3.4.1 */
        TuSDKMediaTransitionTypeFadeIn,
        /** 转场 - 飞入  @since v3.4.1 */
        TuSDKMediaTransitionTypeFlyIn,
        /** 转场 - 拉入--右侧进入  @since v3.4.1 */
        TuSDKMediaTransitionTypePullInRight,
        /** 转场 - 拉入--左侧进入  @since v3.4.1 */
        TuSDKMediaTransitionTypePullInLeft,
        /** 转场 - 拉入--顶部进入  @since v3.4.1 */
        TuSDKMediaTransitionTypePullInTop,
        /** 转场 - 拉入--底部进入  @since v3.4.1 */
        TuSDKMediaTransitionTypePullInBottom,
        /** 转场 - 散步进入  @since v3.4.1 */
        TuSDKMediaTransitionTypeSpreadIn,
        /** 转场 - 闪光灯  @since v3.4.1 */
        TuSDKMediaTransitionTypeFlashLight,
        /** 转场 - 翻页  @since v3.4.1 */
        TuSDKMediaTransitionTypeFlip,
        /** 转场 - 聚焦-小到大  @since v3.4.1 */
        TuSDKMediaTransitionTypeFocusOut,
        /** 转场 - 聚焦-大到小 @since v3.4.1 */
        TuSDKMediaTransitionTypeFocusIn,
        /** 转场 - 叠起 @since v3.4.1 */
        TuSDKMediaTransitionTypeStackUp,
        /** 转场 - 缩放 @since v3.4.1 */
        TuSDKMediaTransitionTypeZoom
    }
//创建一个转场特效数据类,接收一个TuSDKMediaTransitionType类型的枚举
TuSdkMediaTransitionEffectData mediaTransitionEffectData = new TuSdkMediaTransitionEffectData(TuSDKMediaTransitionType);
//设置转场特效开始与结束时间
mediaTransitionEffectData.setAtTimeRange(TuSDKTimeRange.makeTimeUsRange(starTimeUs, endTimeUs));
//设置转场特效持续时间
mediaTransitionEffectData.getFilterArg("duration").setValue(durationUs);
mediaTransitionEffectData.submitParameters();
//预览转场特效
getEditorEffector().addMediaEffectData(mediaTransitionEffectData);
图片贴纸特效功能在EditorStickerComponent中, 添加图片贴纸
//创建一个贴纸数据对象
StickerImageData imageData = new StickerImageData();
//设置要显示的图片Bitmap
imageData.setImage(bitmap);
//设置图片的高度
imageData.height =  TuSdkContext.px2dip(bitmap.getHeight());
//设置图片的宽度
imageData.width = TuSdkContext.px2dip(bitmap.getWidth());
//设置图片开始显示时间
imageData.starTimeUs = 0;
//设置图片结束显示时间
imageData.stopTimeUs = 2 * 1000000;
//添加贴纸数据对象
getEditorController().getActivity().getImageStickerView().appendSticker(imageData);
    /**
     * 将数据转成公用的 TuSdkMediaEffectData
     *
     * @param bitmap      图片
     * @param displaySize 图片显示的大小
     * @param offsetX     相对视频左上角X轴的位置
     * @param offsetY     相对视频左上角Y轴的位置
     * @param rotation    旋转的角度
     * @param startTimeUs 特效开始的时间
     * @param stopTimeUs  特效结束的时间
     * @param stickerSize 当前StickerView的宽高(计算比例用)
     * @return
     */
    protected TuSdkMediaStickerImageEffectData createTileEffectData(Bitmap bitmap, TuSdkSize displaySize, float offsetX, float offsetY, float rotation, long startTimeUs, long stopTimeUs ,TuSdkSize stickerSize) {
        TuSdkMediaStickerImageEffectData mediaTextEffectData = new TuSdkMediaStickerImageEffectData(bitmap,offsetX,offsetY,rotation,displaySize,stickerSize);
        mediaTextEffectData.setAtTimeRange(TuSdkTimeRange.makeTimeUsRange(startTimeUs, stopTimeUs));
        return mediaTextEffectData;
    }
//添加贴纸特效对象
getEditorEffector().addMediaEffectData(createTileEffectData());
视频裁剪功能在EditorTrimComponent中
//设置视频裁剪输出比例,ratio 为 float类型的输出比例,enableClip 为 是否裁剪画面 true 超出比例外的部分会被裁剪掉 false 整个画面缩到预定的比例大小里
getEditorPlayer().setOutputRatio(float ratio, boolean enableClip);
保存视频调用TuSdkMovieEditor.saveVideo(),保存的回调可以在saveVieo() 之前向保存器内添加回调
getEditorSaver().addSaverProgressListener(mSaveProgressListener);
该回调为
//保存进度监听
interface TuSdkSaverProgressListener {
    /**
     * 当前进度
     *
     * @param progress
     * @since v3.0
     */
    void onProgress(float progress);
    /**
     * 保存完成
     *
     * @param outputFile
     * @since v3.0
     */
    void onCompleted(TuSdkMediaDataSource outputFile);
    /**
     * 保存错误
     *
     * @param e
     * @since v3.0
     */
    void onError(Exception e);
}