1.基于Android OpenGLES开发,可实现各种视频剪辑功能,内置多种视频特效滤镜和转场动画,还可按需增加各种自定义滤镜和转场动画;
2.通过OpenGLES渲染图片,把图片当成视频,实现图片和视频混合编辑;
3.视频和背景音乐合成,可自定义任意时段的背景音乐;
4.集成FFmpeg,用于实现从视频中提取音频,视频格式转换等多种强大功能;
APK下载链接: https://pan.baidu.com/s/1YpgxrHIfP0VH1PzTht-ZWQ 提取码: v95m
(需要源码的撩我,非免费的哦!)


EGLSurfaceView实现代码
java
import android.content.Context;
import android.util.AttributeSet;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import com.libmycommon.myutils.CustomLog;
import com.mediaeditor.myegl.EglCore;
import java.lang.ref.WeakReference;
import javax.microedition.khronos.egl.EGLContext;
public class EGLSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private Surface surface;
private EGLThread mEGLThread;
private IGLRender mIGLRender;
public final static int RENDER_MODE_WHEN_DIRTY = 0;
public final static int RENDER_MODE_CONTINUOUSLY = 1;
private int mRenderMode = RENDER_MODE_WHEN_DIRTY;
public EGLSurfaceView(Context context) {
this(context, null);
}
public EGLSurfaceView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public EGLSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
getHolder().addCallback(this);
}
public void setRender(IGLRender IGLRender) {
this.mIGLRender = IGLRender;
}
public void setRenderMode(int mRenderMode) {
if(mIGLRender == null) {
throw new RuntimeException("must set render before");
}
this.mRenderMode = mRenderMode;
}
public EGLContext getEglContext() {
if(mEGLThread != null) {
return mEGLThread.getEglContext();
}
return null;
}
public void requestRender() {
if(mEGLThread != null) {
mEGLThread.requestRender();
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if(surface == null) {
surface = holder.getSurface();
}
mEGLThread = new EGLThread(new WeakReference<EGLSurfaceView>(this));
mEGLThread.isCreate = true;
mEGLThread.start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
mEGLThread.width = width;
mEGLThread.height = height;
mEGLThread.isChange = true;
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mEGLThread.onDestroy();
mEGLThread = null;
surface = null;
}
public EglCore getEglHelper() {
return mEGLThread.getEglHelper();
}
public interface IGLRender {
void onSurfaceCreated(EglCore eglHelper);
void onSurfaceChanged(int width, int height);
void onDrawFrame(WindowSurface windowSurface);
}
class EGLThread extends Thread {
private WeakReference<EGLSurfaceView> surfaceViewWeakReference;
private EglCore eglHelper = null;
private Object object = null;
private WindowSurface windowSurface;
private boolean isExit = false;
private boolean isCreate = false;
private boolean isChange = false;
private boolean isStart = false;
private int width;
private int height;
public EGLThread(WeakReference<EGLSurfaceView> surfaceViewWeakReference) {
this.surfaceViewWeakReference = surfaceViewWeakReference;
}
@Override
public void run() {
super.run();
try {
isExit = false;
isStart = false;
object = new Object();
eglHelper = new EglCore();
windowSurface = new WindowSurface(eglHelper, surfaceViewWeakReference.get().surface, false);
windowSurface.makeCurrent();
while (true) {
if(isExit) {
release();
break;
}
if(isStart) {
if(surfaceViewWeakReference.get().mRenderMode == RENDER_MODE_WHEN_DIRTY) {
synchronized (object) {
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} else if(surfaceViewWeakReference.get().mRenderMode == RENDER_MODE_CONTINUOUSLY) {
try {
Thread.sleep(1000 / 60);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
throw new RuntimeException("mRenderMode is wrong value");
}
}
onCreate();
onChange(width, height);
onDraw();
isStart = true;
if(onMyDraw != null) {
onMyDraw.onMyDraw();
}
}
} catch (Exception e) {//TODO
CustomLog.e("EGLThread runtime exception " + e.toString());
}
}
private void onCreate() {
if(isCreate && surfaceViewWeakReference.get().mIGLRender != null) {
isCreate = false;
surfaceViewWeakReference.get().mIGLRender.onSurfaceCreated(eglHelper);
}
}
private void onChange(int width, int height) {
if(isChange && surfaceViewWeakReference.get().mIGLRender != null) {
isChange = false;
surfaceViewWeakReference.get().mIGLRender.onSurfaceChanged(width, height);
}
}
private void onDraw() {
if(surfaceViewWeakReference.get().mIGLRender != null && eglHelper != null) {
windowSurface.makeCurrent();
surfaceViewWeakReference.get().mIGLRender.onDrawFrame(windowSurface);
}
}
private void requestRender() {
if(object != null) {
synchronized (object) {
object.notifyAll();
}
}
}
public void onDestroy() {
isExit = true;
requestRender();
}
public void release() {
if(eglHelper != null) {
// eglHelper.destroyEgl();
eglHelper.release();
eglHelper = null;
object = null;
surfaceViewWeakReference = null;
}
}
public EGLContext getEglContext() {
if(eglHelper != null) {
eglHelper.getEGLContext();
// return eglHelper.getEglContext();
}
return null;
}
public EglCore getEglHelper() {
return eglHelper;
}
}
private OnMyDraw onMyDraw;
public interface OnMyDraw {
void onMyDraw();
}
public void setOnMyDraw(OnMyDraw onMyDraw) {
this.onMyDraw = onMyDraw;
}
}