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;
    }
}
相关推荐
四维碎片6 小时前
【Qt】配置安卓开发环境
android·开发语言·qt
百***99246 小时前
MySql的慢查询(慢日志)
android·mysql·adb
安卓兼职framework应用工程师6 小时前
android 15.0 Launcher3长按拖拽时,获取当前是哪一屏,获取当前多少个应用图标
android·拖拽·workspace·长按拖拽
雨白6 小时前
Jetpack Compose Navigation3:返回栈管理、大屏适配与自定义策略
android
CIb0la10 小时前
安卓16系统升级后(Google pixel 8/8pro 9/9pro xl 10/10pro xl)救砖及Root方法
android·运维·生活
Ya-Jun10 小时前
项目实战Now in Android:项目模块说明
android·架构·kotlin
@Aurora.11 小时前
【MySQL】基础
android
ooooooctober11 小时前
PHP代码审计框架性思维的建立
android·开发语言·php
q***829112 小时前
图文详述:MySQL的下载、安装、配置、使用
android·mysql·adb
沐怡旸13 小时前
【底层机制】Ashmem匿名共享内存:原理与应用深度解析
android·面试