[OpenGL]从零开始写一个Android平台下的全景视频播放器——2.3 使用GLSurfaceView和MediaPlayer播放一个平面视频(下)

本文介绍如何在Android平台上使用OpenGL和GLSurfaceView结合MediaPlayer实现全景视频播放,包括解决视频颠倒问题、屏幕尺寸自适应以及生命周期管理。通过调整顶点数组适应不同宽高比视频,并提供了获取视频尺寸的方法。
摘要由CSDN通过智能技术生成

Github项目地址,欢迎star~!

为了方便没有准备好梯子的同学,我把项目在CSDN上打包下载,不过更新会慢一些

回到目录

视频颠倒的问题

其实,不要更新mSTMatrix,将他设为单位阵,一般就会显示正常的视频。。
在使用mSTMatrix的情况下,解决方法就是修改顶点数组或者修改纹理数组,我们采用修改顶点数组的方案:

private final float[] vertexData = {
        1f,-1f,0f,
        -1f,-1f,0f,
        1f,1f,0f,
        -1f,1f,0f
};

屏幕尺寸自适应

如何才能让显示出来的宽高比符合视频的宽高比呢? 答案依然是正交投影!
但是有一些不同,因为我们现在有两个尺寸,一个是屏幕的宽高,一个是视频的宽高,在之前显示图片的时候,我们直接采用了把图片去掉一部分,以适应”绘制一个正方形区域”的要求,那有没有更好的解决方案呢?
分析一下吧,其实无非就两种情况:

  • 屏幕宽高比小于视频宽高比,如图:
    这里写图片描述
  • 屏幕宽高比大于视频宽高比,如图:
    这里写图片描述

其中,蓝色的是我们的视频区域,蓝色坐标轴是OpenGL屏幕坐标轴,黄色的是纹理坐标轴,注意,我将所有的规范坐标都放到了视频的四个角落,这是因为我们要保证视频完全显示,不变形并且最大化的显示,而我们的纹理坐标和顶点坐标就是像这四个顶点描述的这样子。

这两种情况,只要搞定一种,另外一种也就很容易推导出来了。

  • 获取视频尺寸

    获取视频的尺寸可以设置一个监听器:

 mediaPlayer.setOnVideoSizeChangedListener(this);

@Override
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
    Log.d(TAG, "onVideoSizeChanged: "+width+" "+height);
    updateProjection(width,height);
}

之前提过,屏幕尺寸是在onSurfaceCreated获取的。
有了这两个尺寸,我们就可以更新Projection矩阵了,代码可能有些难以理解,对于videoRatio>screenRatio,其实就是我们是将videoHeight/videoWidth当做一个单位来处理(因为之前的坐标映射),然后我们用screenHeight/screenWidth再去除这个单位,来获得屏幕Y轴方向应该有的范围

private void updateProjection(int videoWidth, int videoHeight){
    float screenRatio=(float)screenWidth/screenHeight;
    float videoRatio=(float)videoWidth/videoHeight;
    if (videoRatio>screenRatio){
        Matrix.orthoM(projectionMatrix,0,-1f,1f,-videoRatio/screenRatio,videoRatio/screenRatio,-1f,1f);
    }else Matrix.orthoM(projectionMatrix,0,-screenRatio/videoRatio,screenRatio/videoRatio,-1f,1f,-1f,1f);
}

屏幕比例16:10,第一个视频比例4:3,第二个视频比例2:1
这里写图片描述
这里写图片描述

MediaPlayer和GLSurfaceView生命周期控制

首先,主活动的生命周期中和GLSurfaceView主要有两个,和MediaPlayer相关的有三个,我们会在后面做播放控制的时候再详细说明。

@Override
protected void onDestroy() {
    super.onDestroy();
    glRenderer.getMediaPlayer().release();
}

@Override
protected void onPause() {
    super.onPause();
    glSurfaceView.onPause();
    glRenderer.getMediaPlayer().pause();
}

@Override
protected void onResume() {
    super.onResume();
    glSurfaceView.onResume();
}

顺便贴一下所有的代码
GLRenderer.java

package com.martin.ads.panoramaopengltutorial;

import android.content.Context;
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值