“易+”開源 | 基於 ijkplayer 的 LLS-Player 移動端應用實踐

網易智企發表於2023-04-04

雲信低延時直播(Low-Latency Streaming,LLS)是在網易雲信標準直播的基礎上,依託自研的全球實時傳輸網 WE-CAN 推出的低延時直播產品方案。在保障低延時的同時,具有極致秒開,低卡頓的特性。同時相容標準直播的推流和雲端媒體處理能力,方便客戶從標準直播遷移到低延時直播上來。

雲信低延時播放器 LLS-Player 是一個傳輸層的 SDK,基於 WebRTC 進行開發,包含信令和媒體建聯,音影片資料接收,弱網對抗等能力,具有較好的 QoS效能。繼開源了 Windows 端後,我們陸續支援了移動端的能力,本文主要基於開源播放器 ijkplayer,介紹 LLS-Player 移動端的接入和最佳化實踐。

LLS-Player 下載

LLS-Player 基於 WebRTC M94 版本進行開發,程式碼包含 WebRTC 的 patch 程式碼以及其他的原始碼檔案。需要先下載 WebRTC 原生程式碼,然後下載網易雲信的低延時直播程式碼 LLS-Player,最後將 LLS-Player 程式碼覆蓋到 WebRTC 原生程式碼中。

下載 WebRTC M94 原始碼

WebRTC 對應的程式碼分支和 commitId 如下,根據下面的步驟操作即可下載對應的原始碼。

// 以iOS為例
mkdir webrtc
cd webrtc
fetch --nohooks webrtc_ios  // 拉取WebRTC程式碼
cd src
git checkout -b m94 branch-heads/4606  // 此處基於4606建立m94分支。
git reset --hard  b83487f08ff836437715b488f73416215e5570dd  // 重置到我們使用的版本。
gclient sync

下載 LLS-Player 原始碼

git clone https://github.com/GrowthEase/LLS-Player.git

程式碼下載後,將 LLS-Player/src 目錄下所有檔案覆蓋到上面下載的 WebRTC M94 版本中。

程式碼編譯

Mac 開啟 Shell,切換到 src 目錄,執行如下命令:

// 編譯iOS版本
./build_ios.sh --allarch copy

// 編譯android版本,例如arm64-v8a架構
./build_android.sh arm64 --enable-shared

編譯完成後,iOS 在 src/rtd/project/ios/out/ 目錄下會生成動態庫 rtd.framework 和靜態庫 librtd.a;android在src/out/andorid_arm64 目錄下會生成動態庫 librtd.so和對應的 libc++_shared.so。

LLS-Player 整合

LLS-Player 輸出的影片格式為 H264,音訊格式為 PCM。基於 FFMPEG 開發的播放器整合 LLS-Player 和封裝的 rtddemuxer,透過 FFMPEG 原生的介面,就可以實現低延時的播放邏輯。下面以 ijkplayer 為例,介紹整合 LLS-Player 的流程。

Android 端整合

匯入動態庫和標頭檔案

將動態庫和標頭檔案複製到指定的庫目錄下

將 librtd.so 放入對應架構的路徑中:

ijkplayer/android/contrib/build/ffmpeg-$arch/output

標頭檔案 nertd_api.h 和 rtd_def.h 放入對應架構的路徑中 :

ijkplayer/android/contrib/build/ffmpeg-$arch/output/include

修改編譯指令碼

修改  

android/ijkplayer/ijkplayer-$arch/src/main/jni/ffmpeg/Android.mk  檔案,如下圖所示:

新增 rtd_dec.c 和動態庫依賴

將 rtd_dec.c 檔案複製到工程的原始碼目錄下參與編譯,例如 ijkplayer 中放到 ijkavformat 目錄下。修改 ijkplayer/ijkmedia/ijkplayer/Android.mk 檔案。

iOS 端整合

匯入動態庫和標頭檔案

將 rtd.framework 或者 librtd.a 放入 ijkplayer/ios/build/universal/lib目錄下。

標頭檔案nertd_api.h和rtd_def.h放入ijkplayer/ios/build/universal/include目錄下

新增 rtd_dec.c 和庫檔案

將 rtd_dec.c 檔案複製到工程的原始碼目錄下參與編譯,例如 ijkplayer 中放到 ijkavformat 目錄下。以 rtd.framework 為例,庫檔案的依賴如下圖所示:

ijkplayer 修改

在 ff_ffplay.c 中新增低延時拉流的邏輯:

  • 包含標頭檔案和必要的變數宣告
#include "rtd_api.h" // 設定好標頭檔案路徑即可

extern AVInputFormat ff_rtd_demuxer;

* 註冊低延時拉流協議

在 read_thread() 函式里,從 url 中區分出低延時拉流協議頭,例如("nertc"),設定 AVInputFormat 為 ff_rtd_demuxer。

以上都需要在 avformat_open_input() 之前設定,avformat_open_input() 最後一個引數需要設定 options。


if (strncmp(is->filename, "nertc://", 8) == 0) { // 設定AVInputFormat 為ff_rtd_demuxer
    is->iformat = &ff_rtd_demuxer;
}

// 上述程式碼在avformat_open_input前
err = avformat_open_input(&ic, is->filename, is->iformat, &ffp->format_opts);

編譯播放器

上述設定完成後需要重新編譯播放器工程。

android 端執行如下指令碼:


./compile-ijk.sh all

iOS 端開啟工程,直接編譯即可。

播放最佳化

完成上述設定後,輸入 nertc:// 開頭的拉流地址,就可以體驗低延時直播。

LLS-Player 回撥的是 H264 和 PCM 資料,由於 LLS-Player 中的影片 jitterBuffer 和音訊 NetEQ 中有音影片包的快取和追幀邏輯,能夠保持低延時和流暢性之間的平衡。因此,播放器層的緩衝區水位可以儘量的小,達到極致低延時的效果。

下圖是 LLS-Player 端到端延時的效果展示,LLS-Player 的 jitterBuffer 大小設定成 200ms,播放器層的 buffer 水位為 0,採用 OBS 推流,可以看到端到端延時在 550ms 左右。當然不同的業務場景下對延時的要求不太一樣,可以根據實際情況進行調整。

網易智企【易+】開源計劃已正式釋出網易雲信低延時直播方案。

檢視網易雲信低延時播放器原始碼:

https://github.com/GrowthEase/LLS-Player

https://gitee.com/GrowthEase/lls-player

相關文章