Android视频编辑SDK--RDVECore来自锐动的无UI,高度抽象化API

RDVECore功能概述

RDVECore是锐动推出的无UI,高度抽象化API的视频编辑SDK,支持以下功能:

1.1 丰富的编辑功能

RDVECore包含了丰富的基础功能,对于编辑中的视频、图片、音乐有各种处理方式,并且可以根据实际的业务需求,进行搭配组合,所有处理都可以精确到毫秒级,达到最专业的的要求,主要功能如下:

MV MV根据配置资源进行混合以及动画,增强短视频效果

滤镜 RDVEUISdk本身提供丰富的滤镜效果让开发者进行选择,同时用户还可以根据自己的需求进行滤镜扩展。

字幕特效 字幕特效支持在指定位置,指定时间段显示;实时预览效果

配音、配乐 支持指定时间段添加配音; 支持配音、配乐与视频原音比例调节; 支持本地添加更多配乐

截取、分割 支持毫秒级截取、分割视频; 支持快速预览截取、分割后视频

调速 调整视频的播放速度,快放或者慢放

转场 支持多种转场; 支持随机转场、指定转场时长等扩展设置

其它编辑功能 支持多种比例裁剪; 支持90、180、270度旋转视频画面;支持左右镜像、上下镜像;支持输出比例调整;

完善的视频拍摄功能

实时美颜 可以在拍摄过程中实时人脸美肤,提亮、美白等效果,达到人脸美化,同时支持美化程度的调节

人脸贴纸/挂件 支持人脸识别及贴纸/挂件显示

拍摄自由定义 RDVECore在拍摄过程中,可以根据具体的录制需求,进行自由化的设定,拥有更佳优异的拍摄录制效果。

多段拍摄 一个视频可以分多段次拍摄

摄像头切换 前、后摄像头自由切换,中间无卡顿

多比例支持 支持1:1 、9:16、16:9多个比例录制

变焦、对焦 通过相应手势可以缩放摄像头采集画面及清晰度(依赖硬件支持)

滤镜 在拍摄过程中,除了实时美颜,同时还可以实时添加滤镜效果,RDVEUISdk本身提供丰富的滤镜效果让开发者进行选择,同时用户还可以根据自己的需求进行滤镜扩展。

照片 当前摄像头画面保存到图片

RDVECore架构图:

RDVECore简要流程图:

2 集成步骤

2.1 运行环境

Android 4.3(api 18)以上;

处理器:双核1GHz以上CPU(目前只支持ARM CPU, X86、MIPS暂不支持);

推荐四核1.2GHz以上CPU

内存:1 GB以上;

2.2 注册申请AppKey和APPSECRET

1、登录http://www.rdsdk.com注册用户

2、 登录注册好的用户3、 进入视频云管理点击(新增)获取应用的appkey 、appsecret

2.3 下载并导入SDK

2.3.1 Android Studio导入rdVECore模块

点击File--->Import Module,选择路径,填写“Module name”,默认为rdVECore,点击“finish”


关于集成NDK SO库引发冲突解决办法如下:

步骤一:sdk library模块过滤

步骤二:application模块中过滤

编辑SDKNDK包含以下架构的SO库:

[if !supportLists]·[endif]armeabi-v7a

建议在Module的build.gradle文件中使用NDK的“abiFilter”配置,设置支持的SO库架构。

如果在添加“abiFilter”之后Android Studio出现以下提示:

NDK integration is deprecated in the current plugin. Consider trying the new experimental plugin.

则在项目根目录的gradle.properties文件中添加:

android.useDeprecatedNdk=true

在集成NDKSO库时,请注意只保留支持的架构SO库,参考截图配置

关于gradle插件

gradle插件请使用版本2.3.x

可参考demo中使用的版本

[if !supportLists]2.3.2[endif]准备AndroidManifest.xml  (权限)

添加权限:

[if !supportLists]2.3.3[endif]调用初始化API

RdVECore.initialize(context, rootPath, appKey, appSecret, debuggable);

Parameters:

context应用上下文

rootPath自定义的工作目录

appkey在平台申请的Appkey

appScrect在平台申请的appScrect

debuggable是否调试

[if !supportLists]2.4[endif]录制视频

[if !supportLists]2.4.1[endif]录制初始化参数

//画面打开之前配置录制参数(可包含摄像头、输出尺寸、帧码率、是否美颜等)

//通过此方法设置摄像头方向、是否美颜只在onPrepare(RelativeLayout,listener)之前调用有效

//初始化之后设置前后置方向使用

RecorderCore.switchCamera()、RecorderCore.enableBeautify(bEnableBeautify)

RecorderConfig config = new RecorderConfig()

.setVideoSize(width, height)//设置录制视频输出宽高.setVideoFrameRate(frameRate)//设置录制视频帧率

.setVideoBitrate(bitrate)//设置录制视频码率

.setEnableFront(isFrontCamera)//设置录制视频码率.setEnableBeautify(canBeautiy)//设置是否启用美颜

.setBeauitifyLevel(level)//设置美颜级别

.setEnableFrontMirror(enableFrontMirror)//设置录制时是否镜像.setEnableAutoFocus(true)//设置是否自动对焦

.setEnableAutoFocusRecording(false)//设置录制时是否自动对焦

//设置音频编码参数{numChannels - 声音数sampleRate - 采样率bitRate - 码率(bps)}

.setAudioEncodingParameters(numChannels, sampleRate, bitRate);

RecorderCore.setEncoderConfig(config);//设置配置

[if !supportLists]2.4.2[endif]初始化录制界面

/**

* 准备录制

*

*@paramparentLayout

*            用于显示摄像头的父布局

*@paramlistener

*录制回调消息Listener

*/

RecorderCore.onPrepare(parentLayout,IRecorderCallBackShotlistener);

一般用在Activity.onStart()中

[if !supportLists]2.4.3[endif]关于录制结束时的释放清理操作

用于响应Activity.onDestroy()

RecorderCore.onExit(this);

[if !supportLists]2.4.4[endif]录制

//开始录制

RecorderCore.startRecord(localSaveMp4File);

//结束录制

RecorderCore.stopRecord();

//是否正在录制...

RecorderCore.isRecording();

[if !supportLists]2.4.5[endif]关于回调接口

/*

*打开摄像头成功并且开始预览界面

* @paramresult

*返回值>={@link ResultConstants#SUCCESS}代表成功,否则为失败

* @paramresultInfo

*具体返回消息

*/

IRecorderCallBackShot.onPrepared(intresult, StringresultInfo);

/*

*响应录制开始

* @paramresult

*返回值>={@link ResultConstants#SUCCESS}代表成功,否则为失败

* @paramresultInfo

*具体返回消息

*/

IRecorderCallBackShot.onRecordBegin(intresult, StringresultInfo);

/*

* 响应获取已录制信息

*@paramposition 已录制时间 (ms)

*@paramrecordFPS录制帧率

*@paramdelayed延迟时间

*/

IRecorderCallBackShot.onGetRecordStatus(intposition, intrecordFPS, int delayed);

/**

* 响应直播结束

*@paramresult

*            返回值 >={@link ResultConstants#SUCCESS}代表成功,否则为失败

*@paramresultInfo

*/

IRecorderCallBackShot.onRecordEnd(intresult, StringresultInfo);

/**

* 录制出现错误

*@paramresult

*            返回值

*@paramresultInfo

*            具体返回消息

*/

IRecorderCallBackShot.onRecordFailed(intresult, StringresultInfo);

/**

* 响应摄像头打开信息

*@paramnResult

*            返回值 >={@link ResultConstants#SUCCESS}代表成功,否则为失败

*@paramstrResultInfo

*            具体返回消息

*/

IRecorderCallBackShot.onCamera(intresult, StringresultInfo);

/***保存当前画面回调* @param nResult =ResultConstants.SUCCESS* @parampicturePath图片本地路径*/

IRecorderCallBackShot.onScreenShot(int result,String picturePath);

[if !supportLists]2.4.6[endif]摄像头相关(必须在onprepare回调之后才有效)

//聚焦

RecorderCore.cameraAutoFocus();

//是否为前摄像像头

RecorderCore.isFaceFront();

//切换摄像头

RecorderCore.switchCamera();

[if !supportLists]2.4.7[endif]闪光灯(必须在onprepare回调之后才有效)

//获取闪光灯状态

RecorderCore.getFlashMode();

//打开闪光灯

RecorderCore.setFlashMode(boolean enable);

[if !supportLists]2.4.8[endif]美颜

//是否支持美颜

RecorderCore.isBeautifyEnabled();

//打开或关闭美颜RecorderCore.enableBeautify(booleanenableBeautify);

[if !supportLists]2.4.9[endif]截图(必须在listener.onPrepared回调之后才有效)

/**

*当前画面截图

* @param isFocus是否聚焦

* @param path截图文件路径

* @param width截图宽度

* @param height截图高度

*/

RecorderCore.screenshot(isFocus,path, 360, 640, 50);

/**

*响应保存截图

* @param nResult

*返回值=={@link ResultConstants#SUCCESS}代表成功,否则为失败

* @param msg

*

*/

IRecorderCallBackShot.onScreenShot(int nResult, String path);

[if !supportLists]2.4.10[endif]静音

RecorderCore.setMute(isMute);

[if !supportLists]2.4.11[endif]滤镜

//获取支持的滤镜 在listener.onprepared()回调成功之后才能获取支持的滤镜

effects = RecorderCore.getSupportedColorEffects();

//设置滤镜

RecorderCore.setColorEffect(color);

[if !supportLists]2.4.12[endif]水印相关

//判断水印是否注册

RecorderCore.isOsded();

//开启水印

RecorderCore.registerOSD(osd);

//关闭水印

RecorderCore.registerOSD(null);

public class CameraWatermarkBuilder extends VEOSDBuilder{

//设置水印位置

setOSDGravity(int nGravity);

//刷新水印内容

protected void onRefreshOSDView(View vOSD) {}

}

[if !supportLists]2.4.13[endif]水印相关横竖屏录制

说明:输出视频的录制方向,内部通过获取屏幕方向得到

//开始直播录制

第一步:锁定屏幕当前的方向(固定输出方向)

第二步:录制前通过设置屏幕方向的旋转角度(获取当前屏幕的方向0、90、180、270 )辨别是否横屏录制。

RecorderCore.setOrientation(nOrientation);

[if !supportLists]2.4.14[endif]混音播放器

(只支持播放本地音乐,支持的音频格式mp3、mp2、aac、wma、wmv、ac3、ogg)

此播放器支持混音功能.场景:插上耳机,传输一路音频流到看直播端

player.setOnPreparedListener(listener);

player.setOnInfoListener(infolistener);

player.setOnCompletionListener(completlistener);

player.setOnErrorListener(onErrorListener);

player.prepareAsync();

[if !supportLists]2.4.15[endif]是否开启混音功能

//设置是否开启混音

RecorderCore.enableMixAudio(enable);

//获取当前是否开启混音

RecorderCore.isEnableMixAudio();

[if !supportLists]2.4.16[endif]设置混音占比

//设置混音占比0-100

RecorderCore.setMixFactor(factor);

//获取当前混音占比

RecorderCore.getMixFactor();

[if !supportLists]2.5[endif]编辑视频

[if !supportLists]2.5.1[endif]添加播放器

布局里面添加播放器

代码里面用

@BindView(R2.id.epv_player)VirtualVideoView mVideoPlayer;

或者

VirtualVideoView mVideoPlayer;

mVideoPlayer = (VirtualVideoView) findViewById(R.id.epv_player);

获取mVideoPlayer播放器对象

[if !supportLists]2.5.2[endif]构造虚拟视频并添加到播放器

//构造虚拟视频

VirtualVideo mVirtualVideo

mVirtualVideo = new VirtualVideo();

//构造一个场景

Scene scene = VirtualVideo.createScene();

//给场景添加媒体(传媒体路径)并返回媒体对象

MediaObject mediaObject = scene.addMedia(mediaPath);

//将场景添加到虚拟视频

mVirtualVideo.addScene(scene);

//将虚拟视频添加到播放器

try {mVirtualVideo.build(mVideoPlayer);} catch (InvalidStateException e) {}

[if !supportLists]2.5.3[endif]获取视频缩略图

方式1:虚拟视频对象获取缩略图

虚拟视频添加场景后调用build(Context context)函数加载所有媒体,

如:

try {mVirtualVideo.build(mContext);} catch (InvalidStateException e) {e.printStackTrace();}

再调用boolean getSnapShot(float timeSecond,Bitmap snapshot)即可获取对应时间点的缩略图

其中参数timeSecond为缩略图时间点(单位秒),snapshot为获取缩略图的Bitmap对象

返回值为true表示获取成功,false为失败

如:

mVirtualVideo.getSnapshot(1, bitmap);

获取1秒位置的缩略图,并把图片绘入bitmap中

方式2:通过文件获取缩略图

VirtualVideo.getSnapShot(

String mediaPath,//媒体地址

float timeSecond,//缩略图时间点(单位秒)

Bitmap snapShot,//位图对象

boolean isFastSeek)//是否为快速定位

[if !supportLists]2.5.4[endif]添加滤镜特效

//在虚拟视频对象添加滤镜特效

mVirtualVideo.addEffect(

EffectType,//特效类型

startTime,//开始位置(单位秒)

endTime,//结束位置(单位秒)

arg);//其他参数(例如倒序需要传一个倒序视频路径)

//添加完成后更新特效

mVirtualVideo.updateEffects(videoView);

[if !supportLists]2.5.5[endif]添加音乐

//在虚拟视频添加音乐

方式一:

/***添加音乐资源** @param musicPath音乐路径* @param trimStart音乐截取开始位置(单位秒)* @param trimEnd音乐截取结束位置(单位秒)* @param timelineStart音乐在主时间线的开始位置(单位秒)* @param timelineEnd音乐在主时间线的结束位置(单位秒)* @param mixFactor音量占用比例(正常范围0-100,超过100代表音量增益,过大会破音,比如设置20代表原音量的20%,500则为原音量增益5倍)* @param speed音乐速度* @param original是否为原音* @return* @throws InvalidArgumentException*/public VirtualVideo addMusic(String musicPath, float trimStart, float trimEnd, float timelineStart, float timelineEnd, int mixFactor, float speed, boolean original) throws InvalidArgumentException

//清除音乐

mVirtualVideo.clearMusic();

//造作完成后刷新音乐

mVirtualVideo.updateMusic(videoView);

//设置配乐音量占用比例(音量占用比例(正常范围0-100,超过100代表音量增益,过大会破音,比如设置20代表原音量的20%,500则为原音量增益5倍,实时更改,不用调updateMusic)

mVirtualVideo.setMusicMixFactor(musicMixFactor);

[if !supportLists]2.5.6[endif]添加水印

/***添加水印** @param watermark水印对象*/public VirtualVideo addWatermark(Watermark watermark)

其中Watermark对象

//创建一个水印对象

Watermark watermark = new Watermark();

//设置水平路径(图片路径)watermark.setPath(watermarkPath);

//设置水印显示区域(RectF其中上下左右用0-1)watermark.setShowRect(watermarkShowRectF);

//设置开始时间(单位秒)watermark.setStartTime(startTIme);

//设置结束时间 (单位秒)watermark.setEndTime(endTime);

[if !supportLists]2.5.7[endif]视频倒序

/***视频倒序** @param context上下文* @param mediaObject媒体对象* @param reverseVideoPath倒序保存路径* @param vc配置类* @param listener倒序回调*/public static void ExportUtils.reverseSave(Context context, MediaObject mediaObject, String

reverseVideoPath, VideoConfig vc, final ExportListener listener)

/***快速倒序(原视频必须每帧都为关键帧)** @param context上下文* @param mediaObject媒体对象* @param reverseVideoPath倒序保存路径* @param listener倒序回调*/public static void ExportUtils.fastReverseSave(Context context,MediaObject mediaObject, String

reverseVideoPath, final ExportListener listener)

[if !supportLists]2.5.8[endif]MV

第一步:注册MV,得到MVId

MVInfo temp = RdVECore.registerMV(localPath);

第二步:设置MV

if (null != mMVFragment) {mVirtualVideo.setMV(mMVFragment.getCurrentMVId());}

//是否移除MV中的声音(切换配乐时可以移除声音,防止两种声音吵杂)mVirtualVideo.removeMVMusic(bRemoveMVMusic);

[if !supportLists]2.5.9[endif]完成编辑导出视频

/***导出视频* @param context上下文* @param filePath保存路径* @param videoConfig导出配置* @param listener导出回调*/public VirtualVideo export(Context context, String filePath, VideoConfig videoConfig,

ExportListener listener)

其中ExportListener为导出Listenerpublic interface ExportListener {/***导出开始回调*/void onExportStart();/***导出进度回调** @param progress当前进度* @param max最大进度* @return返回是否继续执行,false为终止导出*/boolean onExporting(int progress, int max);/***导出结束回调** @param result结束返回int值*/void onExportEnd(int result);}

导出配置VideoConfig说明如下:

/**

*设置视频分辨率

*如果设置此项,则宽高比将无效

*

* @param width视频宽度

* @param height视频高度

*/

public VideoConfig setVideoSize(int width, int height)

/**

*设置视频帧率

*

* @param frameRate帧率

*/

public VideoConfig setVideoFrameRate(int frameRate)

/**

*设置码率

*

* @param bitRate码率(bps)

*/

public VideoConfig setVideoEncodingBitRate(int bitRate)

/**

*设置关键帧间隔

*

* @param interval关键帧间隔(秒为单位)

*/

public VideoConfig setKeyFrameTime(int interval)

/**

*设置音频编码参数

*

* @param numChannels声音数

* @param sampleRate采样率

* @param bitRate码率(bps)

*/

public void setAudioEncodingParameters(int numChannels, int sampleRate, int bitRate)

/**

*设置输出文件是否需要针对网络优化

*

* @param optimizeForNet输出文件是否需要针对网络优化

*/

public VideoConfig setOptimizeForNet(boolean optimizeForNet)

/**

*设置是否使用硬件编码

*

* @param enable为ture使用硬件编码

*/

public VideoConfig enableHWEncoder(boolean enable)

/**

*设置是否使用硬件解码

*

* @param enable为ture使用硬件解码

*/

public VideoConfig enableHWDecoder(boolean enable)

/*** 设置音频编码参数**@paramnumChannels声音数*@paramsampleRate采样率*@parambitRate码率(bps)*/public voidsetAudioEncodingParameters(intnumChannels,intsampleRate,intbitRate)

[if !supportLists]2.6[endif]打包混淆

需要在proguard.cfg文件中添加如下配置项:

-dontwarn  com.rd.**

-keep class com.rd.** { *; }

#水印

-keepclassmembers class * extends com.rd.recorder.OSDBuilder{  * ;}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容