上一篇文章我们主要讲了视频播放器开发之前需要准备的一个知识,TextureView,用于对图像流的处理。这篇文章开始构建一个基础的视频播放器。

一、准备工作

在之前的文章已经说过了,播放器也是一个view,我们要在这个view上播放视频流。所以我们要自定义一个简单的viewgroup,比如继承FrameLayout。还出就是布局简单,其他控件可以往上面添加。大家见过的视频播放器的控制器都是放在视频的上方的。这样就是用FrameLayout布局是最好的。

class SmallVideoPlayer extends FrameLayout

二、初始化TextureView

这是一个用于承载显示‘数据流’的View,它不会创建新的窗口来显示内容。它是将内容流直接投放到View中,并且可以和其它普通View一样进行移动,旋转,缩放,动画等变化。
TextureView初始化方式如下,并且我们这个播放器View要实现其监听方法:

class SmallVideoPlayer extends FrameLayout implements TextureView.SurfaceTextureListenerprivate void initTextureView() {if (mTextureView == null) {mTextureView = new TextureView(mContext);mTextureView.setSurfaceTextureListener(this);}}

然后我们把这个TextureView添加到我们的视频播放器的view上,并且设置跟视频播放器View一样大小:

    private void addTextureView() {removeView(mTextureView);LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT,Gravity.CENTER);addView(mTextureView, 0, params);}

三、初始化播放器内核

一个公司想要实现机的播放器内核需要一定的成本,所以大部分公司都选择使用第三方的内核,比如bilibili开源的ijkplayer。ijkplayer是一个基于FFmpeg的轻量级Android/iOS视频播放器。FFmpeg的是全球领先的多媒体框架,能够解码,编码,转码,复用,解复用,流,过滤器和播放大部分的视频格式。它提供了录制、转换以及流化音视频的完整解决方案。这里我们也用它。

在项目module的gradle里面添加依赖:

    implementation 'tv.danmaku.ijk.media:ijkplayer-java:0.8.3'implementation 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.3'implementation 'tv.danmaku.ijk.media:ijkplayer-armv5:0.8.3'implementation 'tv.danmaku.ijk.media:ijkplayer-x86:0.8.3'

编译成功之后我们就可以在代码里面用它了,这个也很简单一般不会出什么问题。ijplayer里面提供了一个IMediaPlayer,我们初始化它即可:

    private void initMediaPlayer() {if (mMediaPlayer == null) {mMediaPlayer = new IjkMediaPlayer();mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);}}

准备工作都做好了,我们要在什么时候开始播放呢?当然是TextureView准备好之后就可以播放了,TextuerView的draw方法中会调用TextureLayer layer = getTextureLayer();方法,而getTextureLayer()这个方法中当surface创建成功之后会执行我们实现的接口方法:

 if (mListener != null && createNewSurface) {mListener.onSurfaceTextureAvailable(mSurface, getWidth(), getHeight());}

从上面代码可以看出当我们设置了mListener,并且创建surface成功之后会为我们回调onSurfaceTextureAvailable方法,并传递给我们一个mSurface及其宽高。那我们在这个方法里播放视频就可以了:

    @Overridepublic void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {if (mSurfaceTexture == null) {mSurfaceTexture = surface;openMediaPlayer();} else {mTextureView.setSurfaceTexture(mSurfaceTexture);}}

我们自己创建一个SurfaceTexture对象存储TextureView给我传递的SurfaceTexture对象,然后开启视频播放。如果你自己实现了SurfaceTexture,你也可以用你自己的。

    private void openMediaPlayer() {// 屏幕常亮setKeepScreenOn(true);// 设置dataSourcetry {mMediaPlayer.setDataSource(mContext.getApplicationContext(), Uri.parse(mUrl));if (mSurface == null) {mSurface = new Surface(mSurfaceTexture);}mMediaPlayer.setSurface(mSurface);mMediaPlayer.prepareAsync();} catch (IOException e) {e.printStackTrace();}}

使用ijplayer播放视频很简单,只要为其设置数据源即可。但是为了能让视频显示出来,也就是能在view上播放出来,我们需要使用Surface。
创建对象private Surface mSurface;,传入刚才存储的SurfaceTexture对象:mSurface = new Surface(mSurfaceTexture);,然后把这个surface对象传递给播放器即可,最后使用播放器开始播放,注意这个方法是同步的。
完成以上步骤,简单的视频播放器就可以完成了。

代码:
我们把代码进行整理如下:

播放器

public class SmallVideoPlayer extends FrameLayout implements TextureView.SurfaceTextureListener {private TextureView mTextureView;private SurfaceTexture mSurfaceTexture;private Surface mSurface;private AudioManager mAudioManager;private IMediaPlayer mMediaPlayer;private Context mContext;private String mUrl;public SmallVideoPlayer(@NonNull Context context) {this(context, null);}public SmallVideoPlayer(@NonNull Context context, @Nullable AttributeSet attrs) {this(context, attrs, -1);}public SmallVideoPlayer(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);this.mContext = context;}public void setUp(String url) {mUrl = url;}public void start() {initAudioManager();initMediaPlayer();initTextureView();addTextureView();}private void initAudioManager() {if (mAudioManager == null) {mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {mAudioManager.requestAudioFocus(new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN).build());} else {mAudioManager.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);}}}private void initMediaPlayer() {if (mMediaPlayer == null) {mMediaPlayer = new IjkMediaPlayer();mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);}}private void initTextureView() {if (mTextureView == null) {mTextureView = new TextureView(mContext);mTextureView.setSurfaceTextureListener(this);}}private void addTextureView() {removeView(mTextureView);LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT,Gravity.CENTER);addView(mTextureView, 0, params);}@Overridepublic void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {if (mSurfaceTexture == null) {mSurfaceTexture = surface;openMediaPlayer();} else {mTextureView.setSurfaceTexture(mSurfaceTexture);}}private void openMediaPlayer() {// 屏幕常亮setKeepScreenOn(true);// 设置dataSourcetry {mMediaPlayer.setDataSource(mContext.getApplicationContext(), Uri.parse(mUrl)/*, mHeaders*/);if (mSurface == null) {mSurface = new Surface(mSurfaceTexture);}mMediaPlayer.setSurface(mSurface);mMediaPlayer.prepareAsync();} catch (IOException e) {e.printStackTrace();}}@Overridepublic void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {}@Overridepublic boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {return mSurfaceTexture == null;}@Overridepublic void onSurfaceTextureUpdated(SurfaceTexture surface) {}
}

使用布局:
在activity中的布局加上即可

    <com.example.ycm.smallvideoplayer.smallvideoplayer.SmallVideoPlayerandroid:id="@+id/small_video_player"android:layout_width="match_parent"android:layout_height="200dp" />

在activity中获取播放器view,然后设置一个视频URL,开启播放即可。

    SmallVideoPlayer mSmallVideoPlayer; = findViewById(R.id.small_video_player);mSmallVideoPlayer.setUp("http://tanzi27niu.cdsb.mobi/wps/wp-content/uploads/2017/05/2017-05-17_17-33-30.mp4");mSmallVideoPlayer.start();

以上就完成了视频播放器的初体验。其实你会发现这是多么简单啊。实际上来说一个高级开发人员并没有比你高明多少,他们比你多的其实只是经验和思路。所以想要从初中级开发跳跃到高级开发,需要你不断的思考,独立实现业务需求。如果给你一个大模块,你能利用你的知识,和网络获取的资料就能实现,你离高级开发工程师就不远了。

推荐阅读

Android进阶:自定义视频播放器开发(上)

最后

需要相关教学视频及源码,可以点击链接加入群聊【Android技术开发交流】:https://jq.qq.com/?_wv=1027&k=5PWTvm9, 找群管理免费领取一下,欢迎进群一起学习交流

转载于:https://blog.51cto.com/14263171/2374444

Android进阶:自定义视频播放器开发(下)相关推荐

  1. Android进阶:自定义视频播放器开发(上)

    随着快手,抖音,西瓜视频等视频APP的崛起,视频播放已经成为主流,此时作为Android研发的你,想要提高自己的能力还不知道怎么开发视频播放器怎么行?所以今天就带着大家一起开发一个简易播放器:Smal ...

  2. Android开发笔记(一百二十五)自定义视频播放器

    视频播放方式 在Android中播放视频的方式有两种: 1.使用MediaPlayer结合SurfaceView进行播放.其中通过SurfaceView显示视频的画面,通过MediaPlayer来设置 ...

  3. android 编译 sdl,SDL编译 - Android本地视频播放器开发_Linux编程_Linux公社-Linux系统门户网站...

    在上一章  Android本地视频播放器开发--ffmpeg解码视频文件中的音频(2)[http://www.linuxidc.com/Linux/2013-06/85955p5.htm]中使用Ope ...

  4. Android自定义视频播放器(三)

    参看:Android自定义视频播放器(一):https://blog.csdn.net/zxd1435513775/article/details/81507909 参看:Android自定义视频播放 ...

  5. Android本地视频播放器开发--SDL编译

    在上一章 Android本地视频播放器开发--ffmpeg解码视频文件中的音频(2)中使用OpenSL ES来播放视频的声音,遗留的问题是声音的不同步,由于视频实现部分也要同步,而且音视频也要同步,所 ...

  6. Android本地视频播放器开发 - 搜索本地视频(1)

    这一章的主要内容是搜索手机本地视频,添加到ListView列表里,每一个表项含有这个视频的缩略图,视频的播放时间,视频的标题,在搜索本地视频(1)中我们先制作搜索功能.   Video.java--视 ...

  7. 《android多媒体api》之MediaPlayer自定义视频播放器

    <android多媒体api>系列是整合梳理android开发中经常用到的媒体相关api:多媒体开发主要内容有音频.视频录制播放.摄像头操作.录制操作.流媒体.直播.推流.拉流等方面:最近 ...

  8. 基于NDK、C++、FFmpeg的android视频播放器开发实战-夏曹俊-专题视频课程

    基于NDK.C++.FFmpeg的android视频播放器开发实战-1796人已学习 课程介绍         课程包含了对流媒体(拉流)的播放,演示了播放rtmp的香港卫视,支持rtsp摄像头和ht ...

  9. 视频教程-基于NDK、C++、FFmpeg的android视频播放器开发实战-Android

    基于NDK.C++.FFmpeg的android视频播放器开发实战 夏曹俊:南京捷帝科技有限公司创始人,南京大学计算机硕士毕业,有15年c++跨平台项目研发的经验,领导开发过大量的c++虚拟仿真,计算 ...

最新文章

  1. 阿里某员工:发完年终奖后就离职,工作让我心力交瘁
  2. golang中的jwt
  3. 在Visual Studio设置隐藏cmd,GTK程序有效
  4. (六十三)第四章复习题
  5. Django第二天笔记
  6. 【Kotlin】我的第一个 Kotlin 程序
  7. 获奖名单揭晓!京微力小程序开发者大赛开拓社交电商新尝试
  8. 【已解决】报异常:java.lang.ArithmeticException: / by zero
  9. 协同过滤算法_一文带你了解协同过滤的前世今生
  10. Ubuntu Class ZipArchive not found
  11. 如何添加虚拟PDF打印机
  12. 在Windows 7上面安装Vs2005
  13. markdown在线编辑器
  14. JavaScript格式化字符串为指定长度
  15. 010 《你不理财,财不理你》读书笔记
  16. 1《小学数学教材解读策略研究》课题研究方案
  17. bilinear interpolation是什么
  18. windows通过注册表修改3389端口号
  19. 新世纪的群众性幻想与癫狂3
  20. 全国大学生女子足球锦标赛

热门文章

  1. 计算机图形数学知识,平面----计算机图形学的基础几何知识
  2. c语言中输入字符用什么作用是什么意思,C语言编程问题
  3. 有效值和峰峰值的关系_4.数据预处理—缺失值处理(二)
  4. c语言中格式化字符串系列函数包括,解析C语言中常用的格式化输入、输出函数...
  5. 苹果CMS V8 电脑手机自适应电影模板
  6. 百度SEO Keyword Surfer v0.3.7(关键词优化)
  7. android模块编译错误,android studio编译出错:Android resource linking failed
  8. linux 2.6 添加系统调用,在Fedora 13里编译内核(linux-2.6.36)+添加系统调用
  9. Java23种设计模式之概念篇
  10. BizTalk 开发系列(四十) BizTalk WCF-SQL Adapter读取SQL Service Broker消息