今天使用公司開發手機,調研一下當下很火的抖音客戶端,其使用的視頻編碼類型。
在調研前,有個初步判斷:
1.從抖音服務器推送到客戶端的視頻流要么是avc碼流,要么是hevc碼流(具體要視平台解碼硬件支持情況,本地上傳支持情況,雲端再推來相應的碼流)。
2.本地客戶端,解碼器選擇有三個,手機平台提供硬件解碼器、Android提供的解碼器、抖音平台提供的解碼器。
2.1.其使用優先級為硬件解碼器排首位,后面的選擇則不太確定,視哪個解碼效率更高使用哪個。
2.2.有些手機不帶相應的硬件解碼器(例如,如果推來的是hevc的流,不是近幾年出的手機的話,一般不帶hevc硬件解碼器),則必須使用軟件解碼方式。
具體使用的是安卓提供的,還是使用抖音提供的,要看哪個解碼速度更快。
3.有些視頻做了保護而不能下載到本地,有辦法獲取視頻嗎?
3.1.如果使用硬件解碼器,則通過修改平台解碼驅動源碼,以替換平台解碼庫方式,可以拿到視頻碼流。
3.2.如果走Android提供的DRM方式,對這種沒用過,很可能無法拿到。
3.3.如果走抖音提供的解碼器,無法直接拿到碼流,一種比較低效的方式是,解碼后送平台顯示模塊,在顯示模塊拿yuv圖(其實3.2也可以這么干)。
3.4.另外一種方式是:攔截網卡收到的全部數據,根據hevc數據語法特征,對數據再進行再組裝,但是這種非常費時費力。
4.平台帶硬件解碼器前提下,在java上層,解碼是走MediaCodec方式還是走MediaPlayer方式?
4.1.走MediaPlayer方式跟普通播放器沒多大區別(一點區別是抖音不提供快進快退的seek功能)。
因為MediaPlayer一般是播放本地視頻使用,內部已經做了demux-decode-render很多細節功能,但是由於網絡傳來的流,這個需要抖音根據協議自己做音視頻分離,因此可能不是走這種通路。但是也不好說,畢竟安卓也支持rtsp流播放。
4.2.走MediaCodec的話,需要兩個MediaCodec實例來分別解碼音頻和視頻,然后java層獲取到解碼后的數據后分別送audio/video輸出通路。
-----------------------------------------------------------------------------可愛的分割線-----------------------------------------------------------------------------------------
手機硬件情況:帶avc和hevc硬件解碼器。
測試結果:
1.播放了30多個短視頻,一直出現平台的hevc解碼log信息,因此目前節點上抖音視頻都用上了h265(后來其他調查,發現不一定是265視頻流,自己的蘋果手機上傳的視頻,再下載下來,變成了264編碼碼流)。
2.只有一個手機,因自帶硬件解碼器,因此無法驗證軟解方式下,是使用安卓提供的還是抖音提供的。
3.有辦法獲得碼流。因為看到無法“保存到本地”的視頻,仍在使用平台硬件解碼器解碼。
4.從log中判斷,使用了MediaCodec,未用MediaPlayer。
其他信息:
1.客戶端的log路徑在哪?用於出錯時問題回溯。
logcat方式沒找到(douyin、bytedance相關關鍵詞),lib庫中看到包含libalog.so,應該是log生成相關,由於去掉了符號表,只能用winhex看二進制數據,也沒看到有用信息。
難道release版都把log關掉了?用戶客戶端出bug了,如何定位問題?
另外一種方式查找,如果本地寫log文件,那么應該使用了一些fd,於是看到了:
但是,不幸的是,下載這些log文件,看不到可識別的字符串信息,應該是log做過加密處理,不希望別人看到。
2.是否使用一些開源的東西?例如ffmpeg
使用了!通過其提供的庫可以看到:
使用了x264視頻編碼庫、ffmpeg多媒體框架、fdk-aac音頻編碼庫、libyuv圖形轉換庫、tensorflow機器學習庫等。
3.客戶端包名:com.ss.android.ugc.aweme
21:35:14.776 4551 4551 D BluetoothMapAppObserver: The installed package is: com.ss.android.ugc.aweme
4.安裝路徑
08-29 21:34:59.502 4269 4313 D PackageManager: New package installed in /data/app/com.ss.android.ugc.aweme-mCkAz35nMlxyL_FLCfX72Q==
5.使用線程一覽(太長就不貼全了):