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;
    }
}
相关推荐
双桥wow3 小时前
android 堆栈打印
android
爱学习的大牛1238 小时前
使用C++开发Android .so库的优势与实践指南
android·.so·1024程序员节
帅锅锅00711 小时前
SeLinux Type(类型)深度解析
android·操作系统
2501_9159214311 小时前
iOS混淆与IPA加固全流程(iOS混淆 IPA加固 Ipa Guard实战)
android·ios·小程序·https·uni-app·iphone·webview
游戏开发爱好者811 小时前
iOS 26 App 开发阶段性能优化 从多工具协作到数据驱动的实战体系
android·ios·小程序·uni-app·iphone·webview·1024程序员节
2501_9151063211 小时前
深入剖析 iOS 26 系统流畅度,多工具协同监控与性能优化实践
android·ios·性能优化·小程序·uni-app·cocoa·iphone
小彤花园12 小时前
GooglePlay更改签名秘钥报错(2025最新版)
android·google
Answer_momo13 小时前
一文读懂 Kotlin 数据流 Flow 的使用
android