MediaPlayer
在Android系统中对于视频播放器有原生的实现MediaPlayer, 以及将MediaPlayer,SurfaceView封装在一起的VideoView, 两者都只是使用硬解播放,基本上只支持本地和HTTP协议的视频播放,扩展性都很差,只适合最简单的视频播放需求。
ExoPlayer
谷歌后来有开源了一个播放器项目[ExoPlayer])(https://github.com/google/ExoPlayer), 提供了更好的扩展性和定制能力,并加入了对DASH和HLS等直播协议的支持,但也只支持硬码,如果项目中只需要支持对H264格式的视频播放,以及流媒体协议比较常规(比如HTTP,HLS),基于ExoPlayer定制也是不错的选择。
与Android内置的MediaPlayer相比,ExoPlayer具有许多优点:
*支持通过HTTP(DASH)和SmoothStreaming进行动态自适应流,这两种都不受MediaPlayer的支持。还支持许多其他格式
*能够自定义和扩展播放器,以适应各种不同需求。 ExoPlayer专门设计了这一点,大部分组件都可以自己替换
*官网说了很多,其实说到底最主要的就是各个组件可以自定义,还可以接入ffmpeg组件,基本能满足99.9%的需求
与IJKPlayer和Vitamio相比,ExoPlayer具有的优点:
*导入项目之后APK体积增加小
缺点:
*最低支持版本4.4
*实现比较复杂
ijkplayer
ijkplayer是Bilibili公司开源的播放器实现,整合了FFMpeg, ExoPlayer, MediaPlayer等多种实现,提供了类似于MediaPlayer的API,可以实现软硬解码自由切换,自定义TextureView实现,同时得益于FFMpeg的能力,也能支持多种流媒体协议(RTSP,RTMP,HLS等),多种视频编码格式(h264, mpeg4, mjpeg),具有很高的灵活性,可以定制实现自己特色的播放器(比如支持视频缩放,视频翻转等)。
视频播放的流程
常规的视频播放分为传输,解封装,解码,绘制四个步骤,以下按播放网站上(HTTP)的mp4文件为例,简单介绍一下几个过程:
视频播放过程.png
-
HTTP传输
播放器使用HTTP协议把MP4下载下来,这部分需求一般需要边下边播,服务器的HttpServer一定要支持HTTP Seek,因为播放的过程中需要跳转到不同的位置下载内容,比如MP4结构中的moov元数据信息在很多视频文件中都被放置在文件末尾了。 -
MP4解封包
这部分我们常见的封包格式就是mp4, 视频编码后h264数据被拆分为多个片段封包到mp4中,解封包就是从mp4中解析出h264视频裸码流的过程。需要对Mp4格式有更多了解,可以参考MP4文件格式解析
-
H264解码
视频解码就是将h264裸码流解析成视频像素数据的过程(一般是yuv,也可以是rgba,类似于将jpg图片解码为bitmap数据。h264格式可以使用Android系统提供MediaCoder硬解码,也可以使用FFMpeg进行软解码。
奉上一篇能把H264格式结构讲清楚的文章:深入浅出理解视频编码H264结构 -
OpenGL绘制
就是绘制就是将解析为yuv格式的视频数据绘制到屏幕上的过程,一般使用OpenGL绘制。OpenGL相关绘制的知识点相对比较复杂,这方面目前我也还在学习中。这里有篇文章可以参考TextureView+SurfaceTexture+OpenGL ES来播放视频