QVEditor-Android

More: Author   ReportBugs   
Tags:

Android 剪辑 SDK 接入文档

一、名词解释

  1. 工程:分为剪辑工程(IQEWorkSpace)和卡点视频工程(ISlideWorkSpace),后续统称 workspace。其中小影提供的所有剪辑玩法,都是针对剪辑工程进行的操作。卡点视频即使用素材一键生成大片,目前仅支持片段替换和片段排序。
  2. 播放流:每个工程会独立的播放流,将播放器 View 和工程绑定后,即可完成视频流的显示。同时可以对工程的播放器做相关操作。
  3. 主题:theme,一系列效果的合集,包括片头、片尾、转场、音乐、滤镜等。对工程设置主题,可以实现模板视频功能。
  4. 片段:Clip,片段可以是图片或视频,是工程的基础组成部分。工程将按片段顺序生成一段视频。
  5. 转场:Transition, 转场效果是设定在两个片段之间的,是两个片段的切换效果。
  6. 滤镜/特效滤镜:Filter/FxFilter,是添加给单个片段的,覆盖整个片段,可以实现调色滤镜、边框滤镜、特效滤镜等。
  7. 效果:Effect,贴纸、画中画、字幕、特效、马赛克,都属于效果,是直接在工程上增加的效果。水印也是一种特殊的效果。
  8. 图层:Layer,Clip 都在同一个图层中,效果和音频可以设置自己的图层,图层的层级大小将影响工程视频的实际效果。详情可以参考【基础结构和概念】中的【图层轨道】一节。
  9. 音频:Audio,音频也是一种特殊的效果。分为背景音乐、音效和录音。背景音乐都在同一图层中,即一个时间点不可同时存在多个音频;音效和录音则可以单独设置图层,即一个时间点可以同时存在多个音频。
  10. 源文件区间:SrcRange,片段中表示加入片段源文件的起始点和长度,效果中表示效果裁剪的起始点和长度。详情可以参考【基础结构和概念】中的【Range 相关】一节。
  11. 裁剪区间:TrimRange,裁剪片段的起始点和长度。详情可以参考【基础结构和概念】中的【Range 相关】一节。
  12. 出入区间:DestRange,效果在工程上的起始点和长度。详情可以参考【基础结构和概念】中的【Range 相关】一节。
  13. 导出:Export,将工程以指定分辨率、码率、帧速率和压缩格式输出文件。
  14. 码率:Bitrate,每秒传送的比特数,码率越高,导出视频质量越好。
  15. 帧速率:FPS,每秒刷新图像的帧数,帧速率越高,视频的连续性越好。
  16. 素材包:一种资源文件,用于给工程添加效果使用。特地效果有特地的素材包,主题和卡点视频主题也都有素材包。详情可以参考【素材管理】一节。
  17. 素材包 ID:素材包的唯一标识,安装素材后,可以通过解析素材获取。详情可以参考【素材管理】一节。

二、基础结构与概念

1. 支持格式

  • 输入规范:

    视频格式:MP4、MOV、WMV。 音频格式:MP3、AAC、M4A。 图片格式:JPG、PNG。 视频编码:H264、WMV、MPEG4。 音频编码:MP3、AAC。

  • 输出规范:

    视频格式:MP4、MOV 视频编码:H264 音频编码:AAC

2. 模块结构

剪辑 SDK 核心模块包括剪辑工程、片段、音频、效果、播放器等。

剪辑工程是 SDK 中最基础的模块,它负责生成、保存并维护 SDK 引擎剪辑的上下文环境。片段是工程的基础,是导出视频的组成元素。效果包括贴纸、画中画、字幕、特效、水印、马赛克等,各种效果、音频和片段共同组合形成最终的视频输出。片段上可以添加各种滤镜,片段之间可以设置不同的转场效果。

3. 图层轨道

效果和音频可以在指定区间设置自己的图层(水印和背景音乐除外),高图层的效果可以对低图层的效果起作用或遮挡低图层效果。当两个效果在同一图层时,如果出入点时间不覆盖,则不互相影响;如果出入点时间覆盖,则覆盖时间区间的效果将无法预期。所以尽量给每个效果设定独立的图层,以免最终视频效果不符合预期。

图层限制区间: 音效/录音图层:[10,10000),左边闭区间,右边开区间。 效果图层:[10000,1000000),左边闭区间,右边开区间。(贴纸、字幕、画中画、特效、马赛克)

例: 1)贴纸 1 在图层 100000,贴纸 2 在图层 90000,如果贴纸 1 和贴纸 2 的位置和时间相同时,则贴纸 1 会遮挡贴纸 2。 2)特效 1 在图层 100000,贴纸 1 在图层 90000,贴纸 2 在图层 110000,如果特效 1、贴纸 1 和贴纸 2 的时间相同,则特效对贴纸 1 产生影响,不对贴纸 2 产生影响。

4. 区间 Range 相关:

srcRange::源文件区间,视频源文件选择的时间区间。 trimRange:裁剪区间,裁剪片段的起始点和长度。 destRange:出入区间,效果在工程上的起始点和长度。

5. 坐标系

剪辑中使用的正常坐标系,统一使用视频流(stream)的坐标系,即视频流的左上角为(0, 0),右下角为(stream.width,stream.height)。角度水平向右为 0 度,顺时针为增大。

剪辑中使用的万分比坐标系,统一使用视频流转化为对应比例的坐标系,即视频流的左上角为(0, 0),右下角为(10000,10000)。 即把 stream 映射到万分比左边中,10000 级表示 stream.width 或 stream.height。

6. 剪辑操作符

由于剪辑需要始终保持单线程操作,所以在工程剪辑时,我们将每个操作定义为一个剪辑操作符 BaseOperate。剪辑操作符有 sdk 已经预设的大量操作符,开发者也可以自行组合实现新的操作符。执行时,开发者只需要创建操作符,并将操作符交给 workspace 执行即可,接下来就是等待执行完成的回调。

BaseOperate operate = new BaseOperate();
workspace.handleOperation(operate);

为满足开发者可能存在的特殊需求,操作符也可以进行同步操作,使用代码:

BaseOperate operate = new BaseOperate();
workspace.syncOperation(operate);

由于工程操作时,必须保证只有单个操作正在执行,所以操作符建议只使用一种方式,或者在异步操作完成时,再进行同步操作。 需要注意的是,同步操作暂不支持【高级玩法-对撤销/重做的支持】,强烈建议尽量使用操作符的异步编辑方式。以免出现不必要的并发问题。

三、项目搭建

为了方便开发者进行开发,可以先下载适用于 Android Studio 的 Demo 代码。强烈建议使用 Android Studio(http://developer.android.com/sdk/index.html)进行开发。

1. 前期准备

请向趣维公司申请允许使用剪辑 SDK 的 license 文件,该文件具备有效期。如有升级需要,请自行实现更新系统。

对剪辑 SDK 文档中的名词解释和基础结构与概念先做了解。

2. 创建一个 Android Studio 工程

1)剪辑 SDK 使用的 minSdkVersion 是 21。为了保证兼容性,请在创建工程时将 minSdkVersion 设置为 21。

打开 Android Studio,新建工程如下,填写 Application name 和 Company Domain。点击 Next。将 minimum SDK 更改为 API 21:Android 5.0(Lollipop)。点击 Finish。

2)在项目根目录的 build.gradle 文件中,添加配置

allprojects {
    repositories {
        google()
        jcenter()
        maven {
            url 'https://serverless-1533657941-maven.pkg.coding.net/repository/app-sdk-pub/bintray/'
        }
    }
}

3)在 app 目录的 build.gradle 中,添加配置,ndk 可以根据实际需要选择配置,以降低 APK 包体大小,当前支持 armeabi、armeabi-v7a、arm64-v8a。

android {
    defaultConfig {
        ndk {
            // 按需选择,以降低 APK 包体大小
            abiFilters "armeabi", "armeabi-v7a", "arm64-v8a"
        }
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    sourceSets {
        main {
          jniLibs.srcDirs = ['libs']
        }
    }
  }
}

dependencies {
    //剪辑 SDK
    implementation "com.quvideo.mobile.external:sdk-engine:4.5.0"
}

3. 剪辑 SDK 初始化

在开始使用剪辑功能前,必须对剪辑 SDK 初始化

QEInitData.Builder builder = new QEInitData.Builder(licensePath);
QEEngineClient.init(context, builder.build());

QEInitData 参数说明:

名称 解释 类型 是否必须
licensePath license 文件路径地址,可以是 assets 目录。(注意:android 10 以上只支持放在私有目录中,请保证使用完整绝对路径) String 必须
projectDir 剪辑工程文件存放路径,默认存放剪辑工程的地址,删除 APP 或清除用户数据时会被清除(注意:android 10 以上只支持放在私有目录中,请保证使用完整绝对路径的目录) number 非必须
hwCodecCapPath 设备软硬件配置文件(注意:android 10 以上只支持放在私有目录中,请保证使用完整绝对路径) string 非必须
corruptImgPath clip 错误时显示图片地址(注意:android 10 以上只支持放在私有目录中,请保证使用完整绝对路径) string 非必须
isUseStuffClip 是否末尾补黑帧,默认 false(详解【高级玩法-自由黑帧模式】一章说明) boolean 非必须
iTextPrepareListener 默认文本宏替换数据 ITextPrepareListener 非必须

注意: 简单的 xyt 文件和 license 文件支持放在 assets 目录中直接使用,但是路径名有规范,必须以"assets_android://"开头,如: "assets_android://qvlicense/license.txt" 和 "assets_android://quvideo/trans/0x030000000000012D.xyt"。

四、素材管理开发接入

1. 素材安装

同一个素材,只需要安装一次即可,后续直接通过素材 id 即可查询素材信息。

注意: 1.assets 目录下的素材安装,每次需要完整列表重新安装,会进行增删处理。对于 asset 目录下的素材,升级时如有需要,可以完整重新安装一次,用于素材变更。 2.android 10 以上只支持放在私有目录中,所有素材请保证使用完整绝对路径

/** 安装单个素材文件,zip 包或者 xyt 文件 */
XytManager.install(xytZipPath, xytInstallListener);

/** List<String> xytZipPaths,zip 包或者 xyt 文件列表 */
XytManager.install(xytZipPaths, xytInstallListener);

/** 安装多个 asset 目录下的素材文件,只能是 xyt 文件列表 */
XytManager.installAsset(assetPathList, xytInstallListener);

/** 卸载单个素材,只能是 xyt 文件列表,ttid 为素材 id */
XytManager.unInstall(ttid, xytInstallListener);

XytInstallListener 接口信息:

public interface XytInstallListener {

  void onSuccess();

/**
 * @param filePaths 安装失败的素材文件列表
 * @param errorCode 错误码
 */
  void onFailed(List<String> filePaths, int errorCode);
}

2. 素材信息查询

/**
* 通过素材 id 查询素材信息
*/
XytInfo xytInfo = XytManager.getXytInfo(ttidLong);


/**
* 通过素材路径查询素材信息
*/
XytInfo xytInfo = XytManager.getXytInfo(xytPath);

XytInfo 参数说明:

名称 解释 类型
ttidLong 素材 id long
ttidHexStr 素材 id 的十六进制 如:0x06000000000000D9 String
filePath 素材路径 String

3. 素材工具

 /**
   * Long 转成 16 进制 ttid 字符串
   * 如:1225031875203433521-->"0x1100300000080431"
   */
  String hexStr = QEXytUtil.ttidLongToHex(ttidLong);

  /**
   * 16 进制 ttid 转成 Long
   * 如:""0x1100300000080431"-->1225031875203433521
   */
   long ttid = QEXytUtil.ttidHexStrToLong(ttidHexStr);

  /**
   * 是否 mv 主题
   */
  boolean isMvTheme = QEXytUtil.isMVTheme(ttidLong);

  /**
   * 获取主题上配置的 获取封面的最佳时间点
   */
  int timePos = QEXytUtil.getThemeCoverPos(themePath);

  /**
   * 获取转场配置时长
   */
  int duration = QEXytUtil.getTranDuration(transPath);

  /**
   * 获取转场时长是否可编辑
   */
  boolean isEditable = QEXytUtil.getTranEditable(transPath);

  /**
   * 获取效果插件素材的所有属性信息
   */
   List<SubPluginAttriItem> attriItems = QEXytUtil.getIEPropertyInfo(templateId);
  /**
   * 获取转场时长是否可编辑
   */
  boolean isEditable = QEXytUtil.getTranEditable(transPath);

  /**
   * 特效素材是否支持添加给画中画
   */
   boolean isSupport = isSupportSubFx(String subFxPath);

五、录制功能开发接入

1. 录制视频

1)初始化。

创建 XYCamreaEngine 实例。

XYCameraEngine mXYCamera = new XYCameraEngine(activity, screenSize, ICameraEventCallback);

ICameraEventCallback 说明:

public interface ICameraEventCallback {

  /**
   * 拍照完成
   * @param filePath 文件路径
   */
  void onCaptureDone(String filePath);

  /**
   * 录制中回调
   * @param duration 录制时长
   */
  void onRecorderRunning(long duration);

  /**
   * 停止录制
   */
  void onRecorderStop(WorkThreadTaskItem workThreadTaskItem);

  /**
   * 暂停录制
   */
  void onRecorderPaused();

  /**
   * 录制准备完成
   */
  void onRecorderReady();

  /**
   * 录制时长溢出
   */
  void onRecorderDurationExceeded();

  /**
   * 录制文件大小溢出
   */
  void onRecorderSizeExceeded();

  /**
   * 人脸检测结果
   * 因未集成人脸库,不可用
   * @param isDetected 是否检测到人脸
   */
  void onFaceDetectResult(boolean isDetected);

  /**
   * 相机连接结果
   * @param isConnected 是否成功
   */
  void onConnectResult(boolean isConnected);

  /**
   * 相机断开连接
   */
  void onDisConnect();

  /**
   * 开始预览
   */
  void onPreviewStart();

  /**
   * 停止预览
   */
  void onPreviewStop();

  void onPipSrcObjEnd();

}

2)搭建 Camera 预览

初始化 Preview 需要传入 FrameLayout 作为 SurfaceView 的父布局,内部会自动创建 SurfaceView add 到 FrameLayout 中

mXYCamera.initPreview(mSurfaceContainer);

连接 Camera

mXYCamera.openCamera();

注意:连接 Camera 之前需要确保已申请过 Camera 权限,如果没有需要向用户申请

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

启动预览 在 Camera 连接成功的回调中启动预览

@Override public void onConnectResult(boolean isConnected) {
  if (isConnected) {
    mXYCamera.setDeviceIsPortrait(true,
XYCameraConst.CameraDegrees.DEGREES_PORTRAIT);
    // 启动预览
    mXYCamera.startPreview();
  }
}

关闭 Camera

mXYCamera.closeCamera();

停止预览,在 Camera 断开连接的回调中停止预览

@Override public void onDisConnect() {
  mXYCamera.stopPreview();
}

3) Camera 录制

开始录制需要传递 XYRecorderParam 参数,该参数可以自定义一些录制参数。

mXYCamera.startRecording(new XYRecorderParam(filePath,mXYCamera.getOutPutSize(),mXYCamera.getCurCameraId() == XYCameraConst.CameraId.CAMERA_FRONT));

XYRecorderParam 参数说明:

名称 解释 类型
outputFilePath 视频录制文件路径 String
outputSize 视频录制尺寸 VeMSize
isFrontCamera 是否前置摄像头 boolean

暂停录制会返回当次录制的 start 位置与 end 位置,这样可以知道本次录制在 mp4 文件中的 range

int[] range = mXYCamera.pauseRecording();

继续录制

mXYCamera.resumeRecording();

停止录制 停止录制同样会返回当次录制的 start 位置与 end 位置,如果在当前本来就是暂停录制状态,则可以忽略该 range

int[] range = mXYCamera.stopRecording();

设置录制方向 需要固定 Activity 的屏幕方向 android:screenOrientation="portrait" 如果需要横屏录制,可以用以下接口设置。参考 XYCameraConst.CameraDegrees

mXYCamera.setDeviceIsPortrait(true, XYCameraConst.CameraDegrees.DEGREES_PORTRAIT);

4) Camera 设置

切换镜头,参数参见 XYCameraConst. CameraId

mXYCamera.switchCameraId(XYCameraConst.CameraId.CAMERA_FRONT);

闪光灯,参数参见 XYCameraConst.FlashMode

mXYCamera.getCameraDevice().setFlashMode(XYCameraConst.FlashMode.FLASH_TORCH);

对焦

mXYCamera.getCameraDevice().autoFocus(new Camera.AutoFocusCallback() {
  @Override public void onAutoFocus(boolean success, Camera camera) {

  }
});

焦距调节

mXYCamera.getCameraDevice().setCameraZoom(zoomValue);

焦距范围 0~max

mXYCamera.getCameraDevice().getCameraZoomMax();

曝光调节

mXYCamera.getCameraDevice().setCameraExposure(value);

曝光参数获取

mXYCamera.getCameraDevice().getCameraExposureStep();
mXYCamera.getCameraDevice().getCameraExposureMin();
mXYCamera.getCameraDevice().getCameraExposureMax();

比例调节 参数参见 XYCameraConst.RatioMode,第 2 个参数为距离屏幕上边的距离,用于调节 SurfaceView 的区域

mXYCamera.setRatio(XYCameraConst.RatioMode.RATIO_4_3, 200);

其他 Camera 设置,可以使用 Camera Parameters 来设置

mXYCamera.getCameraDevice().getParameters();
mXYCamera.getCameraDevice().setParameters();

5) Camera 预览效果设置

滤镜设置

mXYCamera.setEffect(effectPath);

美颜设置 开启美颜,value 为默认指。范围为 0~100

mXYCamera.initFaceBeautyMode(value);

美颜参数调节

mXYCamera.setFaceBeautyParam(value);

关闭美颜

mXYCamera.clearFaceBeautyParam();

6) 拍照

传入照片保存路径。 注意:该照片分辨率为 preview size。

mXYCamera.takePicture(filePath);

接收拍照完成回调

@Override public void onCaptureDone(String filePath) {
}

7) 音乐镜头 音乐镜头需要结合开发者晚饭,实现逻辑如下:

  • 使用 MediaPlayer 加载音乐
  • 在开始录制时,同时播放音乐,录制过程中,音乐会同时录制进去
  • 选取一段音乐就是加载音乐后,seek 到 start 位置,并在 end 位置停止录制。 详情参见 demo 中的实现逻辑

2. 音频录制

初始化

XYAudioRecorder.init()

开始录制

// audioFilePath 表示录音文件路径
XYAudioRecorder.startRecord(audioFilePath);

停止录制

XYAudioRecorder.stopRecord();

获取录制时长

XYAudioRecorder.getRecordDuration()

六、剪辑工程功能开发接入

1. 剪辑工程

创建和加载
  /**
   * 创建新的工程
   */
  QEEngineClient.createNewProject(QEWorkSpaceListener)
  /**
   * 加载工程
   */
  QEEngineClient.loadProject(String url, QEWorkSpaceListener qeWorkSpaceListener);
工程删除

方式一:

  /**
   * 删除工程
   */
  QEEngineClient.deleteProject(String projectPath)

方式二:

  /**
   * 删除工程
   */
  IQEWorkSpace.deleteProject(String projectPath)
工程释放

工程编辑结束,需要完整释放工程。

  /**
   * 释放工程缓存
   * param needSave 是否需要保存工程
   */
  IQEWorkSpace.destory(needSave)

如果只是想临时释放工程注册的各项监听器,则调用:

  /**
   * 销毁播放器和注册的监听器,播放器监听和操作队列监听
   * 当需要重新使用时,需要重新绑定播放器和各种监听器
   */
  IQEWorkSpace.unbindUI()

2. 播放器

1)在 Activity 的 layout 中添加播放器 View

  <com.quvideo.mobile.engine.player.EditorPlayerView
      android:id="@+id/editor_play_view"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      />

2)在工程加载成功后,可以绑定工程和播放器

 //
 // initTime 为初始博翻墙需要定位的时间点,默认 0 即可
 mWorkSpace.getPlayerAPI().bindPlayerView(editorPlayerView, initTime);

3)获取播放器控制器

IPlayerController playerController = mWorkSpace.getPlayerAPI().getPlayerController();

IPlayerController 说明:

public interface IPlayerController {
  /** 是否播放中 */
  boolean isPlaying();
  /** 是否暂停 */
  boolean isPause();
  /** 是否停止 */
  boolean isStop();
  /** 播放 */
  int play();
  /** 暂停 */
  int pause();
  /** 播放或暂停切换 */
  int playOrPause();
  /** 设置音量 */
  int setVolume(int volume);
  /** 异步 seek 到时间点 */
  void seek(int time);
  /** 异步 seek 到时间点,playAfterSeek 为 seek 后自动播放 */
  void seek(int time, boolean playAfterSeek);
  /** 获取当前时间 */
  int getCurrentPlayerTime();
  /** 获取播放器总时长 */
  int getPlayerDuration();
  /** 设置播放区域 */
  int setPlayRange(int start, int length);
  /** 获取播放区域 */
  VeRange getPlayerRange();
}

4)注册播放器监听器 注册:

mWorkSpace.getPlayerAPI().registerListener(QEPlayerListener);

注销:

mWorkSpace.getPlayerAPI().unregisterListener(QEPlayerListener);

QEPlayerListener 说明:

public interface QEPlayerListener {

  enum PlayerStatus {
    STATUS_READY,
    STATUS_PLAYING,
    STATUS_SEEKING,
    STATUS_PAUSE,
    STATUS_STOP
  }

  /** 播放器状态回调 */
  void onPlayerCallback(PlayerStatus playerStatus, int progress);
  /** 播放器刷新 */
  void onPlayerRefresh();
  /** 播放器尺寸变化 */
  void onSizeChanged(Rect resultRect);
}

5) 关于 PlayerAPI

通过 mWorkSpace.getPlayerAPI()可以获取 PlayerAPI 播放器相关接口

public interface PlayerAPI {
  /** 绑定播放器 */
  void bindPlayerView(EditorPlayerView editorPlayerView, int initTime);
  /** 注册播放器监听 */
  void registerListener(QEPlayerListener listener);
  /** 注销播放器监听 */
  void unregisterListener(QEPlayerListener listener);
  /** 获取播放器控制器 */
  IPlayerController getPlayerControl();
  /** 获取预览区尺寸 */
  VeMSize getSurfaceSize();
  /** 获取播放器 view 尺寸 */
  VeMSize getPreviewSize();
}

6) 关于 IQEWorkSpace 的其他方法


  /**
   * 通过偏移时间点拿到关键帧后的位置信息
   *
   * @param offsetTime 从 effect 开始的偏移时间
   */
  public EffectPosInfo getEffectPosInfoByTime(int groupId, int effectIndex, int offsetTime);

  /**
   * 通过当前时间拿到关键帧 level 透明度(指的是 overlay subEffect)
   *
   * @param offsetTime 当前相对时间点
   */
  public int getAlphaInfoByTime(int groupId, int effectIndex, int offsetTime);

  /**
   * 通过当前时间拿到属性关键帧的 value 值
   *
   * @param offsetTime 当前相对时间点
   */
  public float getAttriInfoByTime(int groupId, int effectIndex, int subType, String attrName, int offsetTime);

  /**
   * 配置变速时获取相应的 src/scale 时间(针对使用了变速的区域)
   * bSrc 为 true 时,range 应该传入原始时间,返回的是缩放后的时间,
   * bSrc 为 false 时,range 应该传入缩放后的时间,返回的是原始时间;
   */
  public VeRange convertSpeedRange(int clipIndex, VeRange range, boolean isSrc);

3. 获取剪辑工程信息

获取工程相关信息
  /** 获取工程路径 */
  mWorkSpace.getProjectUrl();
  /** 获取工程目录 */
  mWorkSpace.getProjectDir();
  /** 获取更多工程信息 */
  StoryboardAPI storyboardAPI = mWorkSpace.getStoryboardAPI();
  /** 获取片段信息 */
  ClipAPI clipAPI = mWorkSpace.getClipAPI();
  /** 获取效果信息 */
  EffectAPI effectAPI = mWorkSpace.getEffectAPI();

StoryboardAPI 信息:

public interface StoryboardAPI {
  /** 获取分辨率 */
  VeMSize getStreamSize();

  /** 获取总时长 */
  int getDuration();

  /** 获取主题 id */
  long getThemeId();

  /** 获取是否 mv 主题相册工程 */
  boolean isMVProject();

  /** 获取主题片头 */
  ClipData getCover();

  /** 获取主题片尾 */
  ClipData getBackCover();

  /** 获取主题字幕列表 */
  List<ThemeSubtitleEffect> getThemeTitleInfoList();
}

ClipAPI 信息:

public interface ClipAPI {

  /** 获取所有 clip 信息 */
  List<ClipData> getClipList();

  /** 获取指定位置的 clip 信息 */
  ClipData getClipByIndex(int clipIndex);
}

EffectAPI 信息:

public interface EffectAPI {
  /** 获取所有效果信息并按 groupid 分组 */
  SparseArray<List<BaseEffect>> getAllEffect();

  /** 获取 groupid 的所有效果信息 */
  List<BaseEffect> getEffectList(int groupId);

  /** 根据 groupId 和 effectIndex 所有获取效果信息 */
  BaseEffect getEffect(int groupId, int effectIndex);
}

备注:由于 StoryboardAPI、ClipAPI 和 EffectAPI 返回的数据都是 clone 数据,所有直接对返回的数据修改,是不起作用的。

效果分类 groupId 说明
public class QEGroupConst {
  /** 背景音乐 */
  public static final int GROUP_ID_BGMUSIC = 1;
  /** 音效 */
  public static final int GROUP_ID_DUBBING = 4;
  /** 录音 **/
  public static final int GROUP_ID_RECORD = 11;
  /** 字幕 */
  public static final int GROUP_ID_SUBTITLE = 3;
  /** 特效, 和特效滤镜不同 */
  public static final int GROUP_ID_STICKER_FX = 6;
  /** 贴纸 */
  public static final int GROUP_ID_STICKER = 8;
  /** 画中画 */
  public static final int GROUP_ID_COLLAGES = 20;
  /** 马赛克 */
  public static final int GROUP_ID_MOSAIC = 40;
  /** 自定义水印 */
  public static final int GROUP_ID_WATERMARK = 50;
}
数据结构说明

1) 片段 Clip 相关 ClipData 参数说明:

名称 解释 类型
uniqueId clip 的唯一识别码 String
mType 类型{@see ClipData.ClipType} ClipType
mClipFilePath 片段文件路径 String
isVideo 是否视频 boolean
srcRange 源文件区间 VeRange
trimRange 片段裁切区间 VeRange
destRange 片段出入区间 VeRange
cropRect 裁剪区域(万分比区域) Rect
sourceSize 源视频宽高,相对 streamSize 的尺寸 VeMSize
rotateAngle 旋转角度 int
isMute 是否静音 boolean
audioVolume 音量,默认 100 int
soundTone 变声,-60~60,正常 0。{@see QEDftSoundTone}类中有提供的特定音调 float
timeScale 变速值,默认 1.0f float
isKeepTone 是否变速不变调,默认 true。false 时,设置变速会对音调产生影响 boolean
mirror 镜像{@see ClipData.Mirror} Mirror
bReversed 是否倒放 boolean
isPicAnimOn 是否开启图片动画,只允许对图片 clip 设置 boolean
crossInfo 转场,null 表示无。当前片段和下一个片段的转场数据{@see CrossInfo} CrossInfo
filterInfo 滤镜信息 FilterInfo
fxFilterInfo 特效滤镜信息,null 表示无{@see FxFilterInfo} FxFilterInfo
mParamAdjust 参数调节信息{@see ParamAdjust} ParamAdjust
mClipPosInfo 片段位置信息{@see ClipPosInfo} ClipPosInfo
mClipBgData 片段背景信息{@see ClipBgData} ClipBgData
mColorCurveInfo 曲线调色信息数据 {@see ColorCurveInfo} ColorCurveInfo

ClipData.ClipType 参数说明:

名称 解释
NORMAL 正常 clip
THEME_COVER 主题片头
THEME_BACKCOVER 主题片尾

ClipData.Mirror 参数说明:

名称 解释
CLIP_FLIP_NONE 正常
CLIP_FLIP_X 沿 X 方向镜像
CLIP_FLIP_Y 沿 Y 方向镜像
CLIP_FLIP_XY 沿 XY 方向镜像

CrossInfo 参数说明:

名称 解释 类型
crossPath 转场路径 String
duration 转场时长 int
cfgIndex 转场效果样式,有些素材包含多种效果,表示使用第几个效果,默认 0 int

FilterInfo 参数说明:

名称 解释 类型
filterPath 滤镜路径 String
filterLevel 滤镜程度,0~100 int
externalSource 滤镜外部图片源数据,依赖模板支持(如 3D LUT 滤镜模板) String

FxFilterInfo 参数说明:

名称 解释 类型
filterPath 特效滤镜路径 String

ParamAdjust 参数说明:

名称 解释 类型
brightness 亮度,0~100,默认 50 int
contrast 对比度,0~100,默认 50 int
sharpness 锐度,0~100,默认 50 int
saturation 饱和度,0~100,默认 50 int
temperature 色温,0~100,默认 50 int
vignette 暗角,0~100,默认 50 int
hue 色相,0~100,默认 50 int
fade 褪色,0~100,默认 0 int
shadow 阴影,0~100,默认 50 int
highlight 高光,0~100,默认 50 int
noise 颗粒,0~100,默认 0 int

ClipPosInfo 参数说明:

名称 解释 类型
centerPosX 中心点-X,在 streamSize 的坐标系中 int
centerPosY 中心点-Y,在 streamSize 的坐标系中 int
widthScale 宽放大倍数,默认 1 float
heightScale 高放大倍数,默认 1 float
degree 旋转角度,0~359 度 float

ClipBgData 参数说明:

名称 解释 类型
clipBgType 背景类型 ClipBgType
colorArray color,最多可以支持三色渐变 int[]
colorAngle 颜色渐变角度:默认 0-水平方向。0~360 int
blurLen 模糊程度:0~100 int
imagePath 图片背景,自定义图片背景使用 String

ClipBgData.ClipBgType 参数说明:

名称 解释
BLUR 模糊背景
COLOR 纯色背景
PICTURE 图片背景

ColorCurveInfo 参数说明:

名称 解释 类型
mColorCurveItems 曲线调色详情{@see ColorCurveItem} ColorCurveItem

ColorCurveItem 参数说明:

名称 解释 类型
ts 曲线调色点的相对时间 int
rgb 曲线调色 rgb 信息点数据 QPoint
red 曲线调色 red 信息点数据 QPoint
green 曲线调色 green 信息点数据 QPoint
blue 曲线调色 blue 信息点数据 QPoint

注意: 1.曲线调色信息列表,每个 ColorCurveItem 需要按 ts 排序,如果不需要渐变,则只需要一个 ColorCurveItem 即可。 2.rgb/red/green/blue 信息列表,QPoint 的 x、y 取值范围都是 0~255。需按 x 的从小到大排序,且至少需要保证有 x=0 和 x=255 的两个点。

2) 效果 Effect 相关 效果类继承结构:

BaseEffect 参数说明:

名称 解释 类型
uniqueId effect 的唯一识别码 String
groupId 效果 Group 分类 id int
mEffectPath 效果素材文件路径 String
isApplyByTheme 是否主题添加 boolean
srcRange 源文件区间 VeRange
trimRange 效果裁切区间 VeRange
destRange 效果出入区间 VeRange
effectLayerId 效果图层 id,数字越大 层级越高 float
isHadAudio 效果是否带有音频数据 boolean
audioVolume 音量 int

AudioEffect 参数说明:

名称 解释 类型
mAudioInfo 音频数据信息 {@see EffectAudioInfo} EffectAudioInfo

EffectAudioInfo 参数说明:

名称 解释 类型
isRepeat 是否循环,默认开始 boolean
soundTone 变声,-60~60,正常 0。{@see QEDftSoundTone}类中有提供的特定音调 float
audioFadeIn 渐入,只对背景音乐有效 {@see AudioFade} AudioFade
audioFadeOut 渐出,只对背景音乐有效 {@see AudioFade} AudioFade
audioLyric 歌曲字幕信息 {@see AudioLyric} AudioLyric
musicMsg 音乐信息,开发者可以用于存储音乐相关的信息 String

AudioFade 参数说明:

名称 解释 类型
type 渐入渐入类型 {@see AudioFade.Type} AudioFade.Type
duration 渐变时长,0 则无效果 int

AudioFade.Type 参数说明:

名称 解释
FadeIn 渐入
FadeOut 渐出

AudioLyric 参数说明:

名称 解释 类型
lyricPath 歌曲字幕 lyric 文件路径 string
lyricTtid 歌词模板的素材 id long

FloatEffect 参数说明:

名称 解释 类型
alpha 透明度 0~100 int
mMirror 镜像信息 {@see FloatEffect.Mirror} Mirror
mEffectPosInfo 效果位置数据信息 {@see EffectPosInfo} EffectPosInfo

FloatEffect.Mirror 参数说明:

名称 解释
EFFECT_FLIP_NONE 正常
EFFECT_FLIP_X 沿 X 方向镜像
EFFECT_FLIP_Y 沿 Y 方向镜像
EFFECT_FLIP_XY 沿 XY 方向镜像

EffectPosInfo 参数说明:

名称 解释 类型
center 中心点,实际为锚点坐标,{@see Ve3DDataF} 只是默认在中心点,(0,0,0)为效果以 streamsize 的中心点,x/y 左上角为 0,右下角为 1,z 为屏幕上为 0,向屏幕里为正,向屏幕外为负 Ve3DDataF
size 尺寸,(0,0,0)为效果以 streamsize 的宽高深 Ve3DDataF
degree 旋转角度,(0,0,0)为效果以 x/y/z 轴的旋转角度 。取值范围是 0~360 Ve3DDataF
anchorOffset 锚点相对中心点的偏移,默认(0,0,0) Ve3DDataF

Ve3DDataF 参数说明:

名称 解释 类型
x x 轴方向信息 float
y y 轴方向信息 float
z z 轴方向信息 float

AnimEffect 参数说明:

名称 解释 类型
mEffectOverlayInfo 混合模式信息数据 {@see EffectOverlayInfo} EffectOverlayInfo
mEffectMaskInfo 蒙版位置信息数据 {@see EffectMaskInfo} EffectMaskInfo
mEffectChromaInfo 抠色信息数据(绿幕) {@see EffectChromaInfo} EffectChromaInfo
mFilterInfo 滤镜信息数据 {@see FilterInfo} FilterInfo
mParamAdjust 参数调节信息数据 {@see ParamAdjust} ParamAdjust
mColorCurveInfo 曲线调色信息数据 {@see ColorCurveInfo} ColorCurveInfo
mEffectSubFxList 子特效列表信息数据 {@see EffectSubFx} EffectSubFx
mEffectKeyFrameInfo 关键帧信息数据 {@see EffectKeyFrameInfo}(由于功能复杂,后期可能调整数据结构) EffectKeyFrameInfo

EffectOverlayInfo 参数说明:

名称 解释 类型
overlayPath 混合模式素材路径 String
level 混合程度,改参数和透明度一个效果,0~100 int

EffectMaskInfo 参数说明:

名称 解释 类型
maskType 蒙版类型{@see EffectMaskInfo.MaskType} MaskType
centerX 中心点-X,中心点尽量保持在素材位置内。相对画中画的万分比坐标(字幕比较特殊,需要相对 streamsize 的万分比坐标) float
centerY 中心点-Y,中心点尽量保持在素材位置内。相对画中画的万分比坐标(字幕比较特殊,需要相对 streamsize 的万分比坐标) float
radiusY 垂直方向半径,相对画中画的万分比坐标(字幕比较特殊,需要相对 streamsize 的万分比坐标) float
radiusX 水平方向半径,相对画中画的万分比坐标(字幕比较特殊,需要相对 streamsize 的万分比坐标) float
rotation 旋转角度, 0~360 float
softness 羽化程度,取值范围:[0~10000] int
reverse 是否反选 boolean
maskKeyFrameInfo 蒙版关键帧信息{@see MaskKeyFrameInfo} MaskKeyFrameInfo

EffectMaskInfo.MaskType

名称 解释
MASK_NONE 无蒙版
MASK_LINEAR 线性蒙版
MASK_MIRROR 镜像蒙版
MASK_RADIAL 径向蒙版
MASK_RECTANGLE 矩形蒙版

MaskKeyFrameInfo 参数说明:

名称 解释 类型
maskPosList 蒙版位置关键帧信息列表{@see KeyMaskPosInfo} KeyMaskPosInfo 列表
rotationList 旋转角度关键帧信息列表{@see KeyAttributeInfo} KeyAttributeInfo 列表
softnessList 羽化程度关键帧信息列表{@see KeyAttributeInfo} KeyAttributeInfo 列表
reverseList 反选信息关键帧信息列表{@see KeyBAttrInfo} KeyBAttrInfo 列表

KeyMaskPosInfo 参数说明:

名称 解释 类型
centerX 中心点-X,中心点尽量保持在素材位置内。相对画中画的万分比坐标(字幕比较特殊,需要相对 streamsize 的万分比坐标) float
centerY 中心点-Y,中心点尽量保持在素材位置内。相对画中画的万分比坐标(字幕比较特殊,需要相对 streamsize 的万分比坐标) float
radiusY 垂直方向半径,相对画中画的万分比坐标(字幕比较特殊,需要相对 streamsize 的万分比坐标) float
radiusX 水平方向半径,相对画中画的万分比坐标(字幕比较特殊,需要相对 streamsize 的万分比坐标) float

KeyBAttrInfo 参数说明:

名称 解释 类型
attrValue 属性关键帧:属性值 boolean

EffectChromaInfo 参数说明:

名称 解释 类型
enable 是否开启 boolean
color 抠色的颜色值, 如 0xFFFFFF int
accuracy 抠色的精度(0~5000) int

EffectSubFx 参数说明:

名称 解释 类型
subFxPath 子特效素材路径 String
subType 子特效索引,不可修改 1000~2000
destRange 子特效出入点区间,相对效果的时间 VeRange

EffectKeyFrameInfo 参数说明:(由于功能复杂,后期可能调整数据结构)

名称 解释 类型
positionList 位置关键帧列表 {@see KeyPosInfo} KeyPosInfo
scaleList 缩放关键帧列表 {@see KeyScaleInfo} KeyScaleInfo
rotationList 旋转角度关键帧列表{@see KeyRotationInfo} KeyRotationInfo
alphaList 不透明度关键帧列表{@see KeyAlphaInfo} KeyAlphaInfo

BaseKeyFrame 参数说明:

名称 解释 类型
keyFrameType 关键帧类型 KeyFrameType
relativeTime 相对于效果入点的时间 int
isCurvePath 关键帧是否曲线路径 boolean
mKeyBezierCurve 关键帧缓动贝塞尔曲线点{@see KeyBezierCurve} KeyBezierCurve
offsetOpcodeType 基础偏移操作方式{KEYFRAME_COMMON_OFFSET_TYPE_PLUS 相加, KEYFRAME_COMMON_OFFSET_TYPE_MUL 相乘} int

KeyFrameType 参数说明:

名称 解释
Position 位置关键帧
AnchorOffset 锚点位移关键帧
Scale 缩放关键帧
Rotation 旋转关键帧
Alpha 透明度关键帧
Mask 蒙版关键帧,暂不支持
Attribute 属性关键帧,暂不支持

KeyBezierCurve 参数说明:

名称 解释 类型
start 贝塞尔缓动曲线起点,需固定( 0,0) QPoint
stop 贝塞尔缓动曲线终点,需固定( 10000,10000) QPoint
c0 贝塞尔缓动节点 1 QPoint
c1 贝塞尔缓动节点 2 QPoint

KeyPosInfo 参数说明:

名称 解释 类型
center 位置信息,在 streamSize 的坐标系中{@see Ve3DDataF} Ve3DDataF
baseOffset 位置偏移,相对 center 再做一个偏移{@see Ve3DDataF} Ve3DDataF

KeyAnchorOffset 参数说明:

名称 解释 类型
anchorOffset 锚点位置偏移信息,在 streamSize 的坐标系中{@see Ve3DDataF} Ve3DDataF
baseOffset 锚点偏移,相对 anchorOffset 再做一个偏移{@see Ve3DDataF} Ve3DDataF

KeyScaleInfo 参数说明:

名称 解释 类型
scale 缩放信息 {@see Ve3DDataF} Ve3DDataF
baseOffset 缩放倍数偏移,相对 scale 再做一个乘积偏移{@see Ve3DDataF} Ve3DDataF

KeyRotationInfo 参数说明:

名称 解释 类型
rotation 角度信息 {@see Ve3DDataF} Ve3DDataF
baseOffset 角度偏移,相对 rotation 再做一个角度偏移{@see Ve3DDataF} Ve3DDataF

KeyAlphaInfo 参数说明:

名称 解释 类型
alpha 不透明度 0~100 int

CollageEffect 参数说明:

名称 解释 类型
timeScale 变速值,默认 1.0f float
isVideoReverse 是否倒放视频源,视频&音频可分开倒放 boolean
isAudioReverse 是否倒放音频源,视频&音频可分开倒放 boolean

MosaicEffect 参数说明:

名称 解释 类型
mosaicInfo 马赛克模糊程度数据信息 {@see MosaicInfo} MosaicInfo

MosaicInfo 参数说明:

名称 解释 类型
horValue 水平模糊程度 int
verValue 垂直模糊程度 int

SubtitleEffect 参数说明:

名称 解释 类型
textBubbleInfo 字幕数据信息 {@see TextBubbleInfo} TextBubbleInfo

TextBubbleInfo 参数说明:

名称 解释 类型
bSupportAnim 是否支持动画 boolean
isAnimOn 是否开启字幕动画 boolean
isDftTemplate 是否默认字幕 boolean
dftDuration 字幕默认时长 int
mTextBubbleList 字幕数据信息 {@see TextBubble} List(TextBubble)

TextBubble 参数说明:

名称 解释 类型
bSupportAnim 是否支持动画 boolean
isAnimOn 是否开启字幕动画 boolean
isDftTemplate 是否默认字幕 boolean
mDftText 默认文字 String
mTextColor 颜色,如 0xFFFFFFFF,即 ARGB int
mText 文字 String
mTextAlignment 对齐方式,在{@class TextBuble} 中定义,可以进行 ' ' 位运算合并。 int
mFontPath 字体文件路径 String
mDftTextColor 默认颜色,如 0xFFFFFFFF,即 ARGB int
mShadowInfo 字幕阴影信息 {@see ShadowInfo} ShadowInfo
mStrokeInfo 字幕描边信息 {@see StrokeInfo} StrokeInfo
isBold 是否粗体 boolean
isItalic 是否斜体 boolean

ShadowInfo 参数说明:

名称 解释 类型
enable 是否开启阴影 boolean
shadowXShift 横向阴影偏移,百分比小数值,0 表示无偏移,0~1,不可小于 0 float
shadowYShift 垂直阴影偏移,百分比小数值,0 表示无偏移,0~1,不可小于 0 float
shadowColor 阴影颜色,如 0xAA000000,即 ARGB int
shadowBlurRadius 阴影宽度,百分比小数值,0 表示无阴影,0~1,不可小于 0 float

StrokeInfo 参数说明:

名称 解释 类型
strokeWPersent 描边,百分比小数值,0 表示无描边,1 表示描边宽度和文字高度相同,不可小于 0 float
strokeColor 描边的颜色,如 0xFFFFFFFF,即 ARGB int

4. 主题剪辑功能接口

由于剪辑操作都是在线程中异步进行的,所以操作结束后,如果需要获取成功失败信息。可以向工程注册剪辑操作监听器。

  /** 注册操作符监听器 */
    mWorkSpace.addObserver(BaseObserver);

不再需要监听时,可以取消监听:

  /** 注销操作符监听器 */
    mWorkSpace.removeObserver(BaseObserver);

BaseObserver 说明:

public interface BaseObserver {

  void onChange(BaseOperate operate);
}

BaseOperate 说明:

// 是否操作成功
operate.success();

// 是否操作结束保存工程当前状态(保存为线程操作,但备份工程需要耗时,请尽量避免不必要的过多保存操作)
setNeedSavePrj(isNeedSavePrj);

1)应用/切换主题

    // themePath 表示主题素材路径
    ThemeOPApply themeOPApply = new ThemeOPApply(themePath);
    mWorkSpace.handleOperation(themeOPApply);

2)恢复主题背景音乐设置

    // 该操作将删除所以背景应用,切回主题自带的背景音乐
    ThemeOPBgmReset themeOPBgmReset = new ThemeOPBgmReset();
    mWorkSpace.handleOperation(themeOPBgmReset);

3)修改主题关联字幕文本

    // themeSubtitleEffect 表示需要修改的主题字幕,是通过工程获取到的信息 {@see ThemeSubtitleEffect}
    // text 表示修改的文本信息
    ThemeOPSubtitleText themeOPSubtitleText = new ThemeOPSubtitleText(themeSubtitleEffect, text);
    mWorkSpace.handleOperation(themeOPSubtitleText);

ThemeSubtitleEffect 参数说明:

名称 解释 类型 是否必须
mGroupType 字幕类型 GroupType 必须
mIndex 字幕在类型中的排序位置 int 必须
destRange 切入切出区间 VeRange 必须
mText 字幕文本 String 必须
effectPosInfo 字幕位置信息 EffectPosInfo 必须

5. Clip 剪辑功能接口

1)添加

    ArrayList<ClipAddItem> list;
    // clipIndex 为 clip 添加的位置,0 为第一个
    // list 需要添加的 clip 列表
    ClipOPAdd clipOPAdd = new ClipOPAdd(clipIndex, list);
    mWorkSpace.handleOperation(clipOPAdd);

ClipAddItem 参数说明:

名称 解释 类型 是否必须
clipFilePath 文件地址 String 必须
trimRange 切入点 VeRange 非必须
srcRange 源视频文件区间, 仅用于保存 VeRange 非必须
cropRect 裁切区域(万分比区域) Rect 非必须
rotateAngle 旋转角度 int 非必须
filterInfo 滤镜 FilterInfo 非必须

2)复制

    // clipIndex 表示第几个片段,从 0 开始
    ClipOPCopy clipOPCopy = new ClipOPCopy(clipIndex);
    mWorkSpace.handleOperation(clipOPCopy);

3)删除

方式一:
    // clipIndex 表示第几个片段,从 0 开始
    ClipOPDel clipOPDel = new ClipOPDel(clipIndex);
    mWorkSpace.handleOperation(clipOPDel);
方式二:
    // uniqueId 为 ClipData 中的片段唯一 id
    ClipOPDel clipOPDel = new ClipOPDel(uniqueId);
    mWorkSpace.handleOperation(clipOPDel);

4)排序

    // 将位置 clipIndex 的片段移动到 toIndex 的位置
    ClipOPMove clipOPMove = new ClipOPMove(clipIndex, toIndex);
    mWorkSpace.handleOperation(clipOPMove);

5)静音

    // clipIndex 表示第几个片段,从 0 开始
    // isMute 是否静音
    ClipOPMute clipOPMute = new ClipOPMute(clipIndex, isMute);
    mWorkSpace.handleOperation(clipOPMute);

6)音量

    // clipIndex 表示第几个片段,从 0 开始
    // volume 表示音量,100 为正常音量,200 为放大 1 倍
    ClipOPVolume clipOPVolume = new ClipOPVolume(clipIndex, volume);
    mWorkSpace.handleOperation(clipOPVolume);

7)变声

    // clipIndex 表示第几个片段,从 0 开始
    // soundTone 表示音调,从 -60~60,{@see QEDftSoundTone}类中有提供的特定音调
    ClipOPMagicSound clipOPMagicSound = new ClipOPMagicSound(clipIndex, soundTone);
    mWorkSpace.handleOperation(clipOPMagicSound);

8)镜像

    // clipIndex 表示第几个片段,从 0 开始
    // mirror 表示镜像类型 {@see ClipData.Mirror}
    ClipOPMirror clipOPMirror = new ClipOPMirror(clipIndex, mirror);
    mWorkSpace.handleOperation(clipOPMirror);

9)旋转

    // clipIndex 表示第几个片段,从 0 开始
    // rotation 旋转角度 0~359 度
    ClipOPRotate clipOPRotate = new ClipOPRotate(clipIndex, rotation);
    mWorkSpace.handleOperation(clipOPRotate);

10)分割

    // clipIndex 表示第几个片段,从 0 开始
    // splitTime 分割时间,在加入片段的相对时间(是相对 trimRange,不是相对原视频),如从片段的第 5s 分割,则 splitTime=5000
    ClipOPSplit clipOPSplit = new ClipOPSplit(clipIndex, splitTime);
    mWorkSpace.handleOperation(clipOPSplit);

11)变速

    // clipIndex 表示第几个片段,从 0 开始
    // speedValue 变速缩放值。如 0.25 表示 4 倍速。保留两位小数
    // isKeepTone 表示变速是否需要变调
    ClipOPSpeed clipOPSpeed = new ClipOPSpeed(clipIndex, speedValue, isKeepTone);
    mWorkSpace.handleOperation(clipOPSpeed);

12)倒放

    // clipIndex 表示第几个片段,从 0 开始
    // toReverse 是否倒放
    ClipOPReverse clipOPReverse = new ClipOPReverse(clipIndex, toReverse);
    mWorkSpace.handleOperation(clipOPReverse);

13)比例

    // size 比例,只需要宽高比即可
    // isRatioOriginal 是否原比例。用于添加 clip 时是否需要重新适配分辨率
    ClipOPRatio clipOPRatio = new ClipOPRatio(size, isRatioOriginal);
    mWorkSpace.handleOperation(clipOPRatio);

14)裁切

    // clipIndex 表示第几个片段,从 0 开始
    // cropRect 表示裁切区域(万分比区域)
    ClipOPCrop clipOPCrop = new ClipOPCrop(clipIndex, cropRect);
    mWorkSpace.handleOperation(clipOPCrop);

15)视频裁剪

    // clipIndex 表示第几个片段,从 0 开始
    // trimRange 裁剪区域(trimRange 需要设置为源视频的区域 * clip 的 timeScale,比如从原视频的 5~20s,则 trimRange 为 new VeRange(5*timescale, 15*timescale))
    ClipOPTrimRange clipOPTrimRange = new ClipOPTrimRange(clipIndex, trimRange);
    mWorkSpace.handleOperation(clipOPTrimRange);

16)视频源区间

    // clipIndex 表示第几个片段,从 0 开始
    // srcRange 裁剪区域(srcRange 表示从视频源文件选择的区间,目前数据只是存储)
    ClipOPSrcRange clipOPSrcRange = new ClipOPSrcRange(clipIndex, srcRange 裁剪区域);
    mWorkSpace.handleOperation(clipOPSrcRange);

17)图片时长

    // clipIndex 表示第几个片段,从 0 开始
    // duration 图片时长
    ClipOPPicTrim clipOPPicTrim = new ClipOPPicTrim(clipIndex, duration);
    mWorkSpace.handleOperation(clipOPPicTrim);

18)图片动画

    // clipIndex 表示第几个片段,从 0 开始
    // isAnimEnable 是否开启图片动画
    ClipOPPicAnim clipOPPicAnim = new ClipOPPicAnim(clipIndex, isAnimEnable);
    mWorkSpace.handleOperation(clipOPPicAnim);

19)背景

    // clipIndex 表示第几个片段,从 0 开始
    // clipBgData 背景数据 {@see ClipBgData}
    ClipOPBackground clipOPBackground = new ClipOPBackground(clipIndex, clipBgData);
    mWorkSpace.handleOperation(clipOPBackground);

ClipBgData 构造器

  /**
   * 模糊背景
   */
  public ClipBgData(int blurLen);

  /**
   * 图片背景
   */
  public ClipBgData(String imagePath, int blurLen);

  /**
   * 颜色背景
   *
   * @param colorAngle colorArray 最多支持三色。渐变色  0-1-2
   * @param colorAngle 渐变色方向。默认为水平方向,取值范围:0~360,对应的角度:0~360,单位为°
   */
  public ClipBgData(int[] colorArray, int colorAngle);

20)位置修改

  // 方式一:
    // clipIndex 表示第几个片段,从 0 开始
    // clipPosInfo 镜头位置数据 {@see ClipPosInfo}
    ClipOPPosInfo clipOPPosInfo = new ClipOPPosInfo(clipIndex, clipPosInfo);
    mWorkSpace.handleOperation(clipOPPosInfo);
  // 方式二:
    // clipIndex 表示第几个片段,从 0 开始
    // isFitOut 镜头位置是否自适应裁切(true:裁切  false:自适应。对应 imageview 的 scaleType 的 fitCenter 和 centerCrop)
    ClipOPPosInfo clipOPPosInfo = new ClipOPPosInfo(clipIndex, isFitOut);
    mWorkSpace.handleOperation(clipOPPosInfo);

21)镜头参数调节

    // clipIndex 表示第几个片段,从 0 开始
    // paramAdjust 镜头参数调节数据 {@see ParamAdjust}
    ClipOPParamAdjust clipOPParamAdjust = new ClipOPParamAdjust(clipIndex, paramAdjust);
    mWorkSpace.handleOperation(clipOPParamAdjust);

22)曲线调色调节

    // clipIndex 表示第几个片段,从 0 开始
    // colorCurveInfo 曲线调色数据 {@see ColorCurveInfo}
    ClipOPColorCurve clipOPColorCurve = new ClipOPColorCurve(clipIndex, colorCurveInfo);
    mWorkSpace.handleOperation(clipOPColorCurve);

23)修改滤镜

    // clipIndex 表示第几个片段,从 0 开始
    // filterInfo 滤镜信息,null 表示无滤镜
    ClipOPFilter clipOPFilter = new ClipOPFilter(clipIndex, filterInfo);
    mWorkSpace.handleOperation(clipOPFilter);

24)特效滤镜

    // clipIndex 表示第几个片段,从 0 开始
    // fxFilterInfo 特效滤镜信息 {@see FxFilterInfo},null 表示不使用特效滤镜
    ClipOPFxFilter clipOPFxFilter = new ClipOPFxFilter(clipIndex, fxFilterInfo);
    mWorkSpace.handleOperation(clipOPFxFilter);

25)转场

    // clipIndex 表示第几个片段,从 0 开始
    // crossInfo 转场信息 {@see CrossInfo},null 表示不使用转场
    ClipOPTrans clipOPTrans = new ClipOPTrans(clipIndex, crossInfo);
    mWorkSpace.handleOperation(clipOPTrans);

26)替换 clip

    // clipIndex 为 clip 添加的位置,0 为第一个
    // 替换的数据 clipReplaceItem;
    ClipOPReplace clipOPReplace = new ClipOPReplace(clipIndex, clipReplaceItem);
    mWorkSpace.handleOperation(clipOPReplace);

ClipReplaceItem:

名称 解释 类型 是否必须
clipFilePath 文件地址 String 必须
trimRange 切入点 VeRange 非必须
srcRange 源视频文件区间, 仅用于保存 VeRange 非必须
cropRect(万分比区域) 裁切区域 Rect 非必须

6. Effect 剪辑功能接口

1)添加

    // groupId 为 effect 的类型
    // effectIndex 为 effect 添加的位置,0 为第一个
    // effectAddItem 需要添加的 effect 信息 {@see EffectAddItem}
    EffectOPAdd effectOPAdd = new EffectOPAdd(groupId, effectIndex, effectAddItem);
    mWorkSpace.handleOperation(effectOPAdd);

EffectAddItem 参数说明:

名称 解释 类型 是否必须
mEffectPath 素材资源路径 String 必须
trimRange 效果选取的时长,可以选取某一部分,默认(0, -1) VeRange 非必须
destRange effect 在 storyboard 上的 mVeRange(起始点,时长) VeRange 非必须
effectLayerId 效果的层级信息,是一个浮点数,数字越大 层级越高 float 非必须
mEffectPosInfo 素材位置数据,基于 steamsize 的,使用的话 EffectPosInfo 有关于 surfacesize 的转化 EffectPosInfo 非必须
subtitleTexts 字幕时,可以设置字幕的文字 String 非必须

2)复制

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    EffectOPCopy effectOPCopy = new EffectOPCopy(groupId, effectIndex);
    mWorkSpace.handleOperation(effectOPCopy);

3)删除 方式一:

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    EffectOPDel effectOPDel = new EffectOPDel(groupId, effectIndex);
    mWorkSpace.handleOperation(effectOPDel);

方式二:

    // uniqueId 为 effect 的唯一 id {@see BaseEffect.uniqueId}
    EffectOPDel effectOPDel = new EffectOPDel(uniqueId);
    mWorkSpace.handleOperation(effectOPDel);

4)修改图层

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // layerId 表示图层,float 类型,各类型的图层有区间限制
    EffectOPLayerId effectOPLayerId = new EffectOPLayerId(groupId, effectIndex, layerId);
    mWorkSpace.handleOperation(effectOPLayerId);

5)裁切区间

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // trimRange 表示裁切区间
    EffectOPTrimRange effectOPTrimRange = new EffectOPTrimRange(groupId, effectIndex, trimRange);
    mWorkSpace.handleOperation(effectOPTrimRange);

6)出入区间

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // destRange 表示切入切出区间
    EffectOPDestRange effectOPDestRange = new EffectOPDestRange(groupId, effectIndex, destRange);
    mWorkSpace.handleOperation(effectOPDestRange);

7)源文件区间

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // srcRange 表示源文件区间信息
    EffectOPSrcRange effectOPSrcRange = new EffectOPSrcRange(groupId, effectIndex, srcRange);
    mWorkSpace.handleOperation(effectOPSrcRange);

8)透明度

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // alpha 表示透明度,0~100
    EffectOPAlpha effectOPAlpha = new EffectOPAlpha(groupId, effectIndex, alpha);
    mWorkSpace.handleOperation(effectOPAlpha);

9)音量

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // volume 表示音量,100 为正常音量,200 为放大 1 倍
    EffectOPVolume effectOPVolume = new EffectOPVolume(groupId, effectIndex, volume);
    mWorkSpace.handleOperation(effectOPVolume);

10)音频渐入渐出

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // audioFade 表示渐入渐出信息 {@see AudioFade}
    EffectOPAudioFade effectOPAudioFade = new EffectOPAudioFade(groupId, effectIndex, audioFade);
    mWorkSpace.handleOperation(effectOPAudioFade);

11)音频循环

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // isRepeat 表示在切入切成区域是否循环播放
    EffectOPAudioRepeat effectOPAudioRepeat = new EffectOPAudioRepeat(groupId, effectIndex, isRepeat);
    mWorkSpace.handleOperation(effectOPAudioRepeat);

12)音频变声

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // soundTone 表示音调,从 -60~60,{@see QEDftSoundTone}类中有提供的特定音调
    EffectOPAudioTone effectOPAudioTone = new EffectOPAudioTone(groupId, effectIndex, soundTone);
    mWorkSpace.handleOperation(effectOPAudioTone);

13)音频歌词字幕设置

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // audioLyric 表示引擎歌词字幕信息 {@see AudioLyric}
    EffectOPAudioLyric effectOPAudioLyric = new EffectOPAudioLyric(groupId, effectIndex, audioLyric);
    mWorkSpace.handleOperation(effectOPAudioLyric);

14)音频信息

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // message 表示音频信息,如可以保存歌手、歌名等。
    EffectOPAudioMsg effectOPAudioMsg = new EffectOPAudioMsg(groupId, effectIndex, message);
    mWorkSpace.handleOperation(effectOPAudioMsg);

15)锁定播放器刷新效果

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // isLock 表示是否锁定
    EffectOPLock effectOPLock = new EffectOPLock(groupId, effectIndex, isLock);
    mWorkSpace.handleOperation(effectOPLock);

该操作配合 EffectOPPosInfo 使用,当需要快速刷新播放器某个效果位置时,需要先锁定该效果,当位置刷新结束后,需要对改效果解锁。

16)位置信息

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // effectPosInfo 表示位置信息 {@see EffectPosInfo}
    EffectOPPosInfo effectOPPosInfo = new EffectOPPosInfo(groupId, effectIndex, effectPosInfo);
    mWorkSpace.handleOperation(effectOPPosInfo);

备注:EffectOPPosInfo 可以设置是否快速刷新,只有在操作前设置才起作用

    effectOPPosInfo.setFastRefresh(fastRefresh);

快速刷新用于快速刷新播放器,提高播放器刷新性能使用,不会保存到工程中,所以快速刷新操作结束后,需要再进行一次非快速刷新的修改,才能真实起作用。需要结合 EffectOPLock 操作使用,锁定播放器中的素材刷新。

17)镜像修改

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // mirror 表示镜像数据 {@see FloatEffect.Mirror}
    EffectOPMirror effectOPMirror = new EffectOPMirror(groupId, effectIndex, mirror);
    mWorkSpace.handleOperation(effectOPMirror);

18)画中画变速

  // 目前只支持画中画
    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // speedValue 变速缩放值。如 0.25 表示 4 倍速。保留两位小数
    EffectOPCollageSpeed effectOPCollageSpeed = new EffectOPCollageSpeed(groupId, effectIndex, speedValue);
    mWorkSpace.handleOperation(effectOPCollageSpeed);

19)画中画倒放

  // 目前只支持画中画
    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // isVideoReverse 表示是否倒放视频源
    // isAudioReverse 表示是否倒放音频源
    EffectOPCollageReserve effectOPCollageReserve = new EffectOPCollageReserve(groupId, effectIndex, isVideoReverse, isAudioReverse);
    mWorkSpace.handleOperation(effectOPCollageReserve);

20)替换音频

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // audioPath 表示音频路径
    // srcRange 表示引擎裁切区间
    EffectOPAudioReplace effectOPAudioReplace = new EffectOPAudioReplace(groupId, effectIndex, audioPath, srcRange);
    mWorkSpace.handleOperation(effectOPAudioReplace);

21)替换效果素材文件

    // groupId 为 effect 的类型
    // effectIndex 为 effect 添加的位置,0 为第一个
    // effectReplaceItem 需要替换的 effect 信息 {@see EffectReplaceItem}
    EffectOPReplace effectOPReplace = new EffectOPReplace(groupId, effectIndex, effectReplaceItem);
    mWorkSpace.handleOperation(effectOPReplace);

EffectReplaceItem 参数说明:

名称 解释 类型 是否必须
mEffectPath 素材资源路径 String 必须
trimRange null 时则不修改原来的 trimRange VeRange 非必须
destRange null 时则不修改原来的 destRange VeRange 非必须
mEffectPosInfo null 则根据原有的 effectPosInfo 进行简单的缩放处理 EffectPosInfo 非必须

22)画中画混合模式设置

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // effectOverlayInfo 表示混合模式信息 {@see EffectOverlayInfo}
    EffectOPOverlayInfo effectOPOverlayInfo = new EffectOPOverlayInfo(groupId, effectIndex, effectOverlayInfo);
    mWorkSpace.handleOperation(effectOPOverlayInfo);

23)画中画蒙版设置

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // effectMaskInfo 表示蒙版信息 {@see EffectMaskInfo}
    EffectOPMaskInfo effectOPMaskInfo = new EffectOPMaskInfo(groupId, effectIndex, effectMaskInfo);
    mWorkSpace.handleOperation(effectMaskInfo);

24)画中画抠色设置(绿幕)

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // chromaInfo 表示抠色信息 {@see EffectChromaInfo}
    EffectOPChroma effectOPChroma = new EffectOPChroma(groupId, effectIndex, chromaInfo);
    mWorkSpace.handleOperation(effectOPChroma);

25)画中画滤镜设置

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // FilterInfo 表示滤镜信息 {@see FilterInfo}
    EffectOPFilterInfo effectOPFilterInfo = new EffectOPFilterInfo(groupId, effectIndex, filterInfo);
    mWorkSpace.handleOperation(effectOPFilterInfo);

26)画中画参数调节设置

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // paramAdjust 表示参数调节信息 {@see ParamAdjust}
    EffectOPParamAdjust effectOPParamAdjust = new EffectOPParamAdjust(groupId, effectIndex, paramAdjust);
    mWorkSpace.handleOperation(effectOPParamAdjust);

27)画中画曲线调色设置

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // colorCurveInfo 表示曲线调色信息 {@see ColorCurveInfo}
    EffectOPColorCurve effectOPColorCurve = new EffectOPColorCurve(groupId, effectIndex, colorCurveInfo);
    mWorkSpace.handleOperation(effectOPColorCurve);

28)画中画添加子特效

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // subFxPath 表示特效素材路径
    // destRange 表示特效出入相对时间区间
    EffectOPSubFxAdd effectOPSubFxAdd = new EffectOPSubFxAdd(groupId, effectIndex, subFxPath, destRange);
    mWorkSpace.handleOperation(effectOPSubFxAdd);

29)画中画修改子特效出入点时间区间

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // subType 表示子特效索引{@see EffectSubFx}
    // destRange 表示特效出入相对时间区间
    EffectOPSubFxDestRange effectOPSubFxDestRange = new EffectOPSubFxDestRange(groupId, effectIndex, subType, destRange);
    mWorkSpace.handleOperation(effectOPSubFxDestRange);

30)画中画修改子特效是否关闭

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // subType 表示子特效索引{@see EffectSubFx}
    // disable 表示特效效果是否关闭
    EffectOPSubFxDisable effectOPSubFxDisable = new EffectOPSubFxDisable(groupId, effectIndex, subType, disable);
    mWorkSpace.handleOperation(effectOPSubFxDisable);

31)画中画删除子特效

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // subType 表示子特效索引{@see EffectSubFx}
    EffectOPSubFxDel effectOPSubFxDel = new EffectOPSubFxDel(groupId, effectIndex, subType);
    mWorkSpace.handleOperation(effectOPSubFxDel);

32)显示静态图片

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // showStaticPic 表示是否显示静态图片
    EffectOPStaticPic effectOPStaticPic = new EffectOPStaticPic(groupId, effectIndex, showStaticPic);
    mWorkSpace.handleOperation(effectOPStaticPic);

备注:由于一些动态贴纸/字幕,有效果变化,可以通过该操作,使效果关闭动画显示固定效果。

33)马赛克模糊程度

    // groupId 默认为 GROUP_ID_MOSAIC
    // effectIndex 为同类型中第几个效果
    // mosaicInfo 表示马赛克模糊程度 {@see MosaicInfo}
    EffectOPMosaicInfo effectOPMosaicInfo = new EffectOPMosaicInfo(effectIndex, mosaicInfo);
    mWorkSpace.handleOperation(effectOPMosaicInfo);

34)字幕动画开关

    // groupId 默认为 GROUP_ID_SUBTITLE
    // effectIndex 为同类型中第几个效果
    // animOn 表示是否开启动画
    EffectOPSubtitleAnim effectOPSubtitleAnim = new EffectOPSubtitleAnim(effectIndex, animOn);
    mWorkSpace.handleOperation(effectOPSubtitleAnim);

35)字幕文本 单字幕:

    // groupId 默认为 GROUP_ID_SUBTITLE
    // effectIndex 为同类型中第几个效果
    // text 表示字幕文本
    EffectOPSubtitleText effectOPSubtitleText = new EffectOPSubtitleText(effectIndex, text);
    mWorkSpace.handleOperation(effectOPSubtitleText);

组合字幕:

    // groupId 默认为 GROUP_ID_SUBTITLE
    // effectIndex 为同类型中第几个效果
    // textIndex 表示组合字幕中的第几个字幕
    // text 表示字幕文本
    EffectOPMultiSubtitleText effectOPMultiSubtitleText = new EffectOPMultiSubtitleText(effectIndex, textIndex, text);
    mWorkSpace.handleOperation(effectOPMultiSubtitleText);

36)字幕字体 单字幕:

    // groupId 默认为 GROUP_ID_SUBTITLE
    // effectIndex 为同类型中第几个效果
    // fontPath 表示字体文件路径
    EffectOPSubtitleFont effectOPSubtitleFont = new EffectOPSubtitleFont(effectIndex, fontPath);
    mWorkSpace.handleOperation(effectOPSubtitleFont);

组合字幕:

    // groupId 默认为 GROUP_ID_SUBTITLE
    // effectIndex 为同类型中第几个效果
    // textIndex 表示组合字幕中的第几个字幕
    // fontPath 表示字体文件路径
    EffectOPMultiSubtitleFont effectOPMultiSubtitleFont = new EffectOPMultiSubtitleFont(effectIndex, textIndex, fontPath);
    mWorkSpace.handleOperation(effectOPMultiSubtitleFont);

37)字幕文本颜色 单字幕:

    // groupId 默认为 GROUP_ID_SUBTITLE
    // effectIndex 为同类型中第几个效果
    // color 表示文本颜色,如 0xFFFFFFFF,即 ARGB
    EffectOPSubtitleColor effectOPSubtitleColor = new EffectOPSubtitleColor(effectIndex, color);
    mWorkSpace.handleOperation(effectOPSubtitleColor);

组合字幕:

    // groupId 默认为 GROUP_ID_SUBTITLE
    // effectIndex 为同类型中第几个效果
    // textIndex 表示组合字幕中的第几个字幕
    // color 表示文本颜色,如 0xFFFFFFFF,即 ARGB
    EffectOPMultiSubtitleColor effectOPMultiSubtitleColor = new EffectOPMultiSubtitleColor(effectIndex, textIndex, color);
    mWorkSpace.handleOperation(effectOPMultiSubtitleColor);

38)字幕文本对齐方式 单字幕:

    // groupId 默认为 GROUP_ID_SUBTITLE
    // effectIndex 为同类型中第几个效果
    // align 表示对齐方式 {@see TextBuble}
    EffectOPSubtitleAlign effectOPSubtitleAlign = new EffectOPSubtitleAlign(effectIndex, align);
    mWorkSpace.handleOperation(effectOPSubtitleAlign);

组合字幕:

    // groupId 默认为 GROUP_ID_SUBTITLE
    // effectIndex 为同类型中第几个效果
    // textIndex 表示组合字幕中的第几个字幕
    // align 表示对齐方式
    EffectOPMultiSubtitleAlign effectOPMultiSubtitleAlign = new EffectOPMultiSubtitleAlign(effectIndex, textIndex, align);
    mWorkSpace.handleOperation(effectOPMultiSubtitleAlign);

备注:对齐方式为下列参数,在{@class TextBuble} 中定义,可以进行 '|' 位运算合并。

  public static final int ALIGNMENT_NONE = 0;
  public static final int ALIGNMENT_FREE_STYLE = 0;
  public static final int ALIGNMENT_LEFT = 1;
  public static final int ALIGNMENT_RIGHT = 2;
  public static final int ALIGNMENT_TOP = 4;
  public static final int ALIGNMENT_BOTTOM = 8;
  public static final int ALIGNMENT_MIDDLE = 16;
  public static final int ALIGNMENT_HOR_CENTER = 32;
  public static final int ALIGNMENT_VER_CENTER = 64;
  public static final int ALIGNMENT_HOR_FULLFILL = 128;
  public static final int ALIGNMENT_VER_FULLFILL = 256;
  public static final int ALIGNMENT_UNDER_CENTER = 512;
  public static final int ALIGNMENT_ABOVE_CENTER = 1024;

39)字幕文本阴影 单字幕:

    // groupId 默认为 GROUP_ID_SUBTITLE
    // effectIndex 为同类型中第几个效果
    // shadowInfo 表示文本阴影信息 {@see ShadowInfo}
    EffectOPSubtitleShadow effectOPSubtitleShadow = new EffectOPSubtitleShadow(effectIndex, shadowInfo);
    mWorkSpace.handleOperation(effectOPSubtitleShadow);

组合字幕:

    // groupId 默认为 GROUP_ID_SUBTITLE
    // effectIndex 为同类型中第几个效果
    // textIndex 表示组合字幕中的第几个字幕
    // shadowInfo 表示文本阴影信息 {@see ShadowInfo}
    EffectOPMultiSubtitleShadow effectOPMultiSubtitleShadow = new EffectOPMultiSubtitleShadow(effectIndex, textIndex, shadowInfo);
    mWorkSpace.handleOperation(effectOPMultiSubtitleShadow);

40)字幕文本描边 单字幕:

    // groupId 默认为 GROUP_ID_SUBTITLE
    // effectIndex 为同类型中第几个效果
    // strokeInfo 表示文本描边信息 {@see StrokeInfo}
    EffectOPSubtitleStroke effectOPSubtitleStroke = new EffectOPSubtitleStroke(effectIndex, strokeInfo);
    mWorkSpace.handleOperation(effectOPSubtitleStroke);

组合字幕:

    // groupId 默认为 GROUP_ID_SUBTITLE
    // effectIndex 为同类型中第几个效果
    // textIndex 表示组合字幕中的第几个字幕
    // strokeInfo 表示文本描边信息 {@see StrokeInfo}
    EffectOPMultiSubtitleStroke effectOPMultiSubtitleStroke = new EffectOPMultiSubtitleStroke(effectIndex, textIndex, strokeInfo);
    mWorkSpace.handleOperation(effectOPMultiSubtitleStroke);

41)字幕文本粗体 单字幕:

    // groupId 默认为 GROUP_ID_SUBTITLE
    // effectIndex 为同类型中第几个效果
    // isBlod 表示是否设置粗体
    EffectOPSubtitleBlod effectOPSubtitleBlod = new EffectOPSubtitleBlod(effectIndex, isBlod);
    mWorkSpace.handleOperation(effectOPSubtitleBlod);

组合字幕:

    // groupId 默认为 GROUP_ID_SUBTITLE
    // effectIndex 为同类型中第几个效果
    // textIndex 表示组合字幕中的第几个字幕
    // isBlod 表示是否设置粗体
    EffectOPMultiSubtitleBlod effectOPMultiSubtitleBlod = new EffectOPMultiSubtitleBlod(effectIndex, textIndex, isBlod);
    mWorkSpace.handleOperation(effectOPMultiSubtitleBlod);

42)字幕文本斜体 单字幕:

    // groupId 默认为 GROUP_ID_SUBTITLE
    // effectIndex 为同类型中第几个效果
    // isItalic 表示是否设置斜体
    EffectOPSubtitleItalic effectOPSubtitleItalic = new EffectOPSubtitleItalic(effectIndex, isItalic);
    mWorkSpace.handleOperation(effectOPSubtitleItalic);

组合字幕:

    // groupId 默认为 GROUP_ID_SUBTITLE
    // effectIndex 为同类型中第几个效果
    // textIndex 表示组合字幕中的第几个字幕
    // isItalic 表示是否设置斜体
    EffectOPMultiSubtitleItalic effectOPMultiSubtitleItalic = new EffectOPMultiSubtitleItalic(effectIndex, textIndex, isItalic);
    mWorkSpace.handleOperation(effectOPMultiSubtitleItalic);

43)获取画中画抠色图片

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    EffectOPCreateChromaColor effectOPCreateChromaColor = new EffectOPCreateChromaColor(groupId, effectIndex);
    mWorkSpace.handleOperation(effectOPCreateChromaColor);

操作执行结束回调时,可以通过下面方法获取抠色图片:

ChromaColor chromaColor = effectOPCreateChromaColor.getChromaColor();

抠色图片可以获取效果特定位置的颜色值:

// relateX 和 relateY 是相对以画中画为坐标系本身偏移的位置
chromaColor.getColorByPosition(float relateX, float relateY);

注意:取的抠色图片,是取播放器当前时间,该效果的图片。所以需要保证播放器当前时间该图片是显示中,切取色只能取可见区域内的颜色。

当抠色图片不再使用时,需要释放资源:

chromaColor.recycle();

44)关键帧设置

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // effectKeyFrameInfo 表示关键帧数据,每次都需要设置完整列表 {@see EffectKeyFrameInfo}
    EffectOPKeyFrame effectOPKeyFrame = new EffectOPKeyFrame(groupId, effectIndex, effectKeyFrameInfo);
    mWorkSpace.handleOperation(effectOPKeyFrame);

45)更新某类关键帧数据列表(目前只支持位置相关关键帧,Position、AnchorOffset、Scale 和 Rotation、Alpha)

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // keyFrameType 表示关键帧类型 {@see BaseKeyFrame.KeyFrameType}
    // keyFrames 表示该类关键帧列表数据,需要设置完整列表 {@see BaseKeyFrame}
    EffectOPKeyFrameUpdate effectOPKeyFrameUpdate = new EffectOPKeyFrameUpdate(groupId, effectIndex, keyFrameType, keyFrames);
    mWorkSpace.handleOperation(effectOPKeyFrameUpdate);

46)插入单个关键帧(相同时间存在则替换,目前只支持位置相关关键帧,Position、AnchorOffset、Scale 和 Rotation)

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // baseKeyFrame 表示单个关键帧数据 {@see BaseKeyFrame}
    EffectOPKeyFrameInsert effectOPKeyFrameInsert = new EffectOPKeyFrameInsert(groupId, effectIndex, baseKeyFrame);
    mWorkSpace.handleOperation(effectOPKeyFrameInsert);

47)删除某个时间的关键帧(目前只支持位置相关关键帧,Position、AnchorOffset、Scale 和 Rotation)

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // keyFrameType 表示关键帧类型 {@see BaseKeyFrame.KeyFrameType}
    // offsetTime 表示关键帧相对时间 ts
    EffectOPKeyFrameRemove effectOPKeyFrameRemove = new EffectOPKeyFrameRemove(groupId, effectIndex, keyFrameType, offsetTime);
    mWorkSpace.handleOperation(effectOPKeyFrameRemove);

48)修改关键帧的偏移量(目前只支持位置相关关键帧,Position、AnchorOffset、Scale 和 Rotation)

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // keyFrameType 表示关键帧类型 {@see BaseKeyFrame.KeyFrameType}
    // offsetValue 表示关键帧值的偏移量 {@see Ve3DDataF}
    EffectOPKeyFrameUpdateOffset effectOPKeyFrameUpdateOffset = new EffectOPKeyFrameUpdateOffset(groupId, effectIndex, keyFrameType, offsetValue);
    mWorkSpace.handleOperation(effectOPKeyFrameUpdateOffset);

49)修改全部关键帧的偏移量(目前只支持位置相关关键帧,Position、AnchorOffset、Scale 和 Rotation)

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // posOffsetValue 表示位置关键帧值的偏移量,null 表示不修改 {@see Ve3DDataF}
    // rotateOffsetValue 表示角度关键帧值的偏移量,null 表示不修改 {@see Ve3DDataF}
    // scaleOffsetValue 表示缩放关键帧值的偏移量,null 表示不修改 {@see Ve3DDataF}
    // anchorOffsetValue 表示锚点关键帧值的偏移量,null 表示不修改 {@see Ve3DDataF}
    EffectOPKeyFrameUpdateOffsetAll effectOPKeyFrameUpdateOffsetAll = new EffectOPKeyFrameUpdateOffsetAll(groupId, effectIndex, posOffsetValue, rotateOffsetValue, scaleOffsetValue, anchorOffsetValue);
    mWorkSpace.handleOperation(effectOPKeyFrameUpdateOffsetAll);

50)修改蒙版关键帧数据

    // groupId 为 effect 的类型
    // effectIndex 为同类型中第几个效果
    // maskKeyFrameInfo 表示蒙版关键帧数据,null 表示清除关键帧 {@see MaskKeyFrameInfo}
    EffectOPMaskKeyFrame effectOPMaskKeyFrame = new EffectOPMaskKeyFrame(groupId, effectIndex, maskKeyFrameInfo);
    mWorkSpace.handleOperation(effectOPMaskKeyFrame);

7. 工程保存功能接口

    // 用于保存工程当前状态
    BaseOPSavePrj baseOPSavePrj = new BaseOPSavePrj();
    mWorkSpace.handleOperation(baseOPSavePrj);

8. 导出

  /**
   * 开始导出
   *
   * @return 导出控制器, 用于停止导出
   */
  IExportController controller = workSpace.startExport(ExportParams params, IExportListener listener);

ExportParams 参数说明:

名称 解释 类型
outputPath 导出文件路径,需要带后缀,提取音频则只支持 m4a(android 10 以上请使用有完整读写权限的私有目录绝对路径或 content 的 uri 路径) String
expType 导出分辨率类型 int
isGif 是否导出 Gif 图片 boolean
isSoftwareCodec 是否软件编解码,默认使用硬件 boolean
videoBitrateScales 视频比特率浮动 参数,默认不变,设置了 customBitrate 后,就只使用 customBitrate float
customBitrate 自定义比特率, <=0 表示非自定义 int
customFps 自定义帧率, <=0 表示非自定义, sdk 将根据自己的算法设定 fps int
isFullKeyFrame 是否纯 i 帧,只支持转码时使用 boolean
exportRange 导出时间区域 VeRange
customLimitSize 自定义的导出分辨率限制,使用自定义的话,expType 就不重要了,只会判断是否 gif VeMSize

IExportController 导出控制器说明:

public interface IExportController {
  /** 切换后台导出,降低导出时的 cpu 使用率,导出时间将拉长,存在失败风险 */
  int change2Back();

  /** 切换前台导出,恢复导出时的 cpu 使用率 */
  int change2Fore();

  /** 取消 */
  int cancel();
}

IExportListener 导出回调监听

public interface IExportListener {

  /** 导出准备就绪 */
  void onExportReady();

  /** 导出中 */
  void onExportRunning(int percent);

  /** 导出成功,exportPath 导出视频路径 */
  void onExportSuccess(String exportPath);

  /** 导出取消 */
  void onExportCancel();

  /** 导出失败 */
  void onExportFailed(int nErrCode, String errMsg);

  /** 导出资源已释放,取消、失败、成功后都会释放 */
  void onProducerReleased();
}

9. 高级玩法-剪辑操作拓展功能

由于各开发者对剪辑玩法关联的期望不同,为了支持开发者在玩法上的创意想法,剪辑操作允许开发者进行自定义组合。 如:开发者期望对 Clip 倒放后立刻对 Clip 进行静音。则开发者可以自定义操作符:

public class ClipOPReverseMute extends BaseOperate {

  private int clipIndex;

  public ClipOPReverseMute(int clipIndex) {
    this.clipIndex = clipIndex;
  }

  @Override protected boolean operateRun(IEngine engine) {
    // 编辑倒放
    ClipOPReverse clipOPReverse = new ClipOPReverse(clipIndex, true);
    clipOPReverse.operate(engine);
    // 编辑静音
    ClipOPMute clipOPMute = new ClipOPMute(clipIndex, true);
    clipOPMute.operate(engine);
    // 返回最终的成功/失败
    return true;
  }
}

然后再需要时执行操作 ClipOPReverseMute 即可

ClipOPReverseMute clipOPReverseMute = new ClipOPReverseMute(clipIndex);
workspace.handleOperation(clipOPReverseMute);

10. 高级玩法-对撤销/重做的支持(此功能开发中,如遇问题,可以联系我们)

当开发者想进行一些撤销/重做的玩法时,可以在进行剪辑操作前,对需要支持撤销的剪辑设置是否支持 undo。即:

    // 设置支持 undo
    baseOperate.setSupportUndo(true);

设置后,workspace 将对当前操作前的状态,记录一个状态点。(注:目前最多支持 30 个 undo/redo 的记录点)

当需要返回上一个记录点时,执行撤销:

    // 执行撤销
    workspace.undo();

当需要取消撤销动作时时,可以返回上一次执行撤销前的状态。执行重做:

    // 执行重做
    workspace.redo();

由于撤销/重做都有数量,所以可以通过注册监听器的方式,获取 undo/redo 的数量回调。

    workspace.setDequeCountListener(IDequeCountListener);

IDequeCountListener 说明:

public interface IDequeCountListener {
  // undoSize 为数量变化时的目前可以支持的 undo()操作数量
  // redoSize 为数量变化时的目前可以支持的 redo()操作数量
  void onDequeCountChange(int undoSize, int redoSize);
}

执行 Undo/Redo 时,对通知出去的 Operate 将会进行包装。Undo 通知的为 UndoOperate,Redo 通知的为 RedoOperate。获取源操作符的方式为:

UndoOperate.getSrcOperate();

RedoOperate.getSrcOperate();

BaseOperate 中关于 Undo/Redo 的信息:

// 是否处理过 undo
operate.isUndoHandled();
// 是否处理 undo
operate.isDoingUndo();
// 获取操作类型
BaseOperate.EngineWorkType type = operate.getOperateType();

BaseOperate.EngineWorkType 参数说明:

名称 解释
normal 正常
undo 撤销
redo 重做

11. 高级玩法-自由黑帧模式

当初始化时设置 isUseStuffClip 为 true 时,即开启自由黑帧模式。自由黑帧模式和普通剪辑模式的主要区别,即在对效果出入区间的限制上。

普通剪辑模式

如果片段 clip 的播放效果总时长在 60s,而贴纸效果的出入区间是在 55s~70s。则导出时,视频总长度只会是 60s,贴纸时间为 55s~60s,60s 以后的内容将自动截断。 普通剪辑模式下,导出视频的总长度,由片段的最终时长决定。

自有黑帧模式

如果片段 clip 的播放效果总时长在 60s,而贴纸效果的出入区间是在 55s~70s。则导出时,视频总长度将会是 70s,贴纸时间为 55s~70s,60s 以后的片段内容将是黑帧画面,但是不影响贴纸的内容展示。 自有黑帧模式下,导出视频的总长度,由效果和片段的最终时长共同决定。

七、卡点视频工程功能开发接入

1. 卡点视频工程

创建和加载
  /**
   * 创建新的卡点视频工程
   */
  QEEngineClient.createNewSlideProject(long themeId, List<String> nodePathList, QESlideWorkSpaceListener listener);

  /**
   * 加载卡点视频工程
   */
  QEEngineClient.loadSlideProject(String projectPath, QESlideWorkSpaceListener listener);
工程删除

【详情请参看剪辑工程工程删除相关。】

2. 播放器

【详情请参看剪辑工程播放器相关。】

3. 获取片段节点信息

ArrayList<SlideInfo> slideInfos = workspace.getSlideInfoList();

SlideInfo 参数说明:

名称 解释 类型
filePath 片段文件路径 String
sourceType 文件类型{@see Type} SlideInfo.Type
index 索引 int
duration 片段时长 int
previewPos 预览位置 int
mSlidePosInfo 位置信息{@see SlidePosInfo} SlidePosInfo

SlideInfo.Type 参数说明:

名称 解释
Image 图片
Video 视频

SlidePosInfo 参数说明:

名称 解释 类型
mAngle 旋转角度(0~360) int
width 宽,相对于 streamsize float
height 高,相对于 streamsize float
centerX 中心点 x,相对于 streamsize float
centerY 中心点 y,相对于 streamsize float

4. 卡点视频剪辑功能接口

1)排序

    // 将 from 位置的片段移动到 to 位置
    SlideOPMove slideOPMove = new SlideOPMove(from, to);
    mWorkSpace.handleOperation(slideOPMove);

2)替换

    // clipIndex 表示第几个片段,从 0 开始
    // filePath 表示视频/图片路径
    SlideOPReplace slideOPReplace = new SlideOPReplace(clipIndex, filePath);
    mWorkSpace.handleOperation(slideOPReplace);

3)修改片段位置

    // clipIndex 表示第几个片段,从 0 开始
    // slidePosInfo 表示位置信息
    SlideOPPosition slideOPPosition = new SlideOPPosition(clipIndex, slidePosInfo);
    mWorkSpace.handleOperation(slideOPPosition);

5. 导出

【详情请参看剪辑工程导出相关。】

八、 缩略图获取

1. 工程相关缩略图获取
  /**
   * 获取工程封面
   */
  Bitmap bitmap = wrokspace.getProjectThumbnail();

  /**
   * 获取工程封面
   */
  Bitmap bitmap = wrokspace.getProjectThumbnail(int offset);

  /**
   * engine 接口 createThumbnailManager,需要配对调用 destroyThumbnailManager;
   * 否则容易造成内存泄漏;
   */
  Bitmap bitmap = wrokspace.getClipThumbnail(int index, int width, int height);

  /**
   * engine 接口 createThumbnailManager,需要配对调用 destroyThumbnailManager;
   * 否则容易造成内存泄漏;
   */
  Bitmap bitmap = wrokspace.getClipThumbnail(int index, int offset, int width, int height);
2.素材缩略图获取

工具:QEThumbnailTools


  /**
   * 获取图片文件的缩略图(jpeg/png/gif 等)
   *
   * @param offset gif 时,可以取某个时间点的缩略图
   */
  Bitmap bitmap = QEThumbnailTools.getPicFileThumbnail(String filePath, int width, int height, int offset);

  /**
   * 获取视频文件缩略图
   */
  Bitmap bitmap = QEThumbnailTools.getVideoThumbnail(String filePath, int width, int height, int offset);

九、 工具类 QETools

  /**
   * 视频倒放
   *
   * @param reverseSrcFile 原始文件全路径。
   */
  IExportController controller = QETools.reverseFile(final String reverseSrcFile, ExportParams params, IExportListener listener);

  /**
   * 将外部文件导出成适合添加到我们工程的文件(转码 TRANSCODE etc...)。 MPEG4 编码
   * 转码
   */
  IExportController controller = QETools.convertVideo(String srcPath, ExportParams params, IExportListener listener);

  /**
   * 提取音频
   */
  IExportController controller = QETools.directAudio(String srcPath, ExportParams params, IExportListener listener);

  /**
   * 通过引擎解析音频波形数据,数据是一段一段解析回调出来
   * 由于数据量比较大(32k 左右),app 采用 1s 40 帧的筛选
   * 目前是去两极,value [0,1]
   * 取的左声道
   *
   */
  int iRes = QETools.extractAudioWave(String audioPath, VeRange srcRange, IAudioDataListener audioDataListener);
Apps
About Me
GitHub: Trinea
Facebook: Dev Tools