需求描述

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

解决方案

使用两个surfaceView方式,经过测试不行

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

实践

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

2.使用TextureView方式,可以获取当前帧的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);

}

}

相关链接,github地址

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

android无缝切换播放器,Android使用MediaPlayer和TextureView实现视频无缝切换相关推荐

  1. 视频教程-FFmpeg打造Android万能音频播放器-Android

    FFmpeg打造Android万能音频播放器 从事Android移动端开发多年.主导开发过直播.电商.聊天等各种类型APP和游戏SDK:熟悉Android音视频开发.底层NDK开发等:有开源项目:ht ...

  2. android仿音乐播放器,Android仿音乐播放器功能

    本文实例为大家分享了Android仿音乐播放器功能的具体代码,供大家参考,具体内容如下 读取本地音乐文件 源代码: import android.media.MediaPlayer; import a ...

  3. android无缝切换播放器,android 视频 无缝切换 无缝播放 surfaceview

    android 视频 无缝切换 无缝播放 surfaceview 最近做一个app,其中有一个控件要不断的播放视频,切换视频,然后遇到每次切换视频都会黑屏一会. baidu,google没有找到有效的 ...

  4. android 小卷毛播放器,Android 音乐播放器的开发教程(四)Activity和Fragment的通信以及Fragment的切换 ----- 小达...

    Activity和Fragment的通信以及Fragment的切换 在上一篇的博客中讲到了,播放器的主界面布局,是由一个activity和一个fragment构成的,activity启动的时候,在其o ...

  5. android开发音乐播放器,Android开发简易音乐播放器

    这里介绍一个简易的音乐播放器,供大家参考,具体内容如下 效果图如下: 但是,由于这是一个简易版的音乐播放器,所播放的音乐只有一首,且被写死,但,操作却十分简单,方便理解! 这是代码的主要设计: 音乐主 ...

  6. 旧android手机当播放器,android手机立即变无线移动终端播放器 Qloud media 详细教程...

    Ubuntu终端播放器-mocp    作为Linux企业应用管理和维护,常需要putty远程连接维护服务器.Python开发. private void play(long position)// ...

  7. android浮窗播放器,Android仿优酷视频的悬浮窗播放效果

    之前接了需求要让视频播放时可以像优酷视频那样在悬浮窗里播放,并且悬浮窗和主播放页面之间要实现无缝切换,项目中使用的是自封装的ijkplayer 这个要求就代表不能在悬浮窗中新建视频控件,所以需要在悬浮 ...

  8. android智能语音播放器,android IM模块-语音-播放篇1

    MediaPlayer MediaPlayer是我们经常用的一个音频播放类 创建的方式有很多种,可以直接new一个,也可以直接调用MediaPlayer.creat(xxx) 常用API有如下 voi ...

  9. Android调用uc播放器,android 视频播放 -- 调用系统播放器

    android 视频播放,视频来源有两种:一种是本地视频,一种是网络视频,对android播放来说都统一用uri来表示. 播放视频有三种处理方式: (1) 使用webview 播放 (2) 使用vid ...

最新文章

  1. hdu 2065DP
  2. ttcp 之测试网络性能
  3. python快速入门 pdf-Python快速入门 (第3版) PDF 下载
  4. Win7 IIS7.5运行ASP时出现500错误的解决办法
  5. 重拾IP路由选择:CCNA学习指南中的IP路由选择
  6. 大剑无锋之拦截器和过滤器的区别【面试推荐】
  7. c++ 函数参数问题
  8. 从零开始写个编译器吧 - 程序流控制
  9. 基于bootstrap table配置的二次封装
  10. HTML5方式使用freeswitch——VERTO模块
  11. 软著申请说明书及源程序模板
  12. SpringCloud Alibaba实战第三课 Gateway、Sentinel实战
  13. windows nginx 搭建 图片服务器
  14. oracle select into from 用法,sql select into用法
  15. 如何使用计算机求和公式,excel求和公式怎么用
  16. HDR(高动态范围)
  17. Fabric chaincode shim.ChaincodeStubInterface
  18. 人脸识别有趣应用3——抠出人脸并给人脸涂上戏剧脸谱
  19. leetcode奇技淫巧-递归中途强制跳出
  20. 6个不亚于公务员的职业选择

热门文章

  1. c语言驱动程序开发基础教程,C 语言入门介绍
  2. 从项目管理角度谈OA流程优化
  3. TI AM5728 DSP+ARM多核通信开发例程
  4. 南开大学和华科计算机考研哪个好,都是985名校,南开大学和天津大学,哪个更值得上?...
  5. CentOS 7下ngrok服务器搭建
  6. CentOS7 NGROK服务器搭建 无需域名
  7. SpringBoot:SLF4j的使用
  8. ArduBlock 多久没更新了-安装很简单on mac
  9. libjpeg用法linux压缩,使用libjpeg对图像进行压缩
  10. html网页显示蒙文,网页标签中显示蒙古文竖排文本