android 视频 无缝切换 无缝播放 surfaceview

最近做一个app,其中有一个控件要不断的播放视频,切换视频,然后遇到每次切换视频都会黑屏一会。

baidu,google没有找到有效的解决方案。经过n轮的测试,终于搞定了。

下面是代码。

package com.github.neowen.apibasedemo.csdn.circle_media;

import android.media.MediaPlayer;

import android.net.Uri;

import android.os.Bundle;

import android.os.Environment;

import android.os.Handler;

import android.support.v7.app.AppCompatActivity;

import android.util.Log;

import android.view.Gravity;

import android.view.SurfaceHolder;

import android.view.SurfaceView;

import android.view.View;

import android.widget.FrameLayout;

import java.io.File;

/** * Created by Winson on 2016/1/4. */

public class CircleNoBlackVideoActivity extends AppCompatActivity {

public static final String TAG = CircleNoBlackVideoActivity.class.getSimpleName();

public static String path1 = Environment.getExternalStorageDirectory() + File.separator + "test.mp4";

public static String path2 = Environment.getExternalStorageDirectory() + File.separator + "test.mp4";

public static String path3 = Environment.getExternalStorageDirectory() + File.separator + "test.mp4";

public static int DURATION = 15000;

public static String[] paths = new String[]{path1, path2, path3};

SurfaceView mVideoSurface, mNextSurface;

FrameLayout mFrame;

MediaPlayer mCurrentMediaPlayer, mNextMediaPlayer;

Handler mHandler;

int mIndex = 0;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

mFrame = new FrameLayout(this);

setContentView(mFrame);

mHandler = new Handler();

mCurrentMediaPlayer = new MediaPlayer();

mNextMediaPlayer = new MediaPlayer();

mVideoSurface = new SurfaceView(this);

mVideoSurface.getHolder().addCallback(new VideoSurfaceHodlerCallback());

mNextSurface = new SurfaceView(this);

mNextSurface.getHolder().addCallback(new NextVideoSurfaceHodlerCallback());

FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(

700,

500);

lp.gravity = Gravity.LEFT | Gravity.TOP;

mVideoSurface.setLayoutParams(lp);

lp = new FrameLayout.LayoutParams(

700,

500);

lp.gravity = Gravity.LEFT | Gravity.TOP;

mNextSurface.setLayoutParams(lp);

mFrame.addView(mNextSurface);

mFrame.addView(mVideoSurface);

mHandler.postDelayed(mPlayRun, 2000);

}

@Override

protected void onDestroy() {

super.onDestroy();

mHandler.removeCallbacks(mPlayRun);

if (mCurrentMediaPlayer != null) {

mCurrentMediaPlayer.release();

mCurrentMediaPlayer = null;

}

if (mNextMediaPlayer != null) {

mNextMediaPlayer.release();

mNextMediaPlayer = null;

}

}

Runnable mPlayRun = new Runnable() {

@Override

public void run() {

mCurrentMediaPlayer.pause();

mNextMediaPlayer.pause();

mNextMediaPlayer.reset();

try {

if (mIndex == 0) {

String path = paths[mIndex % paths.length];

mIndex++;

mCurrentMediaPlayer.setDataSource(CircleNoBlackVideoActivity.this, Uri.parse(path));

mCurrentMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {

@Override

public void onPrepared(MediaPlayer arg0) {

mCurrentMediaPlayer.start();

mCurrentMediaPlayer.stop();

mVideoSurface.setVisibility(View.GONE);

}

});

mCurrentMediaPlayer.prepareAsync();

mNextMediaPlayer.setDataSource(CircleNoBlackVideoActivity.this, Uri.parse(path));

mNextMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {

@Override

public void onPrepared(MediaPlayer arg0) {

mNextMediaPlayer.start();

Log.d("Tag", "new duration : " + mNextMediaPlayer.getDuration());

mHandler.postDelayed(mPlayRun, DURATION);

}

});

mNextMediaPlayer.prepareAsync();

} else {

String path = paths[mIndex % paths.length];

mIndex++;

mNextMediaPlayer.setDataSource(CircleNoBlackVideoActivity.this, Uri.parse(path));

mNextMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {

@Override

public void onPrepared(MediaPlayer arg0) {

mNextMediaPlayer.start();

Log.d("Tag", "new duration : " + mNextMediaPlayer.getDuration());

mHandler.postDelayed(mPlayRun, DURATION);

}

});

mNextMediaPlayer.prepareAsync();

}

} catch (Exception e) {

e.printStackTrace();

}

}

};

class VideoSurfaceHodlerCallback implements SurfaceHolder.Callback {

@Override

public void surfaceChanged(

SurfaceHolder holder,

int format, int width, int height) {

}

@Override

public void surfaceCreated(SurfaceHolder holder) {

mCurrentMediaPlayer.setDisplay(mVideoSurface.getHolder());

}

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

}

}

class NextVideoSurfaceHodlerCallback implements SurfaceHolder.Callback {

@Override

public void surfaceChanged(

SurfaceHolder holder,

int format, int width, int height) {

}

@Override

public void surfaceCreated(SurfaceHolder holder) {

mNextMediaPlayer.setDisplay(mNextSurface.getHolder());

}

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

}

}

}

总的实现思路是:用两个mediaPlayer 两个 surfaceView .

首先让一个mediaplayer 播一个视频,一般播一个小视频,这样不占资源,这个mediaplayer播放的时候,让他stop在这里,

可以让这个mediaplayer 隐藏掉 ,注意不要reset或者release这个mediaplayer 。然后可以让另外一个mediaplyer 播放视频, 这个时候这个mediaplayer 切换视频资源的时候就不会出现黑屏的现象。

这里我只用mediaplayer 来实现,videoview 应该也可以用这种方法来实现 。

使用上面的java代码就可以实现效果了,替换一下路径,资源最好在10s以上,测试效果好

android无缝切换播放器,android 视频 无缝切换 无缝播放 surfaceview相关推荐

  1. android ffmpeg 仿剪映播放器 剪辑视频 预览条 快速精准抽帧

    android ffmpeg 仿剪映播放器 剪辑视频 预览条 快速精准抽帧 由于本人想学习音视频相关的东西,所以找了剪映作为借鉴,通过仿照剪映的功能学习音视频相关的东西,所以有了这个项目 暂时这个项目 ...

  2. android m3u8离线播放器,android上实现离线缓存播放加密HLS视频和未加密的HLS视频...

    1.首先什么是HLS格式的视频,大家去谷歌下就知道了. 2.我们知道HLS格式的视频,只有安卓4.0以上才支持,目前基本4.0一下的机子基本可以考虑,不兼容了,所以为了减少工作量,就没有打算使用三方的 ...

  3. android 优酷 自动全屏播放,Android如何实现仿优酷视频的悬浮窗播放效果

    Android如何实现仿优酷视频的悬浮窗播放效果 发布时间:2020-07-11 10:24:43 来源:亿速云 阅读:228 作者:清晨 这篇文章主要介绍Android如何实现仿优酷视频的悬浮窗播放 ...

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

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

  5. android 带记忆功能的播放器源码,【全开源可二开】带后台管理面板的在线音乐播放器Android应用APP源码...

    这是一款带后台管理面板的在线音乐播放器Android应用APP源码,可让您更快地构建在线和离线android音频播放器,代码全开源适合二次开发.该源码自带2个紫色和橙色主题(允许您添加更多主题),多语 ...

  6. android全格式多媒体播放器,Android多媒体应用使用MediaPlayer播放音频

    Android提供了对常用音频和视频格式的支持,它所支持的音频格式有MP3(.mp3).3GPP(.3gp).Ogg(.ogg)和WAVE(.ave)等,支持的视频格式有3GPP(.3gp)和MPEG ...

  7. C#Winform+WindowsAPI做个剪贴板无缝自动保存器(视频截图利器)

    C#Winform+WindowsAPI做个剪贴板无缝自动保存器(视频截图利器) (本文最新代码已上传到GitHub,地址在(https://github.com/bitzhuwei/Clipboar ...

  8. android html5播放器,android Html5播放器混音解决方案

    背景 当一个用户正在听音乐而另一个应用需要通知用户一些重要的事情时,用户可能由于音乐声音大而不能听的通知.从Android2.2开始,平台为应用提供了一个协商它们如何使用设备音频输出的途径,这个机制叫 ...

  9. MusicPlayer音乐播放器Android

    MusicPlayer音乐播放器Android [音频采集] 你可以使用手机进行现场录音,实现步骤如下: 第一步:在功能清单文件AndroidManifest.xml中添加音频刻录权限: <us ...

  10. 音乐播放器android版,Android版音乐播放器

    音乐播放器是一个非常常见的应用,这篇博客就是介绍如何制作一个简单的音乐播放器,这款音乐播放器具有以下的功能:播放歌曲.暂停播放歌曲..显示歌曲的总时长.显示歌曲的当前播放时长.调节滑块可以将歌曲调节到 ...

最新文章

  1. 【Django】模型层说明
  2. imitativesimulate
  3. 进击的UI---------------------UIStepper(加减)
  4. SpringMVC框架--学习笔记(下)
  5. 初中计算机学情分析,初中信息技术教学计划
  6. oraclde存储过程_Oracle存储过程详解(引用)+补充
  7. Asp.NET Core 一个接口的多个实现如何通过 DI 注册?
  8. MySQL事务管理+安全管理+MySQL数据类型
  9. centos7下编译openjdk11
  10. Python获取同目录下json文件内容
  11. 12种获取节点和元素的代码
  12. 遍历QListWidget的item
  13. Java的值类型(基本类型)和引用类型
  14. idea中有些类明明在jar包里有,但是却搜不到
  15. 微信小程序在聊天中如何插入表情?
  16. java web 页面布局框架_jsp框架(jsp实现页面框架布局)
  17. 戴尔服务器预装系统如何降级,在戴尔计算机上降级系统BIOS | Dell 中国
  18. Aggressive cows
  19. IE浏览器插件ActiveX的制作以及Google 调用此插件
  20. Forbidden什么意思

热门文章

  1. 【Elasticsearch】Elasticsearch bouncing result 问题
  2. 【Java】国外大神总结的 10 个 Java 编程技巧!
  3. 【Kafka】A broker is already registered on the path /brokers/ids/0. This probably indicates that you
  4. 缓存中间件-Memcache命令介绍
  5. 【Java SE:抽象类】抽象类的引出与深入理解
  6. 知己知彼:一篇来自前端同学对后端接口的吐槽!
  7. Flask自定义错误页面的方法
  8. php数据库字段设置长度,javascript - 表单字符长度与数据库字段长度
  9. Docker的Hadoop-Hbase的 Docker Hub文档
  10. MySQL高级-内存管理及优化