Android 播放器視頻畫面大小與比例

如何實(shí)現(xiàn)視頻畫面大小與比例的

ijkplayer 支持軟解硬解播放
  • 軟解是用OpenGL ES / NDK ANativeWindow 進(jìn)行渲染播放
  • 硬解是用MediaCodec configure Surface 直接渲染到 Surface

無論是OpenGL ES 還是 ANativeWindow 都能隨意處理圖像,MediaCodec 也提提供了setVideoScalingMode(int mode) 這個接口。而ijkplayer 內(nèi)部實(shí)現(xiàn)沒有運(yùn)用上面的機(jī)制來渲染圖片以用來調(diào)整畫面大小與比例。

相關(guān)概念

1、Surface 理解為引用了一塊內(nèi)存緩沖區(qū)(也可以稱畫布),程序可以間接控制這個畫布的大小,就是像素的長與寬,系統(tǒng)底層也會按照設(shè)置的format申請合適的緩沖區(qū)大小。
2、SurfaceHolder.Callback surfaceChanged 回調(diào)的width、height 并不是View 的大小 這一點(diǎn)一定要注意,官方文檔描述的非常清楚。它是SurfaceView 對應(yīng)的Surface 的大小 ,只不過第一次創(chuàng)建Surface 大小默認(rèn)值等于SurfaceView 的大小,參考 setSizeFromLayout()。

setFixedSize(int width, int height) 與setSizeFromLayout()都是設(shè)置Surface 的大小的。setSizeFromLayout() 就是默認(rèn)設(shè)置,導(dǎo)致新創(chuàng)建的SurfaceView 后Surface與View的大小一致。
3、onMeasure 函數(shù)用來決定View大小的

void [onMeasure](https://developer.android.com/reference/android/view/View.html#onMeasure(int, int)) (int widthMeasureSpec, int heightMeasureSpec)

4、視頻分辨率、屏幕分辨率
參考 百度百科 視頻分辨率 屏幕分辨率

5、視頻旋轉(zhuǎn)角度,有的視頻流中是自帶旋轉(zhuǎn)角度信息的,比如:Android Camera 拍攝的橫屏、豎屏視頻的分辨率都一樣的。不過豎屏拍的視頻流有元數(shù)據(jù)角度信息 90。

6、屏幕旋轉(zhuǎn)角度就是我們熟知的手機(jī)物理旋轉(zhuǎn)角度

7、畫面播放比例 Display Aspect Ratio 有常見的下列:
* 16:9/fit_parent
* 4:3/fit_parent
* wrapContent
* aspect_fit_parent
* fill_parent

實(shí)現(xiàn)畫面大小與比例

ijkplayer 在下面的函數(shù)中設(shè)置畫面大小與比例

public void doMeasure(int widthMeasureSpec, int heightMeasureSpec)

僅僅設(shè)置好了View的大小就能搞定所有的一切?這里就簡單描述一下背后的原理以及為何這樣做就可以了。這樣Android 播放器UI 定制就非常清楚了。

1、繪制視頻幀
OpenGL ES、NDK ANativeWindow 、MediaCodec 這些實(shí)現(xiàn)過程中都沒有做裁剪、放大、縮放、旋轉(zhuǎn)操作,無論提供多大畫布(Surface width/height)都繪制到整個畫布上面。不過繪制的時候處理了視頻旋轉(zhuǎn)角度信息,就是width/height 互換。SurfaceFlinger 合成Surface 到屏幕上的時候自動會根據(jù)對應(yīng)的View大小進(jìn)行Scale 操作。
2、視頻播放的比例 Display Aspect Ratio
只要設(shè)置好SurfaceView View的位置與大小,視頻將按照View 的位置與大小顯示。代碼可以參見 doMeasure

3、屏幕旋轉(zhuǎn)角度的變化只是改變了View 的寬/高, doMeasure會重現(xiàn)計算View新的大小
4、屏幕分辨率不影響,因?yàn)镾urfaceFlinger 最后會自動 Scale 到屏幕硬解緩沖區(qū)

然很多博客介紹ijkplayer 視頻播放比例大小選擇的時候都是不太嚴(yán)謹(jǐn)?shù)摹2皇且曨l在View 上裁剪、縮放操作,而是視頻渲染到整個View 區(qū)域。我們變化View 來適配畫面播放比例。
下面是HLS流 (480 * 270)實(shí)時切換畫面比例情況下,打印 輸出 SurfaceRenderView 的 onSizeChanged 事件,大家可以試一試。不過注意不要打印輸出IjkVideoView 這個View的變化了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容