Android MediaPlayer + GLSurfaceView 播放视频

news2024/12/27 18:44:46

Android使用OpenGL 播放视频

    • 概述
      • TextureView的优缺点
      • OpenGL的优缺点
    • 实现
    • 复杂图形效果的场景
    • 参考

概述

    在Android开发中,使用OpenGL ES来渲染视频是一种常见的需求,尤其是在需要实现自定义的视频播放界面或者视频特效时。结合MediaPlayer,我们可以实现一个功能强大的视频播放器。以下是一个简单的示例,展示如何在Android应用中使用OpenGL ES和MediaPlayer播放本地视频。
    常规的视频播放方式有VideoView, MediaPlayer + SurfaceView / TextureView, 以TextureView为例, 它与OpenGL(GLSurfaceView)播放的一些比较:

TextureView的优缺点

  • 优点
    • 灵活性高:TextureView可以与其他View叠加使用,非常适合在复杂的视图层次结构中使用。
    • 硬件加速支持:由于它在硬件加速层进行渲染,其性能也较优。
    • 支持绘制操作:可以从其他线程更新内容,适合用于播放视频、显示实时特效等。
  • 缺点
    • 内存占用较高:TextureView的内部缓冲队列导致比SurfaceView使用更多的内存。
    • 在5.0以前在主线程渲染:在5.0版本之前,TextureView在主线程渲染,可能会导致性能问题。

OpenGL的优缺点

  • 优点
    • 高度定制化:OpenGL提供低级别的图形渲染接口,允许开发者高度定制视频播放界面和特效。
    • 性能优化:通过优化渲染代码,可以在一定程度上提高视频播放的效率和性能。
  • 缺点
    • 开发复杂度较高:使用OpenGL需要编写大量的底层代码,包括顶点着色器和片段着色器的编写,这增加了开发的复杂度和难度。

    TextureView在灵活性、硬件加速支持和多线程更新方面具有优势,适合需要与其他视图交互的场景。而OpenGL则提供了更高的定制化程度,适合需要实现复杂图形效果的场景

实现

    梳理收集来的参考代码, 实现视频播放效果如下:
在这里插入图片描述

GLVideoActivity.java

package com.ansondroider.sdktester.activity;

import android.media.MediaPlayer;
import android.opengl.GLSurfaceView;
import android.os.Bundle;

import com.ansondroider.acore.BaseActivity;
import com.ansondroider.sdktester.gl.GLVideoView;

import java.io.IOException;

public class GLVideoActivity extends BaseActivity {
    MediaPlayer mmp;
    GLVideoView glView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        glView = new GLVideoView(this);
        setContentView(glView);
    }

    @Override
    protected void onStart() {
        super.onStart();
        //postDelayed(new Runnable() {
        //    @Override
        //    public void run() {
                mmp = new MediaPlayer();
                try {
                    mmp.setDataSource("/sdcard/Movies/376463.mp4");
                    mmp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                        @Override
                        public void onPrepared(MediaPlayer mediaPlayer) {
                            glView.onVideoPrepared(mediaPlayer);
                        }
                    });
                    mmp.prepare();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        //    }
        //}, 100);

    }

    @Override
    protected void onStop() {
        super.onStop();
        mmp.stop();
        mmp.release();
    }
}

GLVideoView.java

package com.ansondroider.sdktester.gl;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.media.MediaPlayer;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Surface;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
/**
 * @ProjectName: TheSimpllestplayer
 * @Package: com.yw.thesimpllestplayer.renderview
 * @ClassName: VideoDrawer
 * @Description: 视频渲染器
 * @Author: wei.yang
 * @CreateDate: 2021/11/6 14:23
 * @UpdateUser: 更新者:wei.yang
 * @UpdateDate: 2021/11/6 14:23
 * @UpdateRemark: 更新说明:
 * @Version: 1.0
 */
public class GLVideoView extends GLSurfaceView {
    final String TAG = "GLVideoView";
    //顶点坐标,此处的坐标系是物体坐标系:中心店坐标是(0,0)
    private float[] mVertexCoors = new float[]{
            -1f, -1f,
            1f, -1f,
            -1f, 1f,
            1f, 1f
    };
    //纹理坐标系,中心坐标点为(0.5,0.5),上方向为t从0~1,右边方向为s,从0~1.刚好和计算器物理坐标系是反过来的。
    private float[] mTextureCoors = new float[]{
            0f, 1f,
            1f, 1f,
            0f, 0f,
            1f, 0f
    };
    private String vertextShaderSource = "attribute vec4 aPosition;" +
            "precision mediump float;" +
            "uniform mat4 uMatrix;" +
            "attribute vec2 aCoordinate;" +
            "varying vec2 vCoordinate;" +
            "attribute float alpha;" +
            "varying float inAlpha;" +
            "void main(){" +
            "gl_Position = uMatrix*aPosition;" +
            "vCoordinate = aCoordinate;" +
            "inAlpha = alpha;" +
            "}";
    private String fragmentShaderSource = "#extension GL_OES_EGL_image_external : require\n" +
            "precision mediump float;" +
            "varying vec2 vCoordinate;" +
            "varying float inAlpha;" +
            "uniform samplerExternalOES uTexture;" +
            "void main() {" +
            "vec4 color = texture2D(uTexture, vCoordinate);" +
            "gl_FragColor = vec4(color.r, color.g, color.b, inAlpha);" +
            "}";
    //视频宽高
    private int mVideoWidth = -1;
    private int mVideoHeight = -1;

    //物理屏幕的宽高
    private int mWorldWidth = -1;
    private int mWorldHeight = -1;

    //纹理ID
    private int mTextureId = -1;

    //定义SurfaceTexture 为显示视频做准备;
    private SurfaceTexture mSurfaceTexture = null;

    // 定义OpenGL 程序ID
    private int mProgram = -1;
    //矩阵变换接受者(shader中)
    private int mVertexMatrixHandler = -1;
    //顶点坐标接收者
    private int mVertexPosHandler = -1;
    //纹理坐标接受者
    private int mTexturePosHandler = -1;
    //纹理接受者
    private int mTextureHandler = -1;
    //半透明值接受者
    private int mAlphaHandler = -1;
    //顶点缓冲
    private FloatBuffer mVertexBuffer = null;
    //纹理缓冲
    private FloatBuffer mTextureBuffer = null;
    //矩阵
    private float[] mMatrix = null;
    //透明度
    private float mAlpha = 1f;
    //旋转角度
    private float mWidthRatio = 1f;
    private float mHeightRatio = 1f;
    private int floatLength = 16;

    public GLVideoView(Context context) {
        super(context);
        init();
    }

    public GLVideoView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init(){
        setEGLContextClientVersion(2);
        setRenderer(new VideoRender());
        setRenderMode(RENDERMODE_WHEN_DIRTY);
        initPos();
    }

    /**
     * 初始化顶点坐标
     */
    private void initPos() {
        ByteBuffer vByteBuffer = ByteBuffer.allocateDirect(mVertexCoors.length * 4);
        vByteBuffer.order(ByteOrder.nativeOrder());
        //将坐标转换为floatbuffer,用以传给opengl程序
        mVertexBuffer = vByteBuffer.asFloatBuffer();
        mVertexBuffer.put(mVertexCoors);
        mVertexBuffer.position(0);

        ByteBuffer tByteBuffer = ByteBuffer.allocateDirect(mTextureCoors.length * 4);
        tByteBuffer.order(ByteOrder.nativeOrder());
        mTextureBuffer = tByteBuffer.asFloatBuffer();
        mTextureBuffer.put(mTextureCoors);
        mTextureBuffer.position(0);
    }

    /**
     * 初始化矩阵变换,主要是防止视频拉伸变形
     */
    private void initDefMatrix() {
        //Log.d(TAG, "initDefMatrix");
        if (mMatrix != null) return;
        if (mVideoWidth != -1 && mVideoHeight != -1 &&
                mWorldWidth != -1 && mWorldHeight != -1) {
            mMatrix = new float[floatLength];
            float[] prjMatrix = new float[floatLength];
            float originRatio = mVideoWidth / (float) mVideoHeight;
            float worldRatio = mWorldWidth / (float) mWorldHeight;
            if (mWorldWidth > mWorldHeight) {
                if (originRatio > worldRatio) {
                    mHeightRatio = originRatio / worldRatio;
                    Matrix.orthoM(
                            prjMatrix, 0,
                            -mWidthRatio, mWidthRatio,
                            -mHeightRatio, mHeightRatio,
                            3f, 5f
                    );
                } else {// 原始比例小于窗口比例,缩放高度度会导致高度超出,因此,高度以窗口为准,缩放宽度
                    mWidthRatio = worldRatio / originRatio;
                    Matrix.orthoM(
                            prjMatrix, 0,
                            -mWidthRatio, mWidthRatio,
                            -mHeightRatio, mHeightRatio,
                            3f, 5f
                    );
                }
            } else {
                if (originRatio > worldRatio) {
                    mHeightRatio = originRatio / worldRatio;
                    Matrix.orthoM(
                            prjMatrix, 0,
                            -mWidthRatio, mWidthRatio,
                            -mHeightRatio, mHeightRatio,
                            3f, 5f
                    );
                } else {// 原始比例小于窗口比例,缩放高度会导致高度超出,因此,高度以窗口为准,缩放宽度
                    mWidthRatio = worldRatio / originRatio;
                    Matrix.orthoM(
                            prjMatrix, 0,
                            -mWidthRatio, mWidthRatio,
                            -mHeightRatio, mHeightRatio,
                            3f, 5f
                    );
                }
            }
            //设置相机位置
            float[] viewMatrix = new float[floatLength];
            Matrix.setLookAtM(
                    viewMatrix, 0,
                    0f, 0f, 5.0f,
                    0f, 0f, 0f,
                    0f, 1.0f, 0f
            );
            //计算变换矩阵
            Matrix.multiplyMM(mMatrix, 0, prjMatrix, 0, viewMatrix, 0);
        }
    }
    private Surface mSurface = null;
    MediaPlayer mMediaPlayer;
    public void onVideoPrepared(MediaPlayer mp){
        Log.d(TAG, "onVideoPrepared");
        mMediaPlayer = mp;

        if(mSurfaceTexture != null) {
            int videoWidth = mMediaPlayer.getVideoWidth();
            int videoHeight = mMediaPlayer.getVideoHeight();
            setVideoSize(videoWidth, videoHeight);
            mSurface = new Surface(mSurfaceTexture);
            mMediaPlayer.setSurface(mSurface);
            mMediaPlayer.start();
        }
    }
    private void setVideoSize(int videoWidth, int videoHeight) {
        Log.d(TAG, "setVideoSize " + videoWidth + "x" + videoHeight);
        mVideoWidth = videoWidth;
        mVideoHeight = videoHeight;
    }

    private void setWorldSize(int worldWidth, int worldHeight) {
        mWorldWidth = worldWidth;
        mWorldHeight = worldHeight;
    }

    @Override
    public void setAlpha(float alpha) {
        super.setAlpha(alpha);
        mAlpha = alpha;
    }

    private SurfaceTexture getSurfaceTexture() {
        return mSurfaceTexture;
    }

    /**
     * 创建并使用opengles程序
     */
    private void createGLPrg() {
        if (mProgram == -1) {
            int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertextShaderSource);
            int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderSource);
            //创建programe陈谷
            mProgram = GLES20.glCreateProgram();
            //将顶点着色器加入程序
            GLES20.glAttachShader(mProgram, vertexShader);
            //将片元着色器加入程序
            GLES20.glAttachShader(mProgram, fragmentShader);
            GLES20.glLinkProgram(mProgram);
            //从程序中获取句柄
            mVertexMatrixHandler = GLES20.glGetUniformLocation(mProgram, "uMatrix");
            mVertexPosHandler = GLES20.glGetAttribLocation(mProgram, "aPosition");
            mTextureHandler = GLES20.glGetUniformLocation(mProgram, "uTexture");
            mTexturePosHandler = GLES20.glGetAttribLocation(mProgram, "aCoordinate");
            mAlphaHandler = GLES20.glGetAttribLocation(mProgram, "alpha");

        }
        //使用opengl程序
        GLES20.glUseProgram(mProgram);
    }

    /**
     * 激活并绑定纹理单元
     */
    private void activateTexture() {
        //激活指定纹理单元
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        //绑定纹理ID到纹理单元
        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureId);
        //将激活并绑定的纹理id传递到着色器里面
        GLES20.glUniform1i(mTextureHandler, 0);
        //配置边缘过滤参数
        GLES20.glTexParameterf(
                GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
                GLES20.GL_TEXTURE_MIN_FILTER,
                GLES20.GL_LINEAR
        );
        GLES20.glTexParameterf(
                GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
                GLES20.GL_TEXTURE_MAG_FILTER,
                GLES20.GL_LINEAR
        );
        //配置s轴和t轴的方式
        GLES20.glTexParameteri(
                GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
                GLES20.GL_TEXTURE_WRAP_S,
                GLES20.GL_CLAMP_TO_EDGE
        );
        GLES20.glTexParameteri(
                GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
                GLES20.GL_TEXTURE_WRAP_T,
                GLES20.GL_CLAMP_TO_EDGE
        );
    }

    private void updateTexture() {
        mSurfaceTexture.updateTexImage();
    }

    /**
     * 加载着色器
     *
     * @param shaderType 着色器类型
     * @param shaderCode 着色器代码
     * @return
     */
    private int loadShader(int shaderType, String shaderCode) {
        //根据着色器类型创建着色器
        int shader = GLES20.glCreateShader(shaderType);
        //将着色其代码加入到着色器
        GLES20.glShaderSource(shader, shaderCode);
        //编译zhuoseq
        GLES20.glCompileShader(shader);
        return shader;
    }

    /**
     * 开始绘制渲染
     */
    public void doDraw() {
        if(mMatrix == null)return;
        //启用顶点坐标句柄
        GLES20.glEnableVertexAttribArray(mVertexPosHandler);
        GLES20.glEnableVertexAttribArray(mTexturePosHandler);
        GLES20.glUniformMatrix4fv(mVertexMatrixHandler, 1, false, mMatrix, 0);
        //设置着色器参数, 第二个参数表示一个顶点包含的数据数量,这里为xy,所以为2
        GLES20.glVertexAttribPointer(mVertexPosHandler, 2, GLES20.GL_FLOAT, false, 0, mVertexBuffer);
        GLES20.glVertexAttribPointer(
                mTexturePosHandler,
                2,
                GLES20.GL_FLOAT,
                false,
                0,
                mTextureBuffer
        );
        GLES20.glVertexAttrib1f(mAlphaHandler, mAlpha);
        //开始绘制
        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, mVertexCoors.length / 2);
    }

    @Override
    protected void onDetachedFromWindow() {
        Log.d(TAG, "onDetachedFromWindow");
        super.onDetachedFromWindow();
        GLES20.glDisableVertexAttribArray(mVertexPosHandler);
        GLES20.glDisableVertexAttribArray(mTexturePosHandler);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
        GLES20.glDeleteTextures(1, new int[]{mTextureId}, 0);
        GLES20.glDeleteProgram(mProgram);
        if(mMediaPlayer != null){
            //mMediaPlayer.setSurface(null);
            mMediaPlayer.release();
            mSurface.release();
        }
    }

    public void translate(float dx, float dy) {
        Matrix.translateM(mMatrix, 0, dx * mWidthRatio * 2, -dy * mHeightRatio * 2, 0f);
    }

    public void scale(float sx, float sy) {
        Matrix.scaleM(mMatrix, 0, sx, sy, 1f);
        mWidthRatio /= sx;
        mHeightRatio /= sy;
    }

    public class VideoRender implements GLSurfaceView.Renderer {
        @Override
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            Log.d(TAG, "onSurfaceCreated");
            GLES20.glClearColor(0f, 0f, 0f, 0f);
            //开启混合,即半透明
            GLES20.glEnable(GLES20.GL_BLEND);
            GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
            int[] textureIds = new int[1];
            GLES20.glGenTextures(1, textureIds, 0);
            mTextureId = textureIds[0];
            //根据textureId初始化一个SurfaceTexture
            mSurfaceTexture = new SurfaceTexture(mTextureId);
            mSurfaceTexture.setOnFrameAvailableListener(new SurfaceTexture.OnFrameAvailableListener() {
                @Override
                public void onFrameAvailable(SurfaceTexture surfaceTexture) {
                    requestRender();
                }
            });
            if(mMediaPlayer != null){
                onVideoPrepared(mMediaPlayer);
            }
        }

        @Override
        public void onSurfaceChanged(GL10 gl, int width, int height) {
            Log.d(TAG, "onSurfaceChanged");
            GLES20.glViewport(0, 0, width, height);
            setWorldSize(width, height);
        }

        @Override
        public void onDrawFrame(GL10 gl) {
            Log.d(TAG, "onDrawFrame");
            if(mMediaPlayer == null || !mMediaPlayer.isPlaying())return;

            //清除颜色缓冲和深度缓冲
            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
            if (mTextureId != -1) {
                initDefMatrix();
                //2/创建、编译、启动opengles着色器
                createGLPrg();
                //3.激活并绑定纹理单元
                activateTexture();
                //4.绑定图元到纹理单元
                updateTexture();
                //5.开始绘制渲染
                doDraw();
            }
        }
    }
}

复杂图形效果的场景

普通的视频播放方式很难实现 曲面 百叶窗 这类的效果, 如:
在这里插入图片描述
而使用OpenGL播放, 只需要调整下顶点和纹理的坐标即可:

    //顶点坐标,此处的坐标系是物体坐标系:中心店坐标是(0,0)
    private float[] mVertexCoors = new float[]{
            -1f, 1f,
            -1f, -1f,
            0, 0.5f,
            0, -0.5f,
            1f, 1f,
            1f, -1f,
    };
    //纹理坐标系,中心坐标点为(0.5,0.5),上方向为t从0~1,右边方向为s,从0~1.刚好和计算器物理坐标系是反过来的。
    private float[] mTextureCoors = new float[]{
            0f, 0f,
            0f, 1f,
            0.5f, 0,
            0.5f, 1f,
            1f, 0f,
            1f, 1f
    };

参考

  1. 10.GLSurfaceView+MediaPlayer播放视频.md
  2. 【Android 音视频开发打怪升级:OpenGL渲染视频画面篇】二、使用OpenGL渲染视频画面
  3. Android 最简单的视频播放器之OpenGL ES视频渲染工具封装(三)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2140732.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java后端框架---Spring

目录 一.Spring是什么? 二.Spring Hello World 搭建 三.XML配置bean管理 1.bean标签 2.依赖注入 3.依赖注入的补充 四.注解配置bean管理 1.开启注解扫描 2.使用注解对类进行配置 3.自动注入 五.面向切面编程AOP 1.概述 2.通知 六.spring事务管理 1.数据库…

双三次插值及MATLAB实现

一、双三次插值的概念 双三次插值(Bicubic interpolation),又叫双立方插值。在数值分析这个数学分支中,双三次插值是二维空间中最常用的插值方法。在这种方法中,函数f在点 (x0 ,y0) 的值不仅考虑其直接邻接点对其的影响…

MySQL —— 索引

索引的概念 MySQL的索引是⼀种数据结构,它可以帮助数据库高效地查询、更新数据表中的数据。索引通过 ⼀定的规则排列数据表中的记录,使得对表的查询可以通过对索引的搜索来加快速度。 MySQL索引类似于书籍的目录,通过指向数据行的位置&…

Flutter Error: Type ‘UnmodifiableUint8ListView‘ not found

问题描述 原本我在Mac开发的项目,现在win10运行时报如下错误: ../../../AppData/Local/Pub/Cache/hosted/pub.dev/win32-3.1.4/lib/src/guid.dart:31:9: Error: Type UnmodifiableUint8ListView not found. final UnmodifiableUint8ListView bytes; ^^…

C# 异步编程场景

前言 异步编程允许程序在等待某些操作(如文件读写、网络请求等)完成时,不必阻塞主线程,从而可以继续执行其他任务。这种非阻塞的特性对于提高应用程序的并发性和响应速度至关重要。C# 通过 async 和 await 关键字,以及…

hh exe所选的程序不能与此文件类型相关联。请选择其他程序。

按照hh exe打开chm文件显示所选的程序不能与此文件类型相关联。请选择其他程序。 以上错误来自于 cmd命令行 cd C:\Windows\hh.exe 要打开的chm文件报错 其实根本原因是在设置中.chm文件默认打开方法被其他软件占用了,解决办法只能删除那个软件,如果是W…

828华为云征文 | 云服务器Flexus X实例:部署 AgentOps,全方位监测智能体

目录 一、什么是 AgentOps ? 二、部署 AgentOps 2.1 安装 AgentOps 2.2 注册账号 2.3 生成 API_KEY 三、AgentOps 实例 3.1 创建实例 3.2 运行实例 四、总结 通过深入体验华为云的 Flexus云服务器X实例,我发现它不仅提供了直接通过公网访问的便利性&#…

【 html+css 绚丽Loading 】 000049 流云穿梭环

前言:哈喽,大家好,今天给大家分享今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 &#x1f…

回归预测|基于遗传优化卷积神经网络的数据回归预测Matlab程序GA-CNN 多特征输入单输出 附赠基础CNN

回归预测|基于遗传优化卷积神经网络的数据回归预测Matlab程序GA-CNN 多特征输入单输出 附赠基础CNN 文章目录 一、基本原理1. 卷积神经网络(CNN)2. 遗传算法(GA)3. GA-CNN回归预测模型总结 二、实验结果三、核心代码四、代码获取五…

智能BI项目第一期

该项目是全程跟着鱼皮,还未进行功能扩展。为了方便日后复习,打算将一些重要的步骤记录下来。 项目概述 BI:即商业智能:Business Intelligence 过去 需要手动导入数据、选择要分析的字段和图表,并由专业的数据分析师完成分析,最后得出结论。 现在 用户…

docker发布redis容器

1.导入redis镜像 2.写docker-compose文件 并创建容器 redis:container_name: redisimage: redis:latestports:- "6379:6379"restart: always 3.测试一下

“深入解析:MySQL半同步复制的配置指南与实践技巧“

本次配置是在已搭建好主从复制的架构中进行配置 配置环境 操作系统 master节点 slave节点 centos7 8.0.37 8.0.37 配置半同步复制 配置master 安装master半同步复制插件 INSTALL PLUGIN rpl_semi_sync_source SONAME semisync_source.so; 在MySQL的配置文件中添加配置…

论文(六):Fire-Net: A Deep Learning Framework for Active Forest Fire Detection

文章目录 1.Introduction2.Study Area2.1Landsat-8 Dataset2.2Inventory data 3.Methodology3.1Image Pre-processing3.2Proposed Deep Learning Architecture (Fire-Net)3.2.1Convolution Layers3.2.2 Evaluation Indices/methods or accuracy assessment. 4.Results4.1 Austr…

JVM HotSpot 虚拟机: 对象的创建, 内存布局和访问定位

目录 前言 对象的创建 对象的内存布局 对象的访问定位 前言 了解JVM的内存区域划分之后, 也大致了解了java程序的内存分布模型, 也了解它里面的内存区域里面的类型和各个类型的作用, 接下来我们进一步从对象创建到访问的角度, 来看看这些内存区域之间是怎么关联起来的. …

【C++篇】C++类与对象深度解析(二):类的默认成员函数详解

文章目录 【C篇】C类与对象深度解析(二)前言1. 类的默认成员函数2. 构造函数2.1 函数名与类名相同2.2 无返回值2.3 对象实例化时系统会自动调用2.4 构造函数可以重载2.5 默认构造函数的生成规则2.6 无参构造函数与全缺省构造函数的关系2.7 内置类型与自定…

五、(JS)window中的定时器

一、为什么叫做window中的定时器 我们在全局中会用到一些函数,比如说alert函数,prompt函数,setTimeout等等 我们有在这里定义过这些函数吗?很明显没有。可见我们这些函数都是来自于window。 所以还可以写成window.setTimeout。…

Linux 开发工具(vim、gcc/g++、make/Makefile)+【小程序:进度条】-- 详解

目录 一、Linux软件包管理器 - yum(ubuntu用apt代替yum)1、Linux下安装软件的方式2、认识 yum3、查找软件包4、安装软件5、如何实现本地机器和云服务器之间的文件互传 二、Linux编辑器 - vim1、vim 的基本概念2、vim 下各模式的切换3、vim 命令模式各命令…

【Linux篇】TCP/IP协议(笔记)

目录 一、TCP/IP协议族体系结构 1. 数据链路层 (1)介绍 (2)常用协议 ① ARP协议(Address Resolve Protocol,地址解析协议) ② RARP协议(Reverse Address Resolve Protocol&…

[Meachines] [Easy] Sauna DC域+AS-REP+TGT票证窃取+AutoLogon凭据+DCSync攻击

信息收集 IP AddressOpening Ports10.10.10.175TCP:53,80,88,135,139,389,445,464,593,3268,3269,5985 $ nmap -p- 10.10.10.175 --min-rate 1000 -sC -sV PORT STATE SERVICE VERSION 53/tcp open domain? | fingerprint-strings: | DNSVersionBindReqTCP…