作为一个练手项目,基于IjkMediaPlayer的仿照腾讯视频风格的播放器,支持全屏缩放,对其中核心的代码做记录。
播放器总体架构如图所示:

player是继承frameLayout,自己内部拥有IjkMediaPlayer的实例,以及做渲染显示用的TextureView,同时player只有一个mContainer子控件,mContainer同样也是一个frameLayout容器,容纳TextureView和Controller;Controller也是继承FrameLayout,并作为容器容纳各个控制控件的容器,内部通过接口和player相关联,控制player,同时也根据player的状态改变自己的界面。实现全屏,就是把mContainer先从player中移除掉,然后把mContainer添加到Activity的android.R.id.content根布局下面,然后隐藏导航栏,这样就实现全屏了。
下面是NiceVideoPlayer的主要代码:
1、初始化Container

 private void init(){mContainer = new FrameLayout(mContext);mContainer.setBackgroundColor(Color.BLACK);LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);this.addView(mContainer,params);}

2、添加并关联播放控制器控件

public void setController(BaseVideoPlayerController controller){mContainer.removeView(mController);mController = controller;mController.reset();controller.setNiceVideoPlayer(this);LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);mContainer.addView(mController,params);}

3、用户点击播放,需要开始准备播放,获取声音焦点

 private void initAudioManager(){mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);mAudioManager.requestAudioFocus(null,AudioManager.STREAM_MUSIC,AudioManager.AUDIOFOCUS_GAIN);}

4、初始化MediaPlayer,这里分IjkMediaPlayer和SDK自带的MediaPlayer

 private void initMediaPlayer(){if(mMediaPlayer == null){if(mPlayerType == TYPE_IJK){mMediaPlayer = new IjkMediaPlayer();}else if(mPlayerType == TYPE_NATIVE){mMediaPlayer = new AndroidMediaPlayer();}mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);}}

5、初始化TextureView,并把TextureView添加到mContainer中,注意是添加到最底层

private void initTextureView(){if(mTextureView == null){mTextureView = new NiceTextureView(mContext);mTextureView.setSurfaceTextureListener(this);  //这里设置监听,在textureview准备好之后进行下一步}}private void addTextureView(){mContainer.removeView(mTextureView);LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT,Gravity.CENTER);mContainer.addView(mTextureView,0,params);}

6、TextureView准备好之后,处理监听回调:

@Overridepublic void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {if(mSurfaceTexture == null){Log.i(TAG,"onSurfaceTextureAvailable");mSurfaceTexture = surfaceTexture;openMediaPlayer();}else{mTextureView.setSurfaceTexture(mSurfaceTexture);}}

7、打开播放器,设置播放所必须的监听器,并且关联textureView的Surface,同时设置播放资源:

private void openMediaPlayer(){//屏幕长量mContainer.setKeepScreenOn(true);//设置监听mMediaPlayer.setOnPreparedListener(mOnPreparedListener);mMediaPlayer.setOnInfoListener(mOnInfoListener);mMediaPlayer.setOnErrorListener(mOnErrorListener);mMediaPlayer.setOnCompletionListener(mOnCompletionListener);mMediaPlayer.setOnVideoSizeChangedListener(mOnVideoSizeChangedListener);mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);//设置资源try {mMediaPlayer.setDataSource(mContext,Uri.parse(mUrl));if(mSurface == null){mSurface = new Surface(mSurfaceTexture);}mMediaPlayer.setSurface(mSurface);mMediaPlayer.prepareAsync();mCurrentState = STATE_PREPARING;mController.onPlayStateChanged(mCurrentState);Log.i(TAG,"播放器准备中");} catch (IOException e) {e.printStackTrace();Log.e(TAG,"打开播放器错误",e);}}

8、 IMediaPlayer.OnPreparedListener播放器异步准备监听

private IMediaPlayer.OnPreparedListener mOnPreparedListener = new IMediaPlayer.OnPreparedListener() {@Overridepublic void onPrepared(IMediaPlayer iMediaPlayer) {mCurrentState = STATE_PREPARED;mController.onPlayStateChanged(mCurrentState);iMediaPlayer.start(); //开始播放}};

9、IMediaPlayer.OnCompletionListener播放完毕的监听

 private IMediaPlayer.OnCompletionListener mOnCompletionListener = new IMediaPlayer.OnCompletionListener() {@Overridepublic void onCompletion(IMediaPlayer iMediaPlayer) {mCurrentState = STATE_COMPLETED;mController.onPlayStateChanged(mCurrentState);//关闭屏幕长亮mContainer.setKeepScreenOn(false);}};

10、这里主要监听播放器开始在TextureView中渲染的信息

 private IMediaPlayer.OnInfoListener mOnInfoListener = new IMediaPlayer.OnInfoListener() {@Overridepublic boolean onInfo(IMediaPlayer iMediaPlayer, int what, int extra) {if(what == IMediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START){//播放器开始渲染画面mCurrentState = STATE_PLAYING;mController.onPlayStateChanged(mCurrentState);}return true;}};

11、 IMediaPlayer.OnBufferingUpdateListener 缓存进度改变的信息

 private IMediaPlayer.OnBufferingUpdateListener mBufferingUpdateListener = new IMediaPlayer.OnBufferingUpdateListener() {@Overridepublic void onBufferingUpdate(IMediaPlayer iMediaPlayer, int i) {mBufferPercent = i; //此数据可以用来更新缓存进度条}};

12、进入全屏的方法:

public void enterFullScreen() {if(mCurrentMode  == MODE_FULL_SCREEN) return;//隐藏状态栏NiceUtil.hideActionBar(mContext);//横屏NiceUtil.getAppCompatActivity(mContext).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);ViewGroup viewGroup = NiceUtil.scanForActivity(mContext).findViewById(android.R.id.content);if(mCurrentMode == MODE_TINY_WINDOW){}else{this.removeView(mContainer);}LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);viewGroup.addView(mContainer,layoutParams);mCurrentMode = MODE_FULL_SCREEN;mController.onPlayModeChanged(mCurrentMode);}

13、退出全屏的操作:

public boolean exitFullScreen() {if(mCurrentMode != MODE_FULL_SCREEN) return false;ViewGroup viewGroup = NiceUtil.getAppCompatActivity(mContext).findViewById(android.R.id.content);viewGroup.removeView(mContainer);LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);this.addView(mContainer,params);//显示状态栏NiceUtil.ShowActionBar(mContext);//竖屏NiceUtil.getAppCompatActivity(mContext).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);mCurrentMode = MODE_NORMAL;mController.onPlayModeChanged(mCurrentMode);return true;}

14、重新onBackPress()方法,如果在全屏的时候,退出全屏

public boolean onBackPress(){if(mCurrentMode == MODE_FULL_SCREEN){return exitFullScreen();}if(mCurrentMode == MODE_TINY_WINDOW){return exitTinyWindow();}return false;}

基于IjkMediaPlayer的播放器相关推荐

  1. 安卓实训项目:基于储存卡音乐播放器实训报告5.0

    安卓实训项目:基于储存卡音乐播放器实训报告5.0 (一)功能要求 在基于存储卡音乐播放器V0.4基础上,作如下修改: 1.创建应用程序常量接口保存广播频道常量 2.在音乐播放器应用程序类里添加两个属性 ...

  2. 安卓实训项目:基于储存卡音乐播放器实训报告4.0

    功能要求 在基于存储卡音乐播放器V0.3基础上,作如下修改: 1.创建方法能扫描存储卡上所有mp3文件(采用递归算法) ----完成 2.用自定义应用程序类存放全局数据和方法 ----完成 3.利用异 ...

  3. 安卓第一阶段实训项目:基于存储卡音乐播放器(更新中……)

    文章目录 一.项目功能要求 二.涉及知识点 三.实现思路 1.基于存储卡音乐播放器V0.1 2.基于存储卡音乐播放器V0.2 3.基于存储卡音乐播放器V0.3 4.基于存储卡音乐播放器V0.4 5.基 ...

  4. 一个简单的基于 DirectShow 的播放器 2(对话框类)

    上篇文章分析了一个封装DirectShow各种接口的封装类(CDXGraph):一个简单的基于 DirectShow 的播放器  1(封装类) 本文继续上篇文章,分析一下调用这个封装类(CDXGrap ...

  5. 一个简单的基于 DirectShow 的播放器 1(封装类)

    DirectShow最主要的功能就是播放视频,在这里介绍一个简单的基于DirectShow的播放器的例子,是用MFC做的,今后有机会可以基于该播放器开发更复杂的播放器软件. 注:该例子取自于<D ...

  6. 基于android音乐播放器的设计

    本科毕业论文(设计)诚信声明 本人郑重声明:所呈交的毕业论文(设计),题目<---基于android音乐播放器的设计----------->是本人在指导教师的指导下,进行研究工作所取得的成 ...

  7. android音乐播放器ppt,基于Android音乐播放器设计与开发.ppt

    基于Android音乐播放器设计与开发 毕业设计 基于Android的音乐播放器 设计与开发 设计概述 研究背景 研究意义 研究目标 系统演示 研究背景 随着Android智能手机的普及,用户越来越能 ...

  8. 基于android的音乐播放器毕业设计,基于android音乐播放器的毕业设计ppt

    <基于android音乐播放器的毕业设计ppt>由会员分享,可在线阅读,更多相关<基于android音乐播放器的毕业设计ppt(29页珍藏版)>请在人人文库网上搜索. 1.1. ...

  9. vue-video-player文档_基于vue-video-player自定义播放器的方法

    基于vue-video-player自定义播放器的方法 发布时间:2019-01-07 发布网站:编程之家 编程之家收集整理的这篇文章主要介绍了基于vue-video-player自定义播放器的方法, ...

最新文章

  1. 阿里技术专家推荐的几个公众号!
  2. 无人驾驶:车道线检测,附代码
  3. 内存数据库服务运营之路
  4. 计算机C语言1000-1099,歷届重庆市计算机二级C语言考试试题及答案.doc
  5. 一个自动完成插件的类(TextBox 版)
  6. MogoH5+基于Hbuilder做ios真机测试
  7. linux拷贝文件时如果想保留文件原有的时间属性,可以使用选项,Linux考试题.doc
  8. C#如何关闭指定进程
  9. flutter学习笔记之Dart-8 问号、双问号、感叹号的理解
  10. CSS:absolute绝对定位
  11. 关于编写公司软件测试规范操作手册计划书
  12. ios开发开发之:关于时间戳转化成时间
  13. HTML初识:网页结构、标签、特殊符号、列表
  14. kettle连接数据库报错:Error connecting to database: (using class org.gjt.mm.mysql.Driver) Could not create
  15. GitHub 上发现的几个好项目
  16. 优链时代荣获“2022 数字技术应用创新奖”|2022世界数字经济大会
  17. 用AI技术分析情商 川普和克林顿谁更胜一筹?
  18. bash: 无法执行二进制文件: 可执行文件格式错误
  19. 51单片机基础之五线四相步进电机
  20. [转]国家税务总局:个税专项附加扣除APP正式启用!(附操作指南)

热门文章

  1. linux系统vi光标移动字符,Linux vi中移动光标命令
  2. #include< >和#include“ ”的区别
  3. 高并发读,高并发写解决方案
  4. 智源社区AI周刊No.101:DeepMind推出AlphaTensor登Nature封面;stateof.ai发布AI情况报告...
  5. 为什么要学习人工智能,人工智能热招的岗位有哪些,工资和学历有哪些关系?
  6. 未来哪些职业最有可能被人工智能替代
  7. 信雅达,一家不尊重应聘者的公司
  8. windows server 2016 开启多用户登陆
  9. (向量空间)概念和法则的人为定义 I
  10. MySQL集群:主从模式