本文詳細說明Flutter推流SDK基本使用流程,以及相關功能的使用樣本。
Flutter推流SDK特性
支援RTMP推流協議。
支援基於UDP的ARTC協議推流。
使用視頻H.264編碼以及音頻AAC編碼。
支援碼控、解析度、顯示模式等自訂配置。
支援多種網路攝影機相關操作。
支援即時美顏和自訂美顏效果調節。
支援增、刪動態貼紙實現動態浮水印效果。
支援自訂YUV、PCM等外部音視頻輸入。
支援純音視頻推流以及後台推流。
支援背景音樂及其相關操作。
可使用視訊截圖功能。
支援自動重連、異常處理。
支援音頻3A演算法。
增加視頻軟編、硬編切換邏輯,提升編碼模組穩定性。
功能限制
Flutter直播推流SDK需注意以下限制:
您只能在推流之前設定橫豎屏模式,不支援在直播的過程中即時切換。
在推流設定為橫屏模式時,需設定介面為不允許自動旋轉。
在硬編模式下,考慮編碼器相容問題解析度會使用16的倍數,如設定為540P,則輸出的解析度為544*960,在設定播放器視圖大小時需按輸出解析度等比縮放,避免黑邊等問題。
使用流程
基本使用流程如下:
步驟 | 描述 |
一、註冊SDK | 配置License相關參數,註冊推流SDK。若不調用註冊函數,推流功能無法使用。 |
二、配置推流參數 | 完成推流基本配置、碼率控制配置、解析度自適應配置等。 |
三、進行推流 | 初始化SDK、註冊推流回調、建立預覽視圖後可以開始推流。使用者可以根據業務需求添加推流量控制、設定背景音樂、網路攝影機、外部音頻、動態貼紙等。 說明 阿里雲ApsaraVideo for Live不允許同一時間向同一個推流URL進行多路推流(第二路推流會被拒絕)。 |
註冊SDK
Flutter推流SDK已接入一體化License服務,申請並配置License請參見推流SDK License整合指南。
在使用推流功能前必須進行註冊,否則無法使用推流SDK功能。
註冊SDK。
重要在調用註冊SDK方法前,需要提前配置License。
AlivcLiveBase.registerSDK();
設定監聽回調介面。
AlivcLiveBase.setListener(AlivcLiveBaseListener( onLicenceCheck: (AlivcLiveLicenseCheckResultCode result, String reason) { if (result == AlivcLiveLicenseCheckResultCode.success) { /// 註冊SDK成功 } }, ));
使用AlivcLiveBase其它介面。
/// 擷取原生直播推流SDK版本號碼 String sdkVersion = await AlivcLiveBase.getSdkVersion(); /// 啟用控制台日誌列印 AlivcLiveBase.setConsoleEnable(true); /// 設定log層級為Debug調試層級 AlivcLiveBase.setLogLevel(AlivcLivePushLogLevel.debug); /// 每個分區最大大小,最終日誌總體積是最大分區大小的5倍 const int saveLogMaxPartFileSizeInKB = 100 * 1024 * 1024; /// 日誌路徑 String saveLogDir = "TODO"; /// 設定日誌路徑及日誌分區大小 AlivcLiveBase.setLogPath(saveLogDir, saveLogMaxPartFileSizeInKB);
配置推流參數
建立AlivcLivePusher執行個體。
AlivcLivePusher livePusher = AlivcLivePusher.init();
建立Config,將AlivcLivePusherConfig同AlivcLivePusher聯絡起來。
livePusher.createConfig();
建立AlivcLivePusherConfig執行個體。
AlivcLivePusherConfig pusherConfig = AlivcLivePusherConfig.init();
設定推流參數根據使用情境,自訂設定。
基本推流配置對應參數都有預設值,建議採用預設值,即您可以進行簡單初始化,不做配置。 範例程式碼如下:
/// 設定解析度為540P pusherConfig.setResolution(AlivcLivePushResolution.resolution_540P); /// 設定視頻採集幀率為20fps。建議使用者使用20fps pusherConfig.setFps(AlivcLivePushFPS.fps_20); /// 開啟碼率自適應,預設為true pusherConfig.setEnableAutoBitrate(true); /// 設定主要畫面格間隔。主要畫面格間隔越大,延時越高。建議設定為1-2 pusherConfig.setVideoEncodeGop(AlivcLivePushVideoEncodeGOP.gop_2); /// 設定重連時間長度為2s。單位為毫秒,設定不小於1秒,建議使用預設值即可。 pusherConfig.setConnectRetryInterval(2000); /// 設定預覽鏡像為關閉 pusherConfig.setPreviewMirror(false); /// 設定推流方向為豎屏 pusherConfig.setOrientation(AlivcLivePushOrientation.portrait);
配置碼率控制。
碼率控制通過AlivcLivePushQualityMode枚舉參數配置。推流SDK提供以下碼率控制模式,請根據實際需求修改參數值。
碼率控制模式
描述
範例程式碼
AlivcLivePushQualityMode.resolution_first
清晰度優先模式。SDK內部會對碼率參數進行配置,優先保障推流視頻的清晰度。
pusherConfig.setQualityMode(AlivcLivePushQualityMode.resolution_first);
AlivcLivePushQualityMode.fluency_first
流暢度優先模式。SDK內部會對碼率參數進行配置,優先保障推流視頻的流暢度。
pusherConfig.setQualityMode(AlivcLivePushQualityMode.fluency_first);
AlivcLivePushQualityMode.custom
自訂模式。SDK會根據開發人員設定的碼率進行配置。設定為自訂模式時,您可以選擇配置畫質優先或者流暢度優先,並自行設定初始碼率、最小碼率和目標碼率。
初始碼率:開始直播時的碼率。
最小碼率:當網路較差時,碼率會逐步減低到最小碼率,以減少視頻的卡頓。
目標碼率:當網路較好時,碼率會逐步提高到目標碼率,以提高視頻清晰度。
pusherConfig.setQualityMode(AlivcLivePushQualityMode.custom);
說明選擇清晰度優先或流暢度優先模式時,不需設定初始碼率、最小碼率和目標碼率(setInitialVideoBitrate、setMinVideoBitrate、setTargetVideoBitrate)。推流SDK內部策略會自動保障在網路抖動情況下優先考慮視頻清晰度或流暢度。
選擇自訂碼率時,請參考阿里雲推薦設定配置對應碼率。推薦設定請參考下表內容。
自訂碼率控制推薦設定(畫質優先)
解析度
初始碼率 initialVideoBitrate
最小碼率 minVideoBitrate
目標碼率 targetVideoBitrate
360P
600
300
1000
480P
800
300
1200
540P
1000
600
1400
720P
1500
600
2000
1080P
1800
1200
2500
自訂碼率控制推薦設定(流暢度優先)
解析度
初始碼率 initialVideoBitrate
最小碼率 minVideoBitrate
目標碼率 targetVideoBitrate
360P
400
200
600
480P
600
300
800
540P
800
300
1000
720P
1000
300
1200
1080P
1500
1200
2200
配置解析度自適應。
解析度自適應即動態調整推流解析度。開啟功能後,當網路較差時會自動降低解析度以提高視頻的流暢度和清晰度。範例程式碼如下:
/// 設定開啟解析度自適應 pusherConfig.setEnableAutoResolution(true);
重要某些播放器可能不支援動態解析度,如果您需要使用解析度自適應功能,建議使用阿里雲播放器。
解析度自適應只有在清晰度優先或流暢度優先時才會生效(AlivcLivePushQualityMode枚舉參數配置),自訂模式時無效。
配置圖片推流。
為了更好的使用者體驗,推流SDK提供了後台圖片推流和碼率過低時進行圖片推流的設定。當SDK退至後台時預設暫停推流視頻,只推流音頻,此時可以設定圖片來進行圖片推流和音頻推流。範例程式碼如下:
/// 設定暫停圖片 String pauseImagePath = "xxxx"; // xxxx為手機存放的圖片路徑 pusherConfig.setPauseImg(pauseImagePath);
另外,當網路較差時您可以根據自己的需求設定推流一張靜態圖片。設定圖片後,SDK檢測到當前碼率較低時,會推流此圖片,避免視頻流卡頓。範例程式碼如下所示:
/// 設定網路差圖片 String networkPoorImagePath = "xxxx"; // xxxx為手機存放的圖片路徑 pusherConfig.setNetworkPoorImg(networkPoorImagePath);
配置預覽顯示模式。
推流SDK支援三種預覽模式,預覽顯示模式不影響推流。
AlivcPusherPreviewDisplayMode.preview_scale_fill:預覽顯示時,鋪滿視窗。當視頻比例和視窗比例不一致時,預覽會有變形。
AlivcPusherPreviewDisplayMode.preview_aspect_fit:預覽顯示時,保持視頻比例。當視頻比例與視窗比例不一致時,預覽會有黑邊。
AlivcPusherPreviewDisplayMode.preview_aspect_fill:預覽顯示時,剪下視頻以適配視窗比例。當視頻比例和視窗比例不一致時,預覽會裁剪視頻。
範例程式碼如下:
/// 設定預覽顯示模式為保持視頻比例 pusherConfig.setPreviewDisplayMode(AlivcPusherPreviewDisplayMode.preview_aspect_fit);
iOS系統下重設config。
iOS系統下不再使用[AlivcLivePusherConfig時,建議主動調用下該方法,重設原生config對象,下次再建立時恢複為預設狀態。
建議在AlivcLivePusher已經調用destroy的情況下調用該方法。
/// iOS系統下重設config livePusher.destroyConfigForIOS();
進行推流
建立推流引擎執行個體。
livePusher.initLivePusher();
註冊推流監聽回調。
/// 設定推流狀態監聽回調 livePusher.setInfoDelegate(); /// 設定推流錯誤監聽回調 livePusher.setErrorDelegate(); /// 設定推流網路監聽回調 livePusher.setNetworkDelegate();
監聽推流相關回調。
/// 推流錯誤監聽回調 /// 系統錯誤回調 livePusher.setOnSDKError((errorCode, errorDescription) {}); /// 系統錯誤回調 livePusher.setOnSystemError((errorCode, errorDescription) {}); /// 推流狀態監聽回調 /// 開始預覽回調 livePusher.setOnPreviewStarted(() {}); /// 停止預覽回調 livePusher.setOnPreviewStoped(() {}); /// 渲染第一幀回調 livePusher.setOnFirstFramePreviewed(() {}); /// 推流開始回調 livePusher.setOnPushStarted(() {}); /// 網路攝影機推流暫停回調 livePusher.setOnPushPaused(() {}); /// 網路攝影機推流恢複回調 livePusher.setOnPushResumed(() {}); /// 重新推流回調 livePusher.setOnPushRestart(() {}); /// 推流停止回調 livePusher.setOnPushStoped(() {}); /// 推流網路監聽回調 /// 推流連結失敗 livePusher.setOnConnectFail((errorCode, errorDescription) {}); /// 網路恢複 livePusher.setOnConnectRecovery(() {}); /// 串連被斷開 livePusher.setOnConnectionLost(() {}); /// 網路差回調 livePusher.setOnNetworkPoor(() {}); /// 重連失敗回調 livePusher.setOnReconnectError((errorCode, errorDescription) {}); /// 重連開始回調 livePusher.setOnReconnectStart(() {}); /// 重連成功回調 livePusher.setOnReconnectSuccess(() {});
建立推流預覽視圖。
var x = 0.0; // 自訂數值 var y = 0.0; // 自訂數值 var width = MediaQuery.of(context).size.width; // 自訂數值 var height = MediaQuery.of(context).size.height; // 自訂數值 AlivcPusherPreview pusherPreviewView = AlivcPusherPreview( onCreated: _onPusherPreviewCreated, x: x, y: y, width: width, height: height); return Container( color: Colors.black, width: width, height: height, child: pusherPreviewView);
開始預覽。
/// 視圖建立回調 _onPusherPreviewCreated(id) { /// 開始預覽 livePusher.startPreview(); }
說明如果flutter工程設定的螢幕方向是豎屏,在設定推流方向setOrientation為橫屏時,此時手動調用旋屏方法建立推流預覽視圖的時候,在視圖建立回調調用開始預覽startPreview方法之後,如果出現預覽渲染畫面沒有鋪滿設定的預覽視圖大小,則建議在調用開始預覽方法之前手動執行下延遲一段時間再調用,比如延遲100ms:
Future.delayed(Duration(milliseconds: 100));
開始推流。預覽成功後才可以開始推流。
String pushURL = "推流測試地址(rtmp://......)"; livePusher.startPushWithURL(pushURL);
設定其他推流量控制。
/// 暫停網路攝影機推流。可以調用[setPauseImg]後調用[pause]介面,從網路攝影機推流切換成靜態圖片推流,音頻推流繼續。 livePusher.pause(); /// 從靜態圖片推流切換成網路攝影機推流,音頻推流繼續 livePusher.resume(); /// 推流狀態下可調用停止推流,完成後推流停止 livePusher.stopPush(); /// 在預覽狀態下才可以調用停止預覽,正在推流狀態下,調用停止預覽無效。預覽停止後,預覽畫面定格在最後一幀 livePusher.stopPreview(); /// 推流狀態下或者接收到所有Error相關回調狀態下可調用重新推流,且Error狀態下只可以調用此介面(或者[reconnectPushAsync]重連)或者調用[destory]銷毀推流。完成後重新開始推流,重啟[AlivcLivePusher]內部的一切資源,包括預覽、推流等等restart livePusher.restartPush(); /// 推流狀態下或者接收到[setNetworkDelegate]相關的Error回調狀態下可調用此介面, 且Error狀態下只可以調用此介面(或者[restartPush]重新推流)或者調用[destory]銷毀推流。完成後推流重連,重新連結推流 livePusher.reconnectPushAsync(); /// 銷毀推流後,推流停止,預覽停止,預覽畫面移除。[AlivcLivePusher]相關的一切資源銷毀 livePusher.destory();
設定背景音樂。
/// 開始播放背景音樂 String musicPath = "xxxx"; // xxxx為手機存放的音樂資源路徑 livePusher.startBGMWithMusicPathAsync(musicPath); /// 停止播放背景音樂。若當前現正播放BGM,並且需要切換歌曲,只需要調用開始播放背景音樂介面即可,無需停止當前現正播放的背景音樂 livePusher.stopBGMAsync(); /// 暫停播放背景音樂,背景音樂開始播放後才可調用此介面 livePusher.pauseBGM(); /// 恢複播放背景音樂,背景音樂暫停狀態下才可調用此介面 livePusher.resumeBGM(); /// 開啟迴圈播放音樂 livePusher.setBGMLoop(true); /// 設定降噪開關。開啟降噪後,將對採集到的聲音中非人聲的部分進行過濾處理。可能存在對人聲稍微抑製作用,建議讓使用者自由選擇是否開啟降噪功能,預設不使用 livePusher.setAudioDenoise(true); /// 設定耳返開關。耳返功能主要應用於KTV情境。開啟耳返後,插入耳機將在耳機中聽到主播說話聲音。關閉後,插入耳機無法聽到人聲。未插入耳機的情況下,耳返不起作用 livePusher.setBGMEarsBack(true); /// 混音設定,設定背景音樂音量 livePusher.setBGMVolume(50); // 設定數值範圍:[0 ~ 100],預設:50 /// 混音設定,設定人聲採集音量 livePusher.setCaptureVolume(50); // 設定數值範圍:[0 ~ 100] 預設:50 /// 設定靜音。靜音後音樂聲音和人聲輸入都會靜音。要單獨設定音樂或人聲靜音可以通過混音音量設定介面來調整 livePusher.setMute(true);
監聽背景音樂相關回調。
/// 背景音樂播放完畢 livePusher.setOnBGMCompleted(() {}); /// 背景音樂下載播放逾時 livePusher.setOnBGMDownloadTimeout(() {}); /// 背景音樂開啟失敗 livePusher.setOnBGMOpenFailed(() {}); /// 背景音樂暫停播放 livePusher.setOnBGMPaused(() {}); /// 背景音樂當前播放進度 livePusher.setOnBGMProgress((progress, duration) {}); /// 背景音樂恢複播放 livePusher.setOnBGMResumed(() {}); /// 背景音樂開始播放 livePusher.setOnBGMStarted(() {}); /// 背景音樂停止播放 livePusher.setOnBGMStoped(() {});
設定推流截圖。
/// 調用截圖 String dir = "xxxx"; // xxxx代表設定路徑 if (Platform.isIOS) { /// dir設定要求:iOS系統下是指定存放相對的路徑,會在系統沙箱路徑下自動產生自訂的目錄,設定為""時,則儲存在系統沙箱路徑下。 /// dirTypeForIOS:可選設定。不設定預設是放在系統沙箱的[document]路徑下。 livePusher.snapshot(1, 0, dir, dirTypeForIOS: AlivcLiveSnapshotDirType.document); } else { livePusher.snapshot(1, 0, dir); } /// 設定截圖回調,需要在調用[snapshot]後調用 livePusher.setSnapshotDelegate(); /// 監聽截圖回調 livePusher.setOnSnapshot((saveResult, savePath, {dirTypeForIOS}) { // 截圖儲存成功 if (saveResult == true) { if (Platform.isIOS) { // 根據dirTypeForIOS + savePath拼接擷取沙箱路徑下的完整截圖儲存路徑 } else { // 根據savePath擷取SD下的截圖儲存路徑 } } });
網路攝影機相關操作。
/// 切換前後網路攝影機 livePusher.switchCamera(); /// 開啟/關閉閃光燈,在自拍時開啟閃關燈無效 livePusher.setFlash(false); /// 焦距調整,即可實現採集畫面的縮放功能。傳入參數為正數,則放大焦距,傳入參數為負數則縮小焦距 double max = await livePusher.getMaxZoom(); livePusher.setZoom(min(1.0, max)); /// 手動對焦 /// [autoFocus]參數表示是否需要自動對焦,該參數僅對調用介面的該次對焦操作生效。後續是否自動對焦沿用上述自動聚焦介面設定值。 double pointX = 50.0; // 自訂數值 double pointY = 50.0; // 自訂數值 bool autoFocus = true; livePusher.focusCameraAtAdjustedPoint(pointX, pointY, autoFocus); /// 設定不開啟自動對焦 livePusher.setAutoFocus(false); /// 設定不開啟預覽鏡像 livePusher.setPreviewMirror(false); /// 設定不開啟推流鏡像 livePusher.setPushMirror(false);
配置浮水印。推流SDK提供了添加浮水印功能,並且最多支援添加多個浮水印,浮水印圖片必須為PNG格式圖片。範例程式碼如下:
String watermarkBundlePath = "xxxx"; //xxxx為手機存放的浮水印圖片資源路徑 double coordX = 0.1; double coordY = 0.1; double width = 0.3; /// 添加浮水印 livePusher.addWatermark(watermarkBundlePath, coordX, coordY, width);
說明coordX、coordY、width為相對值,例如coordX:0.1表示浮水印的x值為推流畫面x軸的10%位置,如果推流解析度為540*960,則浮水印x值為54。
浮水印圖片的高度,按照浮水印圖片的真實寬高與輸入的width值等比縮放。
要實現文字浮水印,可以先將文字轉換為圖片,再使用此介面添加浮水印。
為了保障浮水印顯示的清晰度與邊緣平滑,請您盡量使用和浮水印輸出尺寸相同大小的浮水印源圖片。如輸出視頻解析度544*940,浮水印顯示的w是0.1f,則盡量使用浮水印源圖片寬度在544*0.1f=54.4左右。
配置外部音視頻輸入。推流SDK支援將外部的音視頻源輸入進行推流,比如推送一個音視頻檔案。
在推流配置裡面進行外部音視頻輸入配置。
/// 開啟允許外部流輸入 pusherConfig.setExternMainStream(true); /// 設定視頻資料顏色格式定義,這裡設定為YUVNV21,可根據需求設定為其他格式。 pusherConfig.setExternVideoFormat(AlivcLivePushVideoFormat.YUVNV21); /// 設定音頻資料位元深度格式,這裡設定為S16,可根據需求設定為其他格式 pusherConfig.setExternMainStream(AlivcLivePushAudioFormat.S16);
插入外部視頻資料。
/// 只支援外部視頻yuv和rbg格式的連續buffer資料,才可以通過sendVideoData介面,發送視頻資料buffer、長度、寬高、時間戳記、旋轉角度 Uint8List bufferData = xxxx; // xxxx代表Uint8List格式的連續buffer視頻資料 int width = 720; // 視頻寬度 int height = 1280; // 視頻高度 int dataSize = xxxx; // xxxx代表data資料大小 int pts = xxxx; // xxxx代表時間戳記(單位微秒) int rotation = 0; // 旋轉角度 livePusher.sendVideoData(bufferData, width, height, size, pts, rotation);
插入外部音頻資料。
/// 只支援外部pcm格式的連續buffer資料,sendPCMData,發送音頻資料buffer、長度、時間戳記 Uint8List bufferData = xxxx; // xxxx代表Uint8List格式的連續buffer音頻資料 int dataSize = xxxx; // xxxx代表data資料大小 int sampleRate = xxxx; // xxxx代表採樣率 int channel = 0; // 聲道數 int pts = xxxx; // xxxx代表時間戳記(單位微秒) livePusher.sendPCMData(bufferData, size, sampleRate, channel, pts);
添加美顏
Flutter推流SDK提供外掛程式化的美顏處理能力。如需使用美顏功能,請在SDK下載與發布記錄中,下載源碼壓縮包,找到demo目錄下plugins裡面的flutter_livepush_beauty_plugin外掛程式,配合使用。注意:美顏外掛程式不對外發布。
/// 1.初始化美顏對象
AlivcLiveBeautyManager beautyManager = AlivcLiveBeautyManager.init();
beautyManager.setupBeauty();
/// 2.開啟美顏面板
beautyManager.showPanel();
/// 3.關閉美顏面板(安卓使用)
beautyManager.hidePanel();
/// 4.銷毀美顏對象
beautyManager.destroyBeauty();