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