Skip to content

v3.x_Video_Filter

chriszeng87 edited this page May 25, 2017 · 2 revisions

v3.x自定义滤镜方式

推流SDK当前自定义GPU滤镜,即使用OpenGl方式添加App自己的视频滤镜。
v3.x仅支持硬编模式下的自定义视频滤镜,为开发者提供基类KSYImageFilter
滤镜会在预览和推流端都生效
具体步骤如下:

  1. 继承KSYImageFilter创建自己的类,例如DEMOFILTER
  2. 调用KSYStreamer的接口setBeautyFilter将自己的Filter设置给SDK

例如:

 mStreamer.setBeautyFilter(new KSYImageFilter());

这个接口有几种重载,具体如下: 另外,对于硬编可以选择分别指定编码和预览的滤镜实例,或者让SDK通过反射使用无参构造方法自己构造。

/**
使用内置滤镜,int为内置美颜种类可以设置为FILTER_BEAUTY_DISABLE(不使用美颜)、FILTER_BEAUTY_DENOISE、FILTER_BEAUTY、FILTER_SKINWHITEN、FILTER_BEAUTY_PLUS或FILTER_BEAUTY_PLUS,其中软编只可以设置为FILTER_BEAUTY_DISABLE(不使用美颜)和FILTER_BEAUTY_DENOISE。
**/
 void setBeautyFilter(int beautyFilter);
//编码和预览使用SDK通过反射使用无参构造方法自己构造的滤镜实例。
 void setBeautyFilter(KSYImageFilter filter);
/**
分别指定编码和预览的滤镜实例,SDK将不会使用反射重新构造。(!)注意对于硬编码,使用此方法需要分别传入编码和预览的滤镜实例,usage为RecorderConstants::FILTER_USAGE_PREVIEW,FILTER_USAGE_ENCODE ;
**/
 void setBeautyFilter(KSYImageFilter filter, int usage);

KSYImageFilter为分离出来用于OpenGL绘制的框架,主要方便您实现自定义Vertex和Fragment Shader的滤镜,下面为主要方法和变量说明。
注意:自定义的滤镜必须有public的无参构造器,并且调用KSYImageFilter(String vertexShader, String fragmentShader) 进行初始化

//构造方法,此处需要传入顶点和片元着色器
public KSYImageFilter(String vertexShader, String fragmentShader) ;

//注意:默认必须有public的无参构造器,必须在无参构造器里显式的调用上面的构造方法,初始化着色器
public KSYImageFilter() {
       super(vertexShader,fragmentShader);
}

//默认的顶点着色器
protected static final String NO_FILTER_VERTEX_SHADER ;

//默认的片元着色器
protected static final String NO_FILTER_FRAGMENT_SHADER ;

//输入纹理宽度
protected int mTexWidth;

//输入纹理高度
protected int mTexHeight;

//是否完成初始化
protected boolean mIsInitialized;

//编译VertextShader和FragmentShader之前回调
public void onInit() ;

//编译VertextShader和FragmentShader之后,回调
public void onInitialized();

//销毁滤镜,主要用来清理texture和GLProgram,释放资源
public final void destroy() ;

//glDrawArrays之前调用
protected void onDrawArraysAfter() ;

//glDrawArrays之后调用
protected void onDrawArraysPre() ;

//获得uniform在shader中的位置指针
protected int getUniformLocation(java.lang.String) ;

//设置Uniform变量,location为uniform在shader中的位置指针
protected void set* (int location , ...) ;

添加runable会在onDraw时候的GLUSEPROGRAM之后调用protected void runOnDraw(final Runnable runnable) ;

fragment的shader传入参数

//顶点着色器处理后的纹理采样坐标
varying vec2 vTextureCoord;
//Camera 预览的纹理(YUV格式)
uniform samplerExternalOES sTexture;

具体的,可以参考示例的滤镜DEMOFILTER

3. v3.x 和v4.x 对比说明

如果您是v3.x的用户,需要迁移到4.x,麻烦您首先阅读 迁移说明

在此基础上,对于滤镜的变更需要注意以下几点:

  1. KSYImageFilter需要替换为ImgTexFilter
  2. NO_FILTER_VERTEX_SHADER 变更为BASE_VERTEX_SHADER
  3. KSYImageFilter中的setFloat(int, float)相关函数您可以直接使用GLES20.glUniform1f(int, float)
  4. FRAGMENT_SHADER(原demo中的命名)即fragmentshaderbody 需要将下面的两句话去掉
 "#extension GL_OES_EGL_image_external : require\n”
 "uniform samplerExternalOES sTexture;\n”
  1. NO_TRANSFORMER_VERTEX_SHADER 变更为 GlUtil.BASE_VERTEX_SHADER
  2. KSYImageGroupFilter没有这个类了,如果要集成多个filter,直接调用接口getImgTexFilterMgt().setFilter(ImgTexFilter[] filterArray)来进行,参考代码如下:
List<ImgTexFilter> groupFilter = new LinkedList<>();

groupFilter.add(new DemoFilter2());

groupFilter.add(new DemoFilter3());

groupFilter.add(new DemoFilter4());

mStreamer.getImgTexFilterMgt().setFilter(groupFilter);
Clone this wiki locally