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來播放視頻