@@ -58,13 +58,8 @@ public class VideoPlayerActivity extends Activity {
5858 @Override
5959 protected void onCreate (@Nullable Bundle savedInstanceState ) {
6060 super . onCreate(savedInstanceState);
61- mGLSurfaceView = new GLSurfaceView (this );
62- Display display = getWindowManager(). getDefaultDisplay();
63- int width = display. getWidth();
64- int height = (int ) ((width) * (9 / 16f ));
65- ViewGroup . LayoutParams layoutParams = new ViewGroup .LayoutParams (width, height);
66- mGLSurfaceView. setLayoutParams(layoutParams);
67- setContentView(mGLSurfaceView);
61+ setContentView(R . layout. activity_video_player);
62+ mGLSurfaceView = findViewById(R . id. mGLSurfaceView);
6863 mGLSurfaceView. setEGLContextClientVersion(3 );
6964 VideoPlayerRender videoPlayerRender = new VideoPlayerRender (mGLSurfaceView);
7065 videoPlayerRender. setIVideoTextureRenderListener(new VideoPlayerRender .IVideoTextureRenderListener () {
@@ -149,9 +144,184 @@ public class VideoPlayerActivity extends Activity {
149144
150145### 修复变形
151146
147+ 我们要根据视频的宽高和Render中Surface的宽高来计算缩放的比例,让高度或者宽度进行缩放,这样就不会变形了。主要修改的地方就是通过换算这个比例然后根据这个比例来改变顶点渲染器中的点的坐标值,从而让其在换算后的坐标内开始画面,这样就不会变形了。
148+
149+ 下面是改动后的VideoPlayerRender类:
150+
151+ ``` java
152+ public class VideoPlayerRender extends BaseGLSurfaceViewRenderer {
153+ private int mTextureId;
154+ private SurfaceTexture mSurfaceTexture;
155+ private GLSurfaceView mGLSurfaceView;
156+ private boolean mUpdateSurfaceTexture;
157+ private FloatBuffer mVertextBuffer;
158+ private FloatBuffer mTextureBuffer;
159+ private int vertexPosition;
160+ private int texturePosition;
161+ private int samplerTexturePosition;
162+ /**
163+ * 视频的宽高
164+ */
165+ private int mVideoWidth;
166+ private int mVideoHeight;
167+ /**
168+ * 需改更改渲染的大小
169+ */
170+ private boolean mNeedUpdateSize;
171+ /**
172+ * Surface的宽高
173+ */
174+ private int mSurfaceWidth;
175+ private int mSurfaceHeight;
176+
177+ /**
178+ * 坐标占用的向量个数
179+ */
180+ private static final int POSITION_COMPONENT_COUNT = 2 ;
181+ // 逆时针顺序排列
182+ private static final float [] POINT_DATA = {
183+ - 1f , - 1f ,
184+ 1f , - 1f ,
185+ - 1f , 1f ,
186+ 1f , 1f ,
187+ };
188+ /**
189+ * 颜色占用的向量个数
190+ */
191+ private static final int TEXTURE_COMPONENT_COUNT = 2 ;
192+ // 纹理坐标(s, t),t坐标方向和顶点y坐标反着
193+ private static final float [] TEXTURE_DATA = {
194+ 0.0f , 1.0f ,
195+ 1.0f , 1.0f ,
196+ 0.0f , 0.0f ,
197+ 1.0f , 0.0f
198+ };
199+
200+ public VideoPlayerRender (GLSurfaceView surfaceView ) {
201+ mGLSurfaceView = surfaceView;
202+ mVertextBuffer = BufferUtil . getFloatBuffer(POINT_DATA );
203+ mTextureBuffer = BufferUtil . getFloatBuffer(TEXTURE_DATA );
204+ }
205+
206+ @Override
207+ public void onSurfaceCreated (GL10 gl , EGLConfig config ) {
208+ glClearColor(0.0f , 1.0f , 0.0f , 1.0f );
209+ handleProgram(MyApplication . getInstance(), R . raw. video_vertex_shader, R . raw. video_fragment_shader);
210+ vertexPosition = glGetAttribLocation(" vPosition" );
211+ texturePosition = glGetAttribLocation(" vCoordPosition" );
212+ samplerTexturePosition = glGetUniformLocation(" uSamplerTexture" );
213+ mTextureId = TextureUtil . createOESTextureId();
214+ mSurfaceTexture = new SurfaceTexture (mTextureId);
215+ mSurfaceTexture. setDefaultBufferSize(mGLSurfaceView. getWidth(), mGLSurfaceView. getHeight());
216+ mSurfaceTexture. setOnFrameAvailableListener(new SurfaceTexture .OnFrameAvailableListener () {
217+ @Override
218+ public void onFrameAvailable (SurfaceTexture surfaceTexture ) {
219+ mUpdateSurfaceTexture = true ;
220+ if (mGLSurfaceView != null ) {
221+ mGLSurfaceView. requestRender();
222+ }
223+ }
224+ });
225+ if (mTextureRenderListener != null ) {
226+ mTextureRenderListener. onCreate(mSurfaceTexture);
227+ }
228+ }
229+
230+ @Override
231+ public void onSurfaceChanged (GL10 gl , int width , int height ) {
232+ mSurfaceWidth = width;
233+ mSurfaceHeight = height;
234+ adjustVideoSize();
235+ Log . e(" @@@" , " onSurfaceChanged width: " + width + " ...height.." + height);
236+ glViewport(0 , 0 , width, height);
237+ }
238+
239+ @Override
240+ public void onDrawFrame (GL10 gl ) {
241+ glClear(GLES30. GL_DEPTH_BUFFER_BIT | GLES30. GL_COLOR_BUFFER_BIT );
242+ adjustVideoSize();
243+ glVertexAttribPointer(vertexPosition, POSITION_COMPONENT_COUNT , GLES30. GL_FLOAT , false , 0 , mVertextBuffer);
244+ glVertexAttribPointer(texturePosition, TEXTURE_COMPONENT_COUNT , GLES30. GL_FLOAT , false , 0 , mTextureBuffer);
245+ synchronized (this ) {
246+ if (mUpdateSurfaceTexture) {
247+ mSurfaceTexture. updateTexImage();
248+ mUpdateSurfaceTexture = false ;
249+ }
250+ }
251+ GLES30 . glEnableVertexAttribArray(vertexPosition);
252+ GLES30 . glEnableVertexAttribArray(texturePosition);
253+ GLES30 . glUniform1i(samplerTexturePosition, 0 );
254+ // 绘制
255+ GLES30 . glDrawArrays(GLES30. GL_TRIANGLE_STRIP , 0 , 4 );
256+ GLES30 . glFlush();
257+ GLES30 . glDisableVertexAttribArray(vertexPosition);
258+ GLES30 . glDisableVertexAttribArray(texturePosition);
259+ }
260+
261+ public void setVideoSize (int width , int height ) {
262+ if (mVideoWidth == width && mVideoHeight == height) {
263+ return ;
264+ }
265+ // videoWidth 272
266+ // videoHeight 480
267+ mVideoWidth = width;
268+ mVideoHeight = height;
269+ mNeedUpdateSize = true ;
270+ }
271+
272+ private void adjustVideoSize () {
273+ if (mVideoWidth == 0 || mVideoHeight == 0 || mSurfaceHeight == 0 || mSurfaceWidth == 0 ) {
274+ return ;
275+ }
276+ if (! mNeedUpdateSize) {
277+ return ;
278+ }
279+ mNeedUpdateSize = false ;
280+ float widthRation = (float ) mSurfaceWidth / mVideoWidth;
281+ float heightRation = (float ) mSurfaceHeight / mVideoHeight;
282+ float ration = Math . max(widthRation, heightRation);
283+ // 把视频宽高最小的一个扩大到Surface的大小
284+ int targetVideoWidth = Math . round(mVideoWidth * ration);
285+ int targetVideoHeight = Math . round(mVideoHeight * ration);
286+ // 扩大之后的宽高除以目前surface的宽高,来算错各自要xy的比例,这俩里面有一个肯定是1
287+
288+ float rationX = (float ) targetVideoWidth / mSurfaceWidth;
289+ float rationY = (float ) targetVideoHeight / mSurfaceHeight;
290+
291+ float [] targetPositionData = new float []{
292+ POINT_DATA [0 ] / rationY, POINT_DATA [1 ] / rationX,
293+ POINT_DATA [2 ] / rationY, POINT_DATA [3 ] / rationX,
294+ POINT_DATA [4 ] / rationY, POINT_DATA [5 ] / rationX,
295+ POINT_DATA [6 ] / rationY, POINT_DATA [7 ] / rationX,
296+
297+ };
298+ // 换算缩放后的顶点坐标。后面在onDraw()方法中会有这个值设置给顶点着色器
299+ mVertextBuffer. clear();
300+ mVertextBuffer. put(targetPositionData);
301+ mVertextBuffer. position(0 );
302+ }
303+
304+ private IVideoTextureRenderListener mTextureRenderListener;
305+
306+ public void setIVideoTextureRenderListener (IVideoTextureRenderListener render ) {
307+ mTextureRenderListener = render;
308+ }
309+
310+ public interface IVideoTextureRenderListener {
311+ void onCreate (SurfaceTexture surfaceTexture );
312+ }
313+ }
314+ ```
315+
316+
317+
318+ 下面是具体的效果分别是填充宽和填充高的效果:
319+
320+ <img src =" https://raw.githubusercontent.com/CharonChui/Pictures/master/opengl_es_video_player1.jpeg " style =" zoom :40% ;" />
152321
153322
154323
324+ <img src =" https://raw.githubusercontent.com/CharonChui/Pictures/master/opengl_es_video_player_2.jpeg " style =" zoom :33% ;" />
155325
156326
157327
0 commit comments