Android进阶:自定义视频播放器开发(下)
上一篇文章我们主要讲了视频播放器开发之前需要准备的一个知识,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进阶:自定义视频播放器开发(下)相关推荐
- Android进阶:自定义视频播放器开发(上)
随着快手,抖音,西瓜视频等视频APP的崛起,视频播放已经成为主流,此时作为Android研发的你,想要提高自己的能力还不知道怎么开发视频播放器怎么行?所以今天就带着大家一起开发一个简易播放器:Smal ...
- Android开发笔记(一百二十五)自定义视频播放器
视频播放方式 在Android中播放视频的方式有两种: 1.使用MediaPlayer结合SurfaceView进行播放.其中通过SurfaceView显示视频的画面,通过MediaPlayer来设置 ...
- android 编译 sdl,SDL编译 - Android本地视频播放器开发_Linux编程_Linux公社-Linux系统门户网站...
在上一章 Android本地视频播放器开发--ffmpeg解码视频文件中的音频(2)[http://www.linuxidc.com/Linux/2013-06/85955p5.htm]中使用Ope ...
- Android自定义视频播放器(三)
参看:Android自定义视频播放器(一):https://blog.csdn.net/zxd1435513775/article/details/81507909 参看:Android自定义视频播放 ...
- Android本地视频播放器开发--SDL编译
在上一章 Android本地视频播放器开发--ffmpeg解码视频文件中的音频(2)中使用OpenSL ES来播放视频的声音,遗留的问题是声音的不同步,由于视频实现部分也要同步,而且音视频也要同步,所 ...
- Android本地视频播放器开发 - 搜索本地视频(1)
这一章的主要内容是搜索手机本地视频,添加到ListView列表里,每一个表项含有这个视频的缩略图,视频的播放时间,视频的标题,在搜索本地视频(1)中我们先制作搜索功能. Video.java--视 ...
- 《android多媒体api》之MediaPlayer自定义视频播放器
<android多媒体api>系列是整合梳理android开发中经常用到的媒体相关api:多媒体开发主要内容有音频.视频录制播放.摄像头操作.录制操作.流媒体.直播.推流.拉流等方面:最近 ...
- 基于NDK、C++、FFmpeg的android视频播放器开发实战-夏曹俊-专题视频课程
基于NDK.C++.FFmpeg的android视频播放器开发实战-1796人已学习 课程介绍 课程包含了对流媒体(拉流)的播放,演示了播放rtmp的香港卫视,支持rtsp摄像头和ht ...
- 视频教程-基于NDK、C++、FFmpeg的android视频播放器开发实战-Android
基于NDK.C++.FFmpeg的android视频播放器开发实战 夏曹俊:南京捷帝科技有限公司创始人,南京大学计算机硕士毕业,有15年c++跨平台项目研发的经验,领导开发过大量的c++虚拟仿真,计算 ...
最新文章
- 阿里某员工:发完年终奖后就离职,工作让我心力交瘁
- golang中的jwt
- 在Visual Studio设置隐藏cmd,GTK程序有效
- (六十三)第四章复习题
- Django第二天笔记
- 【Kotlin】我的第一个 Kotlin 程序
- 获奖名单揭晓!京微力小程序开发者大赛开拓社交电商新尝试
- 【已解决】报异常:java.lang.ArithmeticException: / by zero
- 协同过滤算法_一文带你了解协同过滤的前世今生
- Ubuntu Class ZipArchive not found
- 如何添加虚拟PDF打印机
- 在Windows 7上面安装Vs2005
- markdown在线编辑器
- JavaScript格式化字符串为指定长度
- 010 《你不理财,财不理你》读书笔记
- 1《小学数学教材解读策略研究》课题研究方案
- bilinear interpolation是什么
- windows通过注册表修改3389端口号
- 新世纪的群众性幻想与癫狂3
- 全国大学生女子足球锦标赛
热门文章
- 计算机图形数学知识,平面----计算机图形学的基础几何知识
- c语言中输入字符用什么作用是什么意思,C语言编程问题
- 有效值和峰峰值的关系_4.数据预处理—缺失值处理(二)
- c语言中格式化字符串系列函数包括,解析C语言中常用的格式化输入、输出函数...
- 苹果CMS V8 电脑手机自适应电影模板
- 百度SEO Keyword Surfer v0.3.7(关键词优化)
- android模块编译错误,android studio编译出错:Android resource linking failed
- linux 2.6 添加系统调用,在Fedora 13里编译内核(linux-2.6.36)+添加系统调用
- Java23种设计模式之概念篇
- BizTalk 开发系列(四十) BizTalk WCF-SQL Adapter读取SQL Service Broker消息