经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » Android » 查看文章
Android使用MediaPlayer和TextureView实现视频无缝切换
来源:jb51  时间:2019/10/9 11:29:29  对本文有异议

需求描述

比如广告播放,每个视频15秒,视频之间切换的时候,性能不太好的机器可能会黑屏一段时间,体验不太好,接下来我们就是要解决这个黑屏问题。

解决方案

使用两个surfaceView方式,经过测试不行
使用一个MediaPlayer,在MediaPlayer上面加一层ImageView,每次播放完成后,获取视频的最后一帧的图像给ImageView,视频切换完成,ImageView隐藏,如此往复循环,可行

实践

1.获取视频流图片方式,通过MediaMetadataRetriever,测试发现,部分机器获取的Bitmap可能为空,无法解决,放弃

2.使用TextureView方式,可以获取当前帧的Bitmap,可行,下面贴代码

  1. package com.winson.blog.video;
  2. import android.graphics.Bitmap;
  3. import android.graphics.SurfaceTexture;
  4. import android.media.MediaPlayer;
  5. import android.net.Uri;
  6. import android.os.Bundle;
  7. import android.os.Environment;
  8. import android.os.Handler;
  9. import android.support.annotation.Nullable;
  10. import android.support.v4.app.Fragment;
  11. import android.util.Log;
  12. import android.view.Gravity;
  13. import android.view.LayoutInflater;
  14. import android.view.Surface;
  15. import android.view.TextureView;
  16. import android.view.View;
  17. import android.view.ViewGroup;
  18. import android.widget.FrameLayout;
  19. import android.widget.ImageView;
  20. import java.io.IOException;
  21. public class VideoFragment extends Fragment {
  22. public static final String TAG = VideoFragment.class.getSimpleName();
  23. String TEST_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/testmp4.mp4";
  24. int mIndex = 0;
  25. String path1 = TEST_PATH;
  26. String[] paths = new String[]{TEST_PATH, TEST_PATH, TEST_PATH, TEST_PATH, TEST_PATH, TEST_PATH};
  27. boolean destory;
  28. Handler mHandler;
  29. Runnable mPlayRun;
  30. FrameLayout content;
  31. TextureView textureView;
  32. ImageView frameImage;
  33. MediaPlayer mediaPlayer;
  34. Bitmap lastFrameBitmap;
  35. public void updateResources(String[] paths) {
  36. this.paths = paths;
  37. if(mHandler != null && mPlayRun!= null){
  38. mHandler.post(mPlayRun);
  39. }
  40. }
  41. @Override
  42. public void onCreate(@Nullable Bundle savedInstanceState) {
  43. super.onCreate(savedInstanceState);
  44. mHandler = new Handler();
  45. mediaPlayer = new MediaPlayer();
  46. mPlayRun = new Runnable() {
  47. @Override
  48. public void run() {
  49. if (mediaPlayer == null || destory) {
  50. return;
  51. }
  52. mediaPlayer.pause();
  53. mediaPlayer.reset();
  54. try {
  55. String path = paths[mIndex % paths.length];
  56. mIndex++;
  57. mediaPlayer.setDataSource(getActivity(), Uri.parse(path));
  58. mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
  59. @Override
  60. public void onPrepared(MediaPlayer arg0) {
  61. mediaPlayer.start();
  62. frameImage.setVisibility(View.GONE);
  63. }
  64. });
  65. mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
  66. @Override
  67. public void onCompletion(MediaPlayer mp) {
  68. frameImage.setVisibility(View.VISIBLE);
  69. Bitmap currentFrameBitmap = textureView.getBitmap();
  70. frameImage.setImageBitmap(currentFrameBitmap);
  71. if (lastFrameBitmap != null) {
  72. lastFrameBitmap.recycle();
  73. }
  74. lastFrameBitmap = currentFrameBitmap;
  75. mHandler.post(mPlayRun);
  76. }
  77. });
  78. mediaPlayer.prepareAsync();
  79. } catch (Exception e) {
  80. e.printStackTrace();
  81. }
  82. }
  83. };
  84. }
  85. public void release() {
  86. mHandler.removeCallbacks(mPlayRun);
  87. if (mediaPlayer != null) {
  88. mediaPlayer.pause();
  89. mediaPlayer.release();
  90. }
  91. }
  92. public Bitmap getBitmap() {
  93. return textureView == null ? null : textureView.getBitmap();
  94. }
  95. @Override
  96. public void onDestroy() {
  97. super.onDestroy();
  98. release();
  99. }
  100. @Nullable
  101. @Override
  102. public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
  103. content = new FrameLayout(getActivity());
  104. FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
  105. lp.gravity = Gravity.LEFT | Gravity.TOP;
  106. textureView = new TextureView(getActivity());
  107. textureView.setLayoutParams(lp);
  108. content.addView(textureView);
  109. frameImage = new ImageView(getActivity());
  110. frameImage.setScaleType(ImageView.ScaleType.FIT_XY);
  111. frameImage.setLayoutParams(lp);
  112. content.addView(frameImage);
  113. textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
  114. @Override
  115. public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
  116. Surface s = new Surface(surface);
  117. mediaPlayer.setSurface(s);
  118. }
  119. @Override
  120. public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
  121. }
  122. @Override
  123. public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
  124. return false;
  125. }
  126. @Override
  127. public void onSurfaceTextureUpdated(SurfaceTexture surface) {
  128. }
  129. });
  130. return content;
  131. }
  132. @Override
  133. public void onActivityCreated(@Nullable Bundle savedInstanceState) {
  134. super.onActivityCreated(savedInstanceState);
  135. testPlay();
  136. }
  137. public void testPlay() {
  138. // mediaPlayer.pause();
  139. // mediaPlayer.reset();
  140. //
  141. // try {
  142. // mediaPlayer.setDataSource(getActivity(), Uri.parse(TEST_PATH));
  143. // mediaPlayer.prepare();
  144. // mediaPlayer.start();
  145. // } catch (IOException e) {
  146. // e.printStackTrace();
  147. // }
  148. mHandler.post(mPlayRun);
  149. }
  150. }

相关链接,github地址

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持w3xue。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号