SurfaceView和MediaPlayer学习

该工程采用SurfaceView和MediaPlayer控制本地视频的播放,通过该工程,可以学会SurfaceView和MediaPlayer的基本用法,如:

SurfaceView常用函数有哪些,与MediaPlayer关联起来的方法

MediaPlayer常用函数有哪些,与SurfaceView关联起来的方法

SurfaceView使用时有哪些注意点

SurfaceView核心代码

1. SurfaceView获取

surfaceView = (SurfaceView) findViewById(R.id.surface_view);

2. SurfaceView实现CallBack

surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {

@Override

public void surfaceCreated(SurfaceHolder surfaceHolder) {

Log.d(TAG, "surfaceCreated: setDisplay");

mediaPlayer.setDisplay(surfaceHolder);//MediaPlayer与SurfaceView关联

if(m_isManToPlay) {

m_isManToPlay = false;

mediaPlayer.start();

} else {

if(current_position != 0) {

mediaPlayer.seekTo(current_position);

}

}

}

@Override

public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {

Log.d(TAG, "surfaceChanged: ");

}

@Override

public void surfaceDestroyed(SurfaceHolder surfaceHolder) {//SurfaceView的Surface是画面不在前台时调用

Log.d(TAG, "surfaceDestroyed: "); //TextureView的Surface是画面销毁时调用

}

});

MediaPlayer核心代码

1. 创建MediaPlayer实例

创建时设置播放源,创建完成后,MediaPlayer处于Prepared状态

mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.video_test);

只创建实例,随后设置播放源

mediaPlayer = new MediaPlayer();//MediaPlayer处于Idle状态

try {

mediaPlayer.setDataSource(getAssets().openFd("audio_test.mp3"));//MediaPlayer处于Initialized状态

mediaPlayer.prepareAsync();//MediaPlayer处于Preparing状态

} catch (IOException e) {

e.printStackTrace();

}

2. 实现OnPreparedListener

mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {

@Override

public void onPrepared(MediaPlayer mediaPlayer) {//MediaPlayer处于Prepared状态

Log.d(TAG, "onPrepared: ");

mediaPlayer.seekTo(1);//处理onPrepared时,surface区域黑屏

}

});

3. 开始播放视频

mediaPlayer.start();

4. 暂停播放视频

mediaPlayer.pause();

5. 快进到某一位置

mediaPlayer.seekTo(1);

6. 释放MediaPlayer资源,画面退出时调用

mediaPlayer.release();

常见问题处理

1. 视频播放时,SurfaceView区域黑屏

MediaPlayer设置SurfaceHolder时,该SurfaceHolder未创建,需要在surfaceCreated回调之后,MediaPlayer才可以与SurfaceView关联

2. 视频播放时,SurfaceView正常显示,视频暂停后画面切入后台,再切回前台,SurfaceView区域黑屏

画面切入后台,SurfaceView销毁(surfaceDestroyed),移入前台时,SurfaceView新建(surfaceCreated),SurfaceView新建时会先将背景绘制成黑色,由于MediaPlayer一直处于暂停状态,没有状态更新,SurfaceView背景保持黑色,解决方法:画面切入后台时,记录当前播放进度,画面再次切入前台时,SurfaceView新建后,MediaPlayer调用seekTo至记录的进度

3. 视频播放时,SurfaceView正常显示,画面切入后台,视频有声音,再切回前台,播放进度无法保存

画面切入后台时,SurfaceView销毁,此时mediaPlayer仍处于播放状态,再切回前台,视频继续播放,解决方法:画面切入后台时,记录当前的播放时间并且暂停播放,画面切回前台后,当SurfaceView新建后,调用MediaPlayer的start接口继续播放

知识点

MediaPlayer工作流程

首先创建MediaPlaer对象new MediaPlayer()或者MediaPlayer.create(this, R.raw.test)指定播放文件

然后调用setDataSource()方法来设置音视频频文件的路径(如果调用MediaPlayer.create,则该步骤不需要)

再调用prepare()方法使MediaPlayer进入到准备状态(如果调用MediaPlayer.create,则该步骤不需要)

调用start方法就可以播放音频

MediaPlayer状态机

SurfaceView工作原理

SurfaceView创建一个置于应用窗口之后的新窗口,好像在视图层次(View Hierarchy)上穿了个"洞",让绘图层(Surface)直接显示出来,SurfaceView窗口刷新时不需要重绘应用程序的窗口,所以这种方式的效率非常高。但是SurfaceView也有一些非常不便的限制,因SurfaceView的内容不在应用窗口上,所以不能使用平移、缩放、旋转等变换操作,也难以放在ListView或者ScrollView中,同样不能使用UI控件的一些特性,比如View.setAlpha()

SurfaceView的双缓冲机制

SurfaceView在更新视图时用了两张Canvas,一张frontCanvas和一张backCanvas,每次显示的是frontCanvas,backCanvas存储的是上一次更改前的视图,当使用lockCanvas()获取画布时,得到的是backCanvas而不是正在显示的frontCanvas,之后在获取到的backCanvas上绘制新视图,再unlockCanvasAndPost(canvas)此视图,那么上传的这张canvas将替换原来的frontCanvas作为新的frontCanvas,原来的frontCanvas将切换到后台作为backCanvas。例如,如果你已经先后两次绘制了视图A和B,那么你再调用lockCanvas()获取视图,获得的将是A而不是正在显示的B,之后你讲重绘的C视图上传,那么C将取代B作为新的frontCanvas显示在SurfaceView上,原来的B则转换为backCanvas。

android surfaceview的简单使用,surfaceview_learn相关推荐

  1. android surfaceview的简单使用,Android SurfaceView的基本使用

    一.为什么要SurfaceView 大多数情况下我们的自定义View都会选择去继承View或ViewGroup来实现,但是为什么系统还要为我们提供一个SurfaceView呢? 首先我们知道View类 ...

  2. 详解与重构hyman《Android SurfaceView实战 打造抽奖转盘》

    详解与重构hyman<Android SurfaceView实战 打造抽奖转盘> 作者:邵励治 一.概述--关于SurfaceView您不得不知道的二三事 1.SurfaceView是干什 ...

  3. Android SurfaceView实战 带你玩转flabby bird (下)

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/43063331,本文出自:[张鸿洋的博客] 1.概述 在Android Surfa ...

  4. Android SurfaceView实战 带你玩转flabby bird (上)

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 转载请标 ...

  5. Android SurfaceView实战 带你玩转flabby bird

    分析 仔细观察游戏,需要绘制的有:背景.地板.鸟.管道.分数: 游戏开始时: 地板给人一种想左移动的感觉: 管道与地板同样的速度向左移动: 鸟默认下落: 当用户touch屏幕时,鸟上升一段距离后,下落 ...

  6. OpenGL.ES在Android上的简单实践:20-水印录制(预览+透明水印 表情 弹幕 gl_blend)

    OpenGL.ES在Android上的简单实践:20-水印录制(预览 gl_blend) 1.继续画出预览帧 紧接着上篇文章,既然是要画出预览帧,按照之前其他项目的架构组成.我们是通过模型FrameR ...

  7. android实现计算器功能吗,利用Android实现一个简单的计算器功能

    利用Android实现一个简单的计算器功能 发布时间:2020-11-20 16:25:01 来源:亿速云 阅读:90 作者:Leah 今天就跟大家聊聊有关利用Android实现一个简单的计算器功能, ...

  8. Android开发环境简单配置

    为什么80%的码农都做不了架构师?>>>    ·         Android开发环境简单配置 写这个系列的原因也是因为自己对android比较感兴趣,而网上多数教程都是直接参照 ...

  9. 文件管理器android实现,Android开发之简单文件管理器实现方法

    易采站长站为您分析Android开发之简单文件管理器实现方法,简单实现了Android的文件目录查看,文件重命名,打开,删除等功能,需要的朋友可以参考下 本文实例讲述了Android开发之简单文件管理 ...

最新文章

  1. TOJ-1036.Rails STL-栈
  2. 手把手教你搭建Linux开发环境(VMware+Ubuntu)(四)——gcc编译器的安装和使用
  3. c# 获取machineguid_C#中怎么生成和获取GUID
  4. python 多线程笔记(6)-- 闭包
  5. MySQL使用详解--根据个人学习总结
  6. 制作斜坡单元的两种方法
  7. mysql 5.6 dmr_CentOS下mysql5.6升级5.7指南
  8. 支持向量机: Maximum Margin Classifier
  9. 如何判断lib是/md or /mt编译的
  10. typecho怎么用html编写文章,为Typecho文章增加HTML标签支持
  11. 独立看门狗及其实现的热启动
  12. matlab和pspice,电力电子电路仿真---MATLAB和PSpice应用
  13. TP框架打印输出原生sql语句
  14. 无网络环境下HTCVive VR设备运行环境搭建
  15. 跑马灯带你深入浅出TextView的源码世界
  16. 【学习】无刷直流电机的基本结构及工作原理
  17. Linked Data_百度百科
  18. 跳槽穷半年,转行穷三年,死守会穷一辈子
  19. python内置函数返回元素个数_Python内置函数
  20. 想问题思路总是不清晰,这个好用的脑图工具推荐给你

热门文章

  1. HTML元素居中(文字居中,块居中【垂直/水平居中】)
  2. c语言休眠函数 vs,编纂C语言跨平台函数(以清屏和休眠函数为例)
  3. Moravec(莫拉维克)影像特征点提取(含原理与C代码)
  4. [春秋云镜wp]CVE-2022-28060 CVE-2022-26201 Victor CMS v1.0存在sql注入漏洞复现拿flag
  5. Python入门——变量
  6. Python练习:阶乘求和
  7. 完美实现刮刮乐抽奖(该有的都有),html+css+jquery实现
  8. 【图形学】基于点云生成树木模型
  9. 做算法工程师是什么样的工作体验
  10. 在matlab中打开mat文件