最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android使用MediaPlayer和TextureView實(shí)現(xiàn)視頻無縫切換

 更新時間:2019年10月09日 10:13:11   作者:Winson_Zhou  
這篇文章主要為大家詳細(xì)介紹了Android使用MediaPlayer和TextureView實(shí)現(xiàn)視頻無縫切換,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下

需求描述

比如廣告播放,每個視頻15秒,視頻之間切換的時候,性能不太好的機(jī)器可能會黑屏一段時間,體驗(yàn)不太好,接下來我們就是要解決這個黑屏問題。

解決方案

使用兩個surfaceView方式,經(jīng)過測試不行
使用一個MediaPlayer,在MediaPlayer上面加一層ImageView,每次播放完成后,獲取視頻的最后一幀的圖像給ImageView,視頻切換完成,ImageView隱藏,如此往復(fù)循環(huán),可行

實(shí)踐

1.獲取視頻流圖片方式,通過MediaMetadataRetriever,測試發(fā)現(xiàn),部分機(jī)器獲取的Bitmap可能為空,無法解決,放棄

2.使用TextureView方式,可以獲取當(dāng)前幀的Bitmap,可行,下面貼代碼

package com.winson.blog.video;
 
import android.graphics.Bitmap;
import android.graphics.SurfaceTexture;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
 
import java.io.IOException;
 
public class VideoFragment extends Fragment {
 
 public static final String TAG = VideoFragment.class.getSimpleName();
 
 String TEST_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/testmp4.mp4";
 int mIndex = 0;
 String path1 = TEST_PATH;
 String[] paths = new String[]{TEST_PATH, TEST_PATH, TEST_PATH, TEST_PATH, TEST_PATH, TEST_PATH};
 
 boolean destory;
 Handler mHandler;
 Runnable mPlayRun;
 FrameLayout content;
 TextureView textureView;
 ImageView frameImage;
 MediaPlayer mediaPlayer;
 Bitmap lastFrameBitmap;
 
 public void updateResources(String[] paths) {
 this.paths = paths;
 if(mHandler != null && mPlayRun!= null){
  mHandler.post(mPlayRun);
 }
 }
 
 @Override
 public void onCreate(@Nullable Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 
 mHandler = new Handler();
 mediaPlayer = new MediaPlayer();
 mPlayRun = new Runnable() {
 
  @Override
  public void run() {
 
  if (mediaPlayer == null || destory) {
   return;
 
  }
  mediaPlayer.pause();
  mediaPlayer.reset();
 
  try {
   String path = paths[mIndex % paths.length];
   mIndex++;
 
   mediaPlayer.setDataSource(getActivity(), Uri.parse(path));
   mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
 
   @Override
   public void onPrepared(MediaPlayer arg0) {
    mediaPlayer.start();
    frameImage.setVisibility(View.GONE);
   }
   });
   mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
   @Override
   public void onCompletion(MediaPlayer mp) {
    frameImage.setVisibility(View.VISIBLE);
    Bitmap currentFrameBitmap = textureView.getBitmap();
    frameImage.setImageBitmap(currentFrameBitmap);
    if (lastFrameBitmap != null) {
    lastFrameBitmap.recycle();
    }
    lastFrameBitmap = currentFrameBitmap;
 
    mHandler.post(mPlayRun);
   }
   });
   mediaPlayer.prepareAsync();
 
  } catch (Exception e) {
   e.printStackTrace();
  }
  }
 
 };
 }
 
 
 public void release() {
 mHandler.removeCallbacks(mPlayRun);
 if (mediaPlayer != null) {
  mediaPlayer.pause();
  mediaPlayer.release();
 }
 }
 
 public Bitmap getBitmap() {
 return textureView == null ? null : textureView.getBitmap();
 }
 
 @Override
 public void onDestroy() {
 super.onDestroy();
 release();
 }
 
 @Nullable
 @Override
 public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
 content = new FrameLayout(getActivity());
 
 FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
 lp.gravity = Gravity.LEFT | Gravity.TOP;
 
 textureView = new TextureView(getActivity());
 textureView.setLayoutParams(lp);
 content.addView(textureView);
 
 frameImage = new ImageView(getActivity());
 frameImage.setScaleType(ImageView.ScaleType.FIT_XY);
 frameImage.setLayoutParams(lp);
 content.addView(frameImage);
 
 textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
  @Override
  public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
  Surface s = new Surface(surface);
  mediaPlayer.setSurface(s);
 
  }
 
  @Override
  public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
  }
 
  @Override
  public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
  return false;
  }
 
  @Override
  public void onSurfaceTextureUpdated(SurfaceTexture surface) {
  }
 });
 
 return content;
 }
 
 @Override
 public void onActivityCreated(@Nullable Bundle savedInstanceState) {
 super.onActivityCreated(savedInstanceState);
 
 testPlay();
 }
 
 public void testPlay() {
// mediaPlayer.pause();
// mediaPlayer.reset();
//
// try {
//  mediaPlayer.setDataSource(getActivity(), Uri.parse(TEST_PATH));
//  mediaPlayer.prepare();
//  mediaPlayer.start();
// } catch (IOException e) {
//  e.printStackTrace();
// }
 
 mHandler.post(mPlayRun);
 }
 
 
}

相關(guān)鏈接,github地址

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Flutter軟鍵盤的原理淺析

    Flutter軟鍵盤的原理淺析

    大家應(yīng)該都知道目前Flutter官方是沒有自定義鍵盤的解決方案,下面這篇文章主要給大家介紹了關(guān)于Flutter軟鍵盤原理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-10-10
  • Android APP檢測實(shí)體按鍵事件詳解

    Android APP檢測實(shí)體按鍵事件詳解

    這篇文章主要為大家詳細(xì)介紹了Android APP檢測實(shí)體按鍵事件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • Android TabHost組件使用方法詳解

    Android TabHost組件使用方法詳解

    這篇文章主要以實(shí)例講解的方式為大家詳細(xì)介紹了Android TabHost組件的使用方法,感興趣的小伙伴們可以參考一下
    2016-05-05
  • Android實(shí)現(xiàn)通用篩選欄

    Android實(shí)現(xiàn)通用篩選欄

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)通用篩選欄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • Android中正確使用字體圖標(biāo)(iconfont)的方法

    Android中正確使用字體圖標(biāo)(iconfont)的方法

    IconFont字體不僅僅流行于Web開發(fā),在移動開發(fā)中也漸漸的使用的范圍更廣泛。這篇文章主要介紹了在Android開發(fā)中使用icon font的代碼和方法。對大家學(xué)習(xí)使用iconfont有一定的參考借鑒價值,有需要的朋友們下面來一起看看吧。
    2016-10-10
  • Android遍歷所有文件夾和子目錄搜索文件

    Android遍歷所有文件夾和子目錄搜索文件

    為了準(zhǔn)確搜索文件,大家可以采取什么方法查找文件,本文為大家介紹Android遍歷所有文件夾和子目錄實(shí)現(xiàn)文件搜索功能,感興趣的小伙伴們可以參考一下
    2016-07-07
  • Android自定義View實(shí)現(xiàn)簡單文字描邊功能

    Android自定義View實(shí)現(xiàn)簡單文字描邊功能

    這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)簡單文字描邊功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • 談?wù)剬ndroid View事件分發(fā)機(jī)制的理解

    談?wù)剬ndroid View事件分發(fā)機(jī)制的理解

    本篇文章主要介紹了談?wù)剬ndroid View事件分發(fā)機(jī)制的理解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • android 開發(fā)中使用okhttp上傳文件到服務(wù)器

    android 開發(fā)中使用okhttp上傳文件到服務(wù)器

    在開發(fā)android手機(jī)客戶端,常常會需要上傳文件到服務(wù)器,使用okhttp會是一個很好的選擇,它使用很簡單,而且運(yùn)行效率也很高,下面小編給大家?guī)砹薬ndroid 開發(fā)中使用okhttp上傳文件到服務(wù)器功能,一起看看吧
    2018-01-01
  • Android四大組件之Activity詳細(xì)介紹

    Android四大組件之Activity詳細(xì)介紹

    大家好,本篇文章主要講的是Android四大組件之Activity詳解,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12

最新評論

石景山区| 商丘市| 丹阳市| 平和县| 八宿县| 玉山县| 峡江县| 乐都县| 晋州市| 分宜县| 新泰市| 增城市| 京山县| 民和| 怀仁县| 武夷山市| 天台县| 内丘县| 凉城县| 泾川县| 清新县| 七台河市| 盘锦市| 工布江达县| 湖南省| 姚安县| 诸城市| 周至县| 缙云县| 汉阴县| 鹰潭市| 巴塘县| 乌海市| 石首市| 察隅县| 鄂托克旗| 北海市| 南木林县| 赣州市| 岑溪市| 中山市|