? ? ? ?最近的項(xiàng)目需要實(shí)現(xiàn)視頻的播放功能未辆,底層的播放實(shí)現(xiàn)需要兼容常規(guī)的url視頻源播放和基于搜狐SDK的視頻源播放(視頻id)淆两,通過(guò)了解視頻播放的相關(guān)知識(shí)點(diǎn)师崎,總結(jié)了一下視頻相關(guān)知識(shí)。?
播放器控件相關(guān)知識(shí)點(diǎn)匯總:
一:播放器相關(guān)基礎(chǔ)知識(shí)點(diǎn)介紹
二:Android中視頻播放器的選擇
三:實(shí)現(xiàn)視頻播放的幾種方式介紹
四:播放器控件相關(guān)開(kāi)源項(xiàng)目介紹
五:播放器的常見(jiàn)使用場(chǎng)景
六:手?jǐn)]播放器控件遇到的問(wèn)題
七:播放器不同模塊代碼的解耦
八:播放器控件實(shí)現(xiàn)思路建議
九:遇到相關(guān)疑難雜癥
十:擴(kuò)展閱讀
一:播放器相關(guān)基礎(chǔ)知識(shí)點(diǎn)介紹
? ? ? 視頻播放的流程常規(guī)的視頻播放分為傳輸汇歹,解封裝屁擅,解碼,繪制四個(gè)步驟秤朗,以下按播放網(wǎng)站上(HTTP)的mp4文件為例煤蹭,簡(jiǎn)單介紹一下幾個(gè)過(guò)程:
HTTP傳輸:
描述:播放器使用HTTP協(xié)議把MP4下載下來(lái),這部分需求一般需要邊下邊播,服務(wù)器的HttpServer一定要支持HTTPSeek硝皂,因?yàn)椴シ诺倪^(guò)程中需要跳轉(zhuǎn)到不同的位置下載內(nèi)容常挚,比如MP4結(jié)構(gòu)中的moov元數(shù)據(jù)信息在很多視頻文件中都被放置在文件末尾了。
MP4解封包:
描述:這部分我們常見(jiàn)的封包格式就是mp4稽物,視頻編碼后H264數(shù)據(jù)被拆分為多個(gè)片段封包到mp4中奄毡,解封包就是從mp4中解析出H264視頻裸碼流的過(guò)程。
H264解碼:
描述:視頻解碼就是將h264裸碼流解析成視頻像素?cái)?shù)據(jù)的過(guò)程(一般是yuv贝或,也可以是rgba吼过,類似于將jpg圖片解碼為bitmap數(shù)據(jù)。h264格式可以使用Android系統(tǒng)提供MediaCoder硬解碼咪奖,也可以使用FFMpeg進(jìn)行軟解碼盗忱。
FFmpeg介紹:
描述:是一套可以用來(lái)記錄、轉(zhuǎn)換數(shù)字音頻羊赵、視頻趟佃,并能將其轉(zhuǎn)化為流的開(kāi)源計(jì)算機(jī)程序。采用LGPL或GPL許可證昧捷。它提供了錄制闲昭、轉(zhuǎn)換以及流化音視頻的完整解決方案。它包含了非常先進(jìn)的音頻/視頻編解碼庫(kù)libavcodec靡挥,為了保證高可移植性和編解碼質(zhì)量序矩,libavcodec里很多code都是從頭開(kāi)發(fā)的。
硬解碼和軟解碼:
一跋破、軟解碼和硬解碼如何區(qū)分
軟解碼:使用CPU進(jìn)行解碼
硬解碼:使用非CPU進(jìn)行解碼簸淀,如顯卡GPU、專用的DSP幔烛、FPGA啃擦、ASIC芯片等
二、軟解碼和硬解碼比較
軟解碼:實(shí)現(xiàn)直接饿悬、簡(jiǎn)單令蛉,參數(shù)調(diào)整方便,升級(jí)易狡恬,但CPU負(fù)載重珠叔,性能較硬解碼低,低碼率下質(zhì)量通常比硬解碼要好一點(diǎn)弟劲。
硬解碼:性能高祷安,低碼率下通常質(zhì)量低于硬解碼器,但部分產(chǎn)品在GPU硬件平臺(tái)移植了優(yōu)秀的軟解碼算法(如X264)的兔乞,質(zhì)量基本等同于軟解碼汇鞭。
優(yōu)缺點(diǎn)對(duì)比:
結(jié)論:
1凉唐、根據(jù)項(xiàng)目的需要,現(xiàn)在幾乎所有的設(shè)備都支持硬解碼和軟解碼霍骄,之前更多的人愿意選擇軟解碼台囱,更大的原因是因?yàn)橛布獯a支持的格式較少,而軟解碼對(duì)于格式是不受限制的读整。
2簿训、現(xiàn)在隨著硬件的不斷提高,解碼技術(shù)的不斷成熟和完善米间,我是更傾向硬解碼强品,但硬件提升的同時(shí),CPU也在不斷的優(yōu)化和提高屈糊,現(xiàn)在也不需要像之前那樣盡可能節(jié)省CPU的榛,現(xiàn)在處于性能過(guò)剩的時(shí)代,CPU已經(jīng)很難處于負(fù)荷狀態(tài)逻锐,選擇軟解碼或者硬解碼都是沒(méi)有誰(shuí)對(duì)誰(shuí)錯(cuò)困曙,剛剛圖上已經(jīng)貼出和標(biāo)記兩者的優(yōu)點(diǎn),根據(jù)項(xiàng)目需要選擇谦去。
圖像渲染:SurfaceView、TextureView蹦哼、GLSurfaceView鳄哭、SurfaceTexture的區(qū)別
一、SurfaceView
? ? ? ?是一個(gè)可以在子線程中更新UI的View纲熏,且不會(huì)影響到主線程妆丘。它為自己創(chuàng)建了一個(gè)窗口(window),就好像在視圖層次(View Hierarchy)上穿了個(gè)“洞”局劲,讓繪圖層(Surface)直接顯示出來(lái)勺拣。但是,和常規(guī)視圖(view)不同鱼填,它沒(méi)有動(dòng)畫(huà)或者變形特效药有,一些View的特性也無(wú)法使用。
概括:
1苹丸、SurfaceView獨(dú)立于視圖層次(View Hierarchy)愤惰,擁有自己的繪圖層(Surface),但也沒(méi)有一些常規(guī)視圖(View)的特性赘理,如動(dòng)畫(huà)等宦言。
2、SurfaceView的實(shí)現(xiàn)中具有兩個(gè)繪圖層(Surface)商模,即我們所說(shuō)的雙緩沖機(jī)制奠旺。我們的繪制發(fā)生在后臺(tái)畫(huà)布上蜘澜,并通過(guò)交換前后臺(tái)畫(huà)布來(lái)刷新畫(huà)面,可避免局部刷新帶來(lái)的閃爍响疚,也提高了渲染效率鄙信。
3、SurfaceView中的SurfaceHolder是Surface的持有者和管理控制者稽寒。
4扮碧、SurfaceHolder.Callback的各個(gè)回調(diào)發(fā)生在主線程。
二杏糙、GLSurfaceView
? ? ? ?繼承SurfaceView慎王,除了擁有SurfaceView所有特性外,還加入了EGL(EGL是OpenGL ES和原生窗口系統(tǒng)之間的橋梁) 的管理宏侍,并自帶了一個(gè)單獨(dú)的渲染線程赖淤。
概括:
1、繼承自SurfaceView谅河,擁有其所有特性咱旱。
2、加入了EGL管理绷耍,是SurfaceView應(yīng)用OpenGL ES的典型場(chǎng)景吐限。
3、有單獨(dú)的渲染線程GLThread褂始。
4诸典、單獨(dú)出了Renderer接口負(fù)責(zé)實(shí)際渲染,不同的Renderer實(shí)現(xiàn)相當(dāng)于不同的渲染策略崎苗,使用方式靈活(策略模式)狐粱。
三、SurfaceTexture
? ? ? ?Android3.0(API 11)新加入的一個(gè)類胆数,不同于SurfaceView會(huì)將圖像顯示在屏幕上肌蜻,SurfaceTexture對(duì)圖像流的處理并不直接顯示,而是轉(zhuǎn)為GL外部紋理必尼。
概括:
1蒋搜、SurfaceTexture可以從圖像流(相機(jī)、視頻)中捕獲幀數(shù)據(jù)用作OpenGL ES外部紋理(GL_TEXTURE_EXTERNAL_OES)胰伍,實(shí)現(xiàn)無(wú)縫連接齿诞。
2、我們可以很方便的對(duì)這個(gè)外部紋理進(jìn)行二次處理(如添加濾鏡等)骂租。
3祷杈、輸出目標(biāo)是Camera或MediaPlayer時(shí),可以用SurfaceTexture代替SurfaceHolder渗饮,這樣圖像流將把所有幀傳給SurfaceTexture而不是顯示在設(shè)備上但汞。
4宿刮、使用updateTexImage()方法更新最新的圖像。
四私蕾、TextureView
? ? ? TextureView是Android4.0(API 14)引入僵缺,它必須使用在開(kāi)啟了硬件加速的窗體中。除了擁有SurfaceView的特性外踩叭,它還可以進(jìn)行像常規(guī)視圖(View)那樣進(jìn)行平移磕潮、縮放等動(dòng)畫(huà)。
概括:
1容贝、必須開(kāi)啟硬件加速(這個(gè)默認(rèn)就是開(kāi)啟的)自脯。
2、可以像常規(guī)視圖(View)那樣使用它斤富,包括進(jìn)行平移膏潮、縮放等操作。
3满力、TextureView重載了draw()方法焕参,主要是使用SurfaceTexture中收到的圖像數(shù)據(jù)作為紋理更新到對(duì)應(yīng)的HardwareLayer中。
4油额、通過(guò)SurfaceTextureListener接口讓使用者知道SurfaceTexture的各種狀態(tài)叠纷。
SurfaceView對(duì)比TextureView:
Open GL,Open GL ES與Android EGL介紹:
介紹:OpenGL ES(OpenGL for Embedded Systems潦嘶,以下簡(jiǎn)稱OpenGL)
介紹:是OpenGL三維圖形API的子集讲岁,針對(duì)手機(jī)、PDA和游戲主機(jī)等嵌入式設(shè)備而設(shè)計(jì)衬以。該API由Khronos集團(tuán)定義推廣,Khronos是一個(gè)圖形軟硬件行業(yè)協(xié)會(huì)校摩,該協(xié)會(huì)主要關(guān)注圖形和多媒體方面的開(kāi)放標(biāo)準(zhǔn)看峻。
Android EGL:
介紹:EGL是介于諸如OpenGL或OpenVG的Khronos渲染API與底層本地平臺(tái)窗口系統(tǒng)的接口,是OpenGL ES和本地窗口系統(tǒng)(Native Window System)之間的通信接口衙吩,它被用于處理圖形管理互妓、表面/緩沖捆綁、渲染同步及支援使用其他KhronosAPI進(jìn)行的高效坤塞、加速冯勉、混合模式2D和3D渲染。
EGL的主要功能:
EGL是用來(lái)管理繪圖表面(Drawing surfaces)摹芙,并且提供了如下的機(jī)制
1灼狰、與本地窗口系統(tǒng)進(jìn)行通信
2、查找繪圖表面可用的類型和配置信息
3浮禾、創(chuàng)建繪圖表面
4交胚、同步OpenGL ES 2.0和其他的渲染API(Open VG份汗、本地窗口系統(tǒng)的繪圖命令等)
5、管理渲染資源蝴簇,比如材質(zhì)
二:Android中視頻播放器的選擇
1杯活、MediaPlayer
描述:在Android系統(tǒng)中對(duì)于視頻播放器有原生的實(shí)現(xiàn)MediaPlayer,以及將MediaPlayer和SurfaceView封裝在一起的VideoView熬词,兩者都只是使用硬解碼播放旁钧,基本上只支持本地和HTTP協(xié)議的視頻播放,擴(kuò)展性都很差互拾,只適合最簡(jiǎn)單的視頻播放需求歪今。
2、ExoPlayer
描述:谷歌后來(lái)有開(kāi)源了一個(gè)播放器項(xiàng)目[ExoPlayer])(https://github.com/google/ExoPlayer)摩幔,提供了更好的擴(kuò)展性和定制能力彤委,并加入了對(duì)DASH和HLS等直播協(xié)議的支持,但也只支持硬解碼或衡,如果項(xiàng)目中只需要支持對(duì)H264格式的視頻播放焦影,以及流媒體協(xié)議比較常規(guī)(比如HTTP,HLS)封断,基于ExoPlayer定制也是不錯(cuò)的選擇斯辰。?
? ? ? ?與Android內(nèi)置的MediaPlayer相比,ExoPlayer具有許多優(yōu)點(diǎn):
1坡疼、支持HTTP上的動(dòng)態(tài)自適應(yīng)流DASH和SmoothStreaming彬呻。
2、支持高級(jí)的HLS特點(diǎn)柄瑰,例如正確的處理#EXT-X-DISCONTINUITY標(biāo)簽闸氮。
3、能夠無(wú)縫的合并教沾,串聯(lián)蒲跨,循環(huán)播放媒體文件。
4授翻、能夠被高度擴(kuò)展和定制或悲,以適用不同的場(chǎng)景,ExoPlayer專門(mén)設(shè)計(jì)了這一點(diǎn)堪唐,大部分組件都可以自己替換巡语。(可以自定義視頻緩存,視頻進(jìn)度實(shí)時(shí)回調(diào))
5淮菠、各個(gè)組件可以自定義男公,還可以接入ffmpeg組件,基本能滿足99.9%的需求合陵。(具體詳情去官網(wǎng)了解)
缺點(diǎn):
1理澎、在某些設(shè)備上播放音頻逞力,ExoPlayer可能會(huì)比MediaPlayer消耗更多的電量。
2糠爬、最低支持版本4.4?
3寇荧、實(shí)現(xiàn)比較復(fù)雜
3、ijkplayer
描述:ijkplayer是Bilibili公司開(kāi)源的播放器實(shí)現(xiàn)执隧,整合了FFMpeg揩抡,ExoPlayer,MediaPlayer等多種實(shí)現(xiàn)镀琉,提供了類似于MediaPlayer的API峦嗤,可以實(shí)現(xiàn)軟硬解碼自由切換,自定義TextureView實(shí)現(xiàn)屋摔,同時(shí)得益于FFMpeg的能力烁设,也能支持多種流媒體協(xié)議(RTSP,RTMP钓试,HLS等)装黑,多種視頻編碼格式(h264, mpeg4,mjpeg),具有很高的靈活性弓熏,可以定制實(shí)現(xiàn)自己特色的播放器(比如支持視頻縮放恋谭,視頻翻轉(zhuǎn)等)。
三:實(shí)現(xiàn)視頻播放的幾種方式介紹
一:MediaController+VideoView實(shí)現(xiàn)方式(靈活度低挽鞠,SDK已包含)
介紹:這種方式是最簡(jiǎn)單的實(shí)現(xiàn)方式疚颊,VideoView繼承了SurfaceView同時(shí)實(shí)現(xiàn)了MediaPlayerControl接口,MediaController則是安卓封裝的輔助控制器信认,帶有暫停材义,播放,停止嫁赏,進(jìn)度條等控件母截。通過(guò)VideoView+MediaController可以很輕松的實(shí)現(xiàn)視頻播放、停止橄教、快進(jìn)、快退等功能喘漏,雖然VideoView的實(shí)現(xiàn)方式很簡(jiǎn)單护蝶,但是由于是自帶的封裝好的類,所以無(wú)論是播放器的大小翩迈、位置以及控制都不受我們控制持灰。
二:MediaPlayer+SurfaceView+MediaController(靈活度中,SDK已包含)
描述:MediaController是安卓封裝的輔助控制器负饲,帶有暫停堤魁,播放喂链,停止,進(jìn)度條等控件妥泉,播放實(shí)現(xiàn)使用SurfaceView作為播放容器實(shí)現(xiàn)椭微,播放的控制使用MediaPlayer實(shí)現(xiàn),這種方式由于使用了MediaController盲链,同樣無(wú)法定制播放器控件蝇率,不過(guò)使用MediaPlayer實(shí)現(xiàn)播放,提供了視頻播放時(shí)更多的回調(diào)函數(shù)刽沾,可以實(shí)現(xiàn)更多元化的需求本慕,例如:回調(diào)播放視頻的寬高,視頻播放開(kāi)始侧漓,停止锅尘,完成等回調(diào)。
三:MediaPlayer+SurfaceView+自定義控制器(靈活度高布蔗,SDK已包含)
描述:使用MediaPlayer實(shí)現(xiàn)視頻播放藤违,可以提供視頻播放時(shí)狀態(tài)的多種回調(diào),然后不使用MediaController何鸡,而是使用自定義的控制器纺弊,實(shí)現(xiàn)更加靈活的界面需求。
四:使用Exo骡男,IJKPlayer淆游,F(xiàn)FMPEG等開(kāi)源實(shí)現(xiàn)(靈活度極高,接入相對(duì)復(fù)雜隔盛,引入外部jar犹菱,aar或者M(jìn)odule)
描述:與Android內(nèi)置的MediaPlayer相比,ExoPlayer具有許多優(yōu)點(diǎn):
1吮炕、支持HTTP上的動(dòng)態(tài)自適應(yīng)流DASH和SmoothStreaming腊脱。
2、支持高級(jí)的HLS特點(diǎn)龙亲,例如正確的處理#EXT-X-DISCONTINUITY標(biāo)簽陕凹。
3、能夠無(wú)縫的合并鳄炉,串聯(lián)杜耙,循環(huán)播放媒體文件。
4拂盯、能夠被高度擴(kuò)展和定制佑女,以適用不同的場(chǎng)景,ExoPlayer專門(mén)設(shè)計(jì)了這一點(diǎn),大部分組件都可以自己替換团驱。(例如:視頻緩存的定制)
5摸吠、各個(gè)組件可以自定義,還可以接入ffmpeg組件嚎花,基本能滿足99.9%的需求寸痢。(具體詳情去官網(wǎng)了解)
五:使用愛(ài)奇藝,騰訊贩幻,優(yōu)酷轿腺,搜狐視頻SDK(靈活度取決于SDK開(kāi)放接口)
描述:視頻播放的相關(guān)數(shù)據(jù)及狀態(tài),不同的SDK會(huì)有不同的接口設(shè)計(jì)丛楚,接入一般有官方demo族壳,定制的東西相對(duì)較少,接入相對(duì)簡(jiǎn)單趣些,一般使用視頻資源id標(biāo)識(shí)資源仿荆。
四:播放器控件相關(guān)開(kāi)源項(xiàng)目介紹
一:ijkplayer(26.5k)
項(xiàng)目地址:https://github.com/Bilibili/ijkplayer
介紹:Ijkplayer是Bilibili發(fā)布的基于FFplay的輕量級(jí)Android/iOS視頻播放器。實(shí)現(xiàn)了跨平臺(tái)功能坏平,API易于集成拢操;編譯配置可裁剪,方便控制安裝包大胁疤妗令境;支持硬件加速解碼,更加省電顾瞪;提供Android平臺(tái)下應(yīng)用彈幕集成的解決方案舔庶。
二:ExoPlayer(15.6k)
項(xiàng)目地址:https://github.com/google/ExoPlayer
介紹:這款由YouTube開(kāi)發(fā)的播放器真的是非常強(qiáng)大。對(duì)于自定義播放器非常友好陈醒,里面講很多模塊抽象成獨(dú)立的組件可供使用者自行定制惕橙,當(dāng)然官方也提供了一些默認(rèn)的實(shí)現(xiàn)。
優(yōu)點(diǎn):
1钉跷、在不同Android版本和不同的手機(jī)設(shè)備上擁有更統(tǒng)一的行為表現(xiàn)弥鹦,更少的設(shè)備差異帶來(lái)的問(wèn)題。
2爷辙、作為一個(gè)獨(dú)立的庫(kù)彬坏,可以很輕易的升級(jí)。
3膝晾、可以根據(jù)用戶的需求方便的對(duì)播放器行為進(jìn)行定制和擴(kuò)展栓始,ExoPlayer中的很多組件都支持自定義和擴(kuò)展。
4玷犹、支持播放視頻列表,并且可以支持對(duì)視頻的裁剪、合并歹颓,以及循環(huán)播放設(shè)置坯屿。
5、支持更多的視頻格式巍扛,包括MediaPlayer不支持的DASH领跛、SmoothStreaming。
6撤奸、支持Widevine功能吠昭,這個(gè)功能可以下載和播放經(jīng)過(guò)Google加密的視頻文件。
7胧瓜、能夠方便的集成額外的擴(kuò)展庫(kù)矢棚,比如IMA擴(kuò)展庫(kù)。
缺點(diǎn):
1府喳、相比于Android原生的MediaPlayer蒲肋,ExoPlayer將顯著的消耗更多的電量
2、集成ExoPlayer將對(duì)你的APP包體增加幾百KB的大小
三:GSYVideoPlayer(14.1k)
項(xiàng)目地址:https://github.com/CarGuo/GSYVideoPlayer
介紹:視頻播放器钝满,支持基本的拖動(dòng)兜粘,聲音、亮度調(diào)節(jié)弯蚜,支持邊播邊緩存孔轴,支持視頻本身自帶rotation的旋轉(zhuǎn)(90,270之類),重力旋轉(zhuǎn)與手動(dòng)旋轉(zhuǎn)的同步支持碎捺,支持列表播放路鹰,直接添加控件為封面,列表全屏動(dòng)畫(huà)牵寺。
主要特點(diǎn):
1悍引、支持基本的拖動(dòng),聲音帽氓、亮度調(diào)節(jié)趣斤。
2、支持邊播邊緩存黎休,使用了AndroidVideoCache浓领。(https://github.com/danikula/AndroidVideoCache)
3、支持視頻本身自帶rotation的旋轉(zhuǎn)势腮。
4联贩、增加了重力旋轉(zhuǎn)與手動(dòng)旋轉(zhuǎn)的同步支持。
5捎拯、支持列表播放泪幌。
6、直接添加控件為封面。
7祸泪、全屏和播放等的動(dòng)畫(huà)效果吗浩。
8、列表的全屏效果優(yōu)化没隘,多種配置模式懂扼。
9、列表的小窗口播放右蒲,可拖動(dòng)阀湿。
10、網(wǎng)絡(luò)視頻加載速度瑰妄。
11陷嘴、鎖定/解鎖全屏點(diǎn)擊功能。
12翰撑、支持快播和慢播罩旋。
13、調(diào)整顯示比例:默認(rèn)眶诈、16:9涨醋、4:3。
14逝撬、調(diào)整不同清晰度的支持浴骂。
15、支持IJKPlayer和EXOPlayer切換宪潮。
16溯警、進(jìn)度條小窗口預(yù)覽(測(cè)試)。
17狡相、Https支持梯轻。
18、連續(xù)播放一個(gè)列表的視頻尽棕。
19喳挑、支持全屏與非全屏兩套布局切換
20、彈幕支持
四:JieCaoVideoPlayer(10.1k)
項(xiàng)目地址:https://github.com/lipangit/JieCaoVideoPlayer(JiaoZiVideoPlayer)
介紹:節(jié)操視頻播放器是一個(gè)讓開(kāi)發(fā)者可以三兩行代碼就能集成到應(yīng)用中的視頻播放框架滔悉,并且提供了開(kāi)放的接口來(lái)滿足不同開(kāi)發(fā)者的不同需求伊诵。
JiaoZiVideo主要特點(diǎn):
1、可以完全自定義UI和任何功能
2回官、一行代碼切換播放引擎曹宴,支持的視頻格式和協(xié)議取決于播放引擎,android.media.MediaPlayerijkplayer
3歉提、完美檢測(cè)列表滑動(dòng)
4笛坦、可實(shí)現(xiàn)全屏播放区转,小窗播放
5、能在ListView版扩、ViewPager和ListView蜗帜、ViewPager和Fragment等多重嵌套模式下全屏工作
6、可以在加載资厉、暫停、播放等各種狀態(tài)中正常進(jìn)入全屏和退出全屏
7蔬顾、多種視頻適配屏幕的方式宴偿,可鋪滿全屏,可以全屏剪裁
8诀豁、重力感應(yīng)自動(dòng)進(jìn)入全屏
9窄刘、全屏后手勢(shì)修改進(jìn)度和音量。
10舷胜、Home鍵退出界面暫停播放娩践,返回界面繼續(xù)播放。
Android主流開(kāi)源視頻播放器對(duì)比:(時(shí)間節(jié)點(diǎn):2019年6月)
優(yōu)缺點(diǎn)對(duì)比:
市面上熱度最高的開(kāi)源播放器就是ijkplayer和Exoplayer烹骨,其他大多數(shù)是在它們的基礎(chǔ)上進(jìn)行二次封裝翻伺。
五:播放器的常見(jiàn)使用場(chǎng)景
場(chǎng)景一:一個(gè)Activity就顯示一個(gè)視頻控件
解析:如果需要實(shí)現(xiàn)點(diǎn)擊全屏顯示功能,需要添加輔助類:OrientationUtils沮焕,實(shí)現(xiàn)該
場(chǎng)景轉(zhuǎn)屏相關(guān)邏輯實(shí)現(xiàn)吨岭。(參考開(kāi)源項(xiàng)目:GSYVideoPlayer)
場(chǎng)景二:視頻控件嵌套在列表的中
解析:當(dāng)視頻控件嵌套在列表里面時(shí)的注意點(diǎn):
1、列表滑動(dòng)無(wú)法看到視頻時(shí)峦树,視頻停止播放辣辫。
2、列表控件全屏播放時(shí)魁巩,需要停止列表中的小視頻播放急灭,把全屏視頻布局覆蓋在界面頂部,并播放全屏視頻谷遂。
3葬馋、需要在列表Adapter中,添加視頻相關(guān)邏輯埋凯,例如全屏按鈕點(diǎn)擊時(shí)点楼,列表刷新等操作需要添加輔助類:GSYVideoHelper和內(nèi)部類GSYVideoHelper.GSYVideoHelperBuilder實(shí)現(xiàn)該場(chǎng)景下的視頻播放實(shí)現(xiàn)。
場(chǎng)景三:在詳情頁(yè)白对,視頻控件固定在頂部
解析:如果需要實(shí)現(xiàn)手動(dòng)和屏幕旋轉(zhuǎn)時(shí)掠廓,全屏播放視頻,需要添加輔助類OrientationUtils甩恼。
實(shí)現(xiàn)相關(guān)功能如:
1蟀瞧、在進(jìn)入界面視頻未開(kāi)始播放時(shí)沉颂,禁止手機(jī)的旋轉(zhuǎn)功能悦污。(不然會(huì)亂屏)
2铸屉、需要在視頻開(kāi)始播放后,開(kāi)啟手機(jī)旋轉(zhuǎn)功能切端。
3彻坛、需要OrientationUtils類在onConfigurationChanged函數(shù)中,傳入播放器對(duì)象實(shí)現(xiàn)屏幕旋轉(zhuǎn)的監(jiān)聽(tīng)踏枣。
六昌屉、手?jǐn)]播放器控件遇到的問(wèn)題匯總
5.1、全屏播放的實(shí)現(xiàn)(注意狀態(tài)欄與導(dǎo)航欄的系統(tǒng)版主適配)
5.2茵瀑、音頻焦點(diǎn)搶占問(wèn)題(注意系統(tǒng)版主適配)
5.3间驮、橫豎屏手動(dòng)和被動(dòng)切換注意點(diǎn)
5.4、Activity或Fragment在不同狀態(tài)下的马昨,視頻控件如何適配竞帽,關(guān)閉屏幕,來(lái)電鸿捧,切換到后臺(tái)屹篓,退出等處理。
(與Activity與Fragment生命周期的聯(lián)動(dòng))
5.5匙奴、自定義時(shí)間進(jìn)度條的實(shí)現(xiàn)(ProgressTimeBar)
5.6抱虐、兼容不同底層播放能力(EXO,F(xiàn)FMPEG饥脑,SohuSdk等)
5.7恳邀、不同狀態(tài)在是否需要自動(dòng)息屏
5.8、不同狀態(tài)的切換(使用Visible與InVisible或使用addView與removeView)
5.9灶轰、視頻的自動(dòng)寬高適配
七:播放器不同模塊代碼的解耦
6.1谣沸、底層播放能力的解耦,單獨(dú)實(shí)現(xiàn)笋颤,使用策列模式實(shí)現(xiàn)(EXO和SohuSdk乳附,后續(xù)添加不同的視頻源SDK)
6.2、手勢(shì)操作的解耦(滑動(dòng)調(diào)節(jié)伴澄,單擊赋除,雙擊的監(jiān)聽(tīng)與響應(yīng)事件)
6.3、各種響應(yīng)對(duì)話框單獨(dú)分離出來(lái)
6.4非凌、視頻狀態(tài)的控制相關(guān)操作(暫停举农,繼續(xù)等操作)
八、播放器控件實(shí)現(xiàn)思路建議(個(gè)人理解敞嗡,僅供參考)
1颁糟、如果在Android與IOS需要有統(tǒng)一的標(biāo)準(zhǔn)航背,并需要對(duì)特定流媒體協(xié)議,特定視頻編碼有一定的要求棱貌,建議優(yōu)先參考ijkPlayer玖媚。
2、如果只需要實(shí)現(xiàn)底層播放婚脱,且項(xiàng)目視頻播放模塊需要大量定制功能的話今魔,建議查看ExoPlayer和jiaoziPlayer,大量定制功能需要自己實(shí)現(xiàn)障贸。
3涡贱、如果需要一個(gè)較為完善,已經(jīng)實(shí)現(xiàn)了常見(jiàn)視頻播放控件的相關(guān)功能(愛(ài)奇藝惹想,優(yōu)酷,騰訊視頻的視頻控件)督函,并實(shí)現(xiàn)了播放器控件的各種場(chǎng)景下的使用demo嘀粱,GSYPlayer是首選,此外辰狡,GSY也有實(shí)現(xiàn)了對(duì)EXO和IJKPlayer的封裝實(shí)現(xiàn)分支锋叨。
九:遇到相關(guān)疑難雜癥(持續(xù)更新)
問(wèn)題一:在調(diào)節(jié)亮度和音量時(shí),彈出的對(duì)話框使用getContext()或外部傳入的Context宛篇,在使用外部傳入的Context時(shí)娃磺,對(duì)話框布局底部會(huì)被截取一小段。
解決方案:統(tǒng)一使用getContext()獲取叫倍。
問(wèn)題二:在Activity中的Ondestroy中執(zhí)行視頻控件的Release()函數(shù)偷卧,發(fā)現(xiàn)如果在release()函數(shù)中才放棄音頻焦點(diǎn)的話,會(huì)使得Activity的OnDestroy會(huì)延遲執(zhí)行吆倦,甚至退出Activity听诸,重新啟動(dòng)其他Activity時(shí),其他Activity都初始化了蚕泽,銷毀的Activity的OnDestroy函數(shù)還沒(méi)有執(zhí)行晌梨。
解決方案:在視頻控件的OnPause中就放棄音頻焦點(diǎn)。
十:擴(kuò)展閱讀
1须妻、https://blog.csdn.net/u010072711/article/details/51517170(Android視頻播放器實(shí)現(xiàn)小窗口和全屏狀態(tài)切換)
2仔蝌、https://blog.csdn.net/qq_25955641/article/details/89790669(Android播放器的三種實(shí)現(xiàn)方法)
3、https://blog.csdn.net/liuzhi0724/article/details/81318816?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-1(Android實(shí)現(xiàn)視頻播放的3種實(shí)現(xiàn)方式)
4荒吏、https://www.reibang.com/p/53581512ba3f(github上十二款最著名的Android播放器開(kāi)源項(xiàng)目)
5敛惊、https://blog.csdn.net/qq_34895720/article/details/101511876(Android中視頻播放器的選擇,MediaPlayer绰更、ExoPlayer豆混、ijkplayer簡(jiǎn)單對(duì)比)
6篓像、http://www.voidcn.com/article/p-ktividrq-tk.html(MP4文件格式解析)
7、https://www.reibang.com/p/291ff6ddc164(TextureView+SurfaceTexture+OpenGLES來(lái)播放視頻(三)
8皿伺、https://blog.csdn.net/charleslei/article/details/44599041(簡(jiǎn)單談?wù)動(dòng)簿幋a和軟編碼)
9员辩、https://blog.csdn.net/pangpang123654/article/details/78125038?utm_medium=distribute.pc_relevant.
none-task-blog-baidujs-1(硬解碼與軟解碼的選擇)
10、https://blog.csdn.net/afei__/article/details/100023701?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-8.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-8.nonecase(淺談SurfaceView鸵鸥、TextureView奠滑、GLSurfaceView、SurfaceTexture)
11妒穴、https://blog.csdn.net/m475664483/article/details/52998445(SurfaceTexture宋税,TextureView,SurfaceView和GLSurfaceView的區(qū)別)
12、https://blog.csdn.net/aa642531/article/details/93230076(Android主流開(kāi)源視頻播放器對(duì)比)
13讼油、https://zhuanlan.zhihu.com/p/115220766(Android OpenGL ES系列連載:(06)EGL)