Android OpenGLES视频剪辑示例源码

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;
    }
}
相关推荐
村里小码农12 小时前
Android APP之间共享数据
android·contentprovider·contentresolver·android app数据共享
Jerry12 小时前
Navigation 最佳实践
android
Just_Paranoid13 小时前
【Android UI】Android 颜色的表示和获取使用指南
android·ui·theme·color·attr·colorstatelist
louisgeek13 小时前
Android Charles Proxy 抓包
android
Exploring15 小时前
从零搭建使用 Open-AutoGML 搜索附近的美食
android·人工智能
ask_baidu15 小时前
Doris笔记
android·笔记
lc99910215 小时前
简洁高效的相机预览
android·linux
hqk16 小时前
鸿蒙ArkUI:状态管理、应用结构、路由全解析
android·前端·harmonyos
消失的旧时光-194316 小时前
从 C 链表到 Android Looper:MessageQueue 的底层原理一条线讲透
android·数据结构·链表
方白羽16 小时前
Android 中Flags从源码到实践
android·app·客户端