隨着網絡基礎建設的發展和資費的降低,在這個內容消費升級的時代,文字、圖片沒法知足人們對視覺的需求,所以視頻直播應運而生。承載了實時性Real-Time和交互性的直播雲服務是直播覆蓋各行各業的新動力。git
想必瞭解過直播的人都清楚直播主要分爲3部分:推流->流媒體服務器->拉流。github
而咱們今天須要講的就是推流這部分,它主要包括音視頻採集,音視頻前處理,音視頻編碼,推流和傳輸4個方面。可是因爲網絡的複雜性和大數據的統計,推流還須要有全局負載均衡調度 GSLB(Global Server Load Balance),以及實時的統計數據上報服務器,包括提供頻道管理給用戶運營,所以推流 SDK 須要接入 GSLB 中心調度,統計服務器,心跳服務器,用於推流分配到網絡最好的節點,有大數據的統計和分析。web
下圖涵蓋了直播相關的全部服務,紅色小標的線條表明指令流向,綠色小標的線條表明數據流向。算法
採集是全部環節中的第一環,咱們使用的系統原生框架 AVFoundation 採集數據。經過 iPhone 攝像頭(AVCaptureSession)採集視頻數據,經過麥克風(AudioUnit)採集音頻數據。目前視頻的採集源主要來自攝像頭採集、屏幕錄製(ReplayKit)、從視頻文件讀取推流。
音視頻都支持參數配置。音頻能夠設置採樣率、聲道數、幀大小、音頻碼率、是否使用外部採集、是否使用外部音頻前處理;視頻能夠設置幀率、碼率、分辨率、先後攝像頭、攝像頭採集方向、視頻端顯示比例、是否開啓攝像頭閃光燈、是否打開攝像頭響應變焦、是否鏡像前置攝像頭預覽、是否鏡像前置攝像頭編碼、是否打開濾鏡功能、濾鏡類型、是否打開水印支持、是否打開 QoS 功能、是否輸出 RGB 數據、是否使用外部視頻採集。服務器
前處理模塊也是主觀影響主播觀看效果最主要的環節。目前 iOS 端比較知名的是 GPUImage,提供了豐富的預處理效果,咱們也在此基礎上進行了封裝開發。視頻前處理包含濾鏡、美顏、水印、塗鴉等功能,同時在人臉識別和特效方面接入了第三方廠商 FaceU。SDK 內置 4 款濾鏡黑白、天然、粉嫩、懷舊;支持 16:9 裁剪;支持磨皮和美白(高斯模糊加邊緣檢測);支持靜態水印,動態水印,塗鴉等功能。音頻前處理則包括回聲抑制、嘯叫、增益控制等。音視頻都支持外部前處理。微信
編碼最主要的兩個難點是:網絡
因爲iOS端硬件兼容性比較好,所以能夠採用硬編。SDK 目前支持軟件編碼 openH264,硬件編碼 VideoToolbox。而音頻支持軟件編碼 FDK-AAC 和硬件編碼 AudioToolbox。負載均衡
視頻編碼的核心思想就是去除冗餘信息:框架
推流 SDK 使用的流媒體協議是 RTMP(RealTime Messaging Protocol)。而音視頻發送最困難的就是針對網絡的帶寬評估。因爲從直播端到 RTMP 服務器的網絡狀況複雜,尤爲是在 3G 和帶寬較差的 Wifi 環境下,網絡丟包、抖動和延遲常常發生,致使直播推流不順暢。RTMP 基於 TCP 進行傳輸,TCP 自身實現了網絡擁塞下的處理,內部的機制較爲複雜,並且對開發者不可見,開發者沒法根據 TCP 協議的信息判斷當時的網絡狀況,致使發送碼率大於實際網絡帶寬,形成比較嚴重的網絡擁塞。所以咱們自研開發了一款實時根據網絡變化的 QoS 算法,用於實時調節碼率、幀率、分辨率,同時將數據實時上報統計平臺。ide
鑑於推流的主流程分爲上述描述的 4 個部分:音視頻採集、音視頻前處理、音視頻編碼、音視頻發送。所以將推流 SDK 進行模塊劃分爲 LSMediacapture 層(對外 API+ 服務器交互)、視頻融合模塊(視頻採集+視頻前處理)、音頻融合模塊(音頻採集+音頻前處理)、基礎服務模塊、音視頻編碼模塊、網絡發送模塊。
下圖是直播的主要流程,用戶初始化 SDK,建立線程,開始直播,音視頻數據採集,編碼,發送。在發送線程下,音視頻數據發送,QoS 開啓,根據網絡實時評估帶寬,調整幀率,碼率控制編碼器參數,同時觸發跳幀,調整分辨率控制採集分辨率參數。用戶中止直播,反初始化 SDK,銷燬線程。QoS &跳幀能夠有效的解決用戶在網絡很差的狀況下,直播卡頓的問題。在不一樣的碼率和分辨率狀況下,都可以作到讓用戶流暢地觀看視頻直播。
隨着音頻處理和壓縮技術的不斷髮展,效果更好、適用範圍更廣、性能更高的算法和新的技術必將不斷涌現,若是你有好的技術或者分享,歡迎關注網易 MC 官方博客以及微信公衆號:**
關注更多技術乾貨內容: 網易雲信博客
歡迎關注 網易雲信 GitHub
歡迎關注 網易雲信官網官網微信公衆號: