騰訊直播Android端推流sdk


https://www.qcloud.com/document/product/454/7885

基礎知識

推流 是指將音視頻數據采集編碼之后,推送到您指定的視頻雲平台上,這里涉及大量的音視頻基礎知識,而且需要長時間的打磨和優化才能達到符合預期的效果。

騰訊視頻雲 SDK 主要幫您解決在智能手機上的推流問題,它的接口非常簡單易用,只需要一個推流URL就能驅動:

特別說明

  • 不綁定騰訊雲

    SDK 不綁定騰訊雲,如果要推流到非騰訊雲地址,請在推流前設置 TXLivePushConfig 中的 enableNearestIP 設置為 NO。但如果您要推流的地址為騰訊雲地址,請務必在推流前將其設置為 YES,否則推流質量可能會因為運營商 DNS 不准確而受到影響。

准備工作

代碼對接

本篇攻略主要是面向攝像頭直播的解決方案,該方案主要用於美女秀場直播、個人直播以及活動直播等場景。

step 1: 添加界面元素

為了能夠展示攝像頭預覽的影像,您需要在您的布局xml文件里加入如下一段代碼,他會在您的UI上安插一個TXCloudVideoView控件,這是我們用來顯示攝像頭影像的專用控件:

<com.tencent.rtmp.ui.TXCloudVideoView android:id="@+id/video_view" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerInParent="true" android:visibility="gone"/> 

step 2: 創建Pusher對象

創建一個TXLivePusher對象,我們后面主要用它來完成推流工作。

不過在創建 LivePush 對象之前,還需要您指定一個LivePushConfig對象,該對象的用途是決定 LivePush 推流時各個環節的配置參數,比如推流用多大的分辨率、每秒鍾要多少幀畫面(FPS)以及Gop(表示多少秒一個I幀)等等。

LivePushConfig 在new出來之后便已經裝配了一些我們反復調過的參數,如果您不需要自己定制這些配置,簡單地塞給LivePush對象就可以了。如果您有相關領域的經驗基礎,需要對這些默認配置進行調整,可以閱讀進階篇中的內容。

TXLivePusher mLivePusher = new TXLivePusher(getActivity()); mLivePushConfig = new TXLivePushConfig(); mLivePusher.setConfig(mLivePushConfig); 

step 3: 啟動推流

經過step1 和 step2 的准備之后,用下面這段代碼就可以啟動推流了:

String rtmpUrl = "rtmp://2157.livepush.myqcloud.com/live/xxxxxx"; mLivePusher.startPusher(rtmpUrl); TXCloudVideoView mCaptureView = (TXCloudVideoView) view.findViewById(R.id.video_view); mLivePusher.startCameraPreview(mCaptureView); 
  • startPusher 的作用是告訴 SDK 音視頻流要推到哪個推流URL上去。
  • startCameraPreview 則是將界面元素和Pusher對象關聯起來,從而能夠將手機攝像頭采集到的畫面渲染到屏幕上。

step 4: 設定清晰度

使用 setVideoQuality 接口的可以設定推流的畫面清晰度:

  • quality
    SDK 提供了六種基礎檔位,根據我們服務大多數客戶的經驗進行積累和配置。其中 STANDARD、HIGH、SUPER 適用於直播模式,MAIN_PUBLISHER 和 SUB_PUBLISHER 適用於連麥直播中的大小畫面,VIDEOCHAT 用於實時音視頻。

  • adjustBitrate
    是否開啟 Qos 流量控制,開啟后SDK 會根據主播上行網絡的好壞自動調整視頻碼率。相應的代價就是,主播如果網絡不好,畫面會很模糊且有很多馬賽克。

  • adjustResolution
    是否允許動態分辨率,開啟后 SDK 會根據當前的視頻碼率選擇相匹配的分辨率,這樣能獲得更好的清晰度。相應的代價就是,動態分辨率的直播流所錄制下來的文件,在很多播放器上會有兼容性問題。

step 5: 美顏濾鏡

  • 美顏
    setBeautyFilter 接口可以設置美顏和美白級別,兩者的調整級別都是 0 至 9,0 表示不啟用美顏,1.9.1 版本開始美顏效果做了明顯的優化,配合 540 * 960 分辨率(setVideoQuality - VIDEO_QUALITY_HIGH_DEFINITION),可以達到最佳的畫質效果:

    mLivePusher.setBeautyFilter(7, 3); 
  • 濾鏡
    setFilter 接口可以設置濾鏡效果,濾鏡本身是一張直方圖文件,我們設計師團隊提供了八種素材,默認打包在了Demo中,您可以隨意使用,不用擔心版權問題。

    Bitmap bmp = null; bmp = decodeResource(getResources(), R.drawable.langman); if (mLivePusher != null) { mLivePusher.setFilter(bmp); } 

    如果要自定義濾鏡,一定要用 PNG 格式的圖片,不要用 JPG,不要用 JPG,不要用 JPG...

  • 曝光
    setExposureCompensation 可以調節曝光值,這個調整項在 iOS 端是沒有的(我們使用了系統的自動曝光)。但是 Android 機型差異太大,很多千元機的自動曝光效果實在一般,所以我們還是推薦在您的 UI 界面上提供一個自動曝光的操作滑竿,讓主播可以自己調節曝光值大小。

    setExposureCompensation 的參數為 -1 到 1 的浮點數: 0 表示不調整, -1 是將曝光降到最低, 1 表示是將曝光加強到最高。

step 6: 控制攝像頭

  • 切換前置或后置攝像頭
    默認是使用前置攝像頭(可以通過修改 TXLivePushConfig 的配置函數 setFrontCamera 來修改這個默認值),調用一次switchCamera 切換一次,注意切換攝像頭前必須保證 TXLivePushConfig 和 TXLivePusher 對象都已經初始化。
    // 默認是前置攝像頭 mLivePusher.switchCamera(); 
  • 打開或關閉閃光燈
    只有后置攝像頭才可以打開閃光燈,另外該接口需要在啟動預覽之后調用
    //mFlashTurnOn為true表示打開,否則表示關閉 if (!mLivePusher.turnOnFlashLight(mFlashTurnOn)) { Toast.makeText(getActivity().getApplicationContext(), "打開閃光燈失敗:絕大部分手機不支持前置閃光燈!", Toast.LENGTH_SHORT).show(); } 
  • 攝像頭自動或手動對焦
    大部分后置攝像頭才支持對焦,SDK 支持兩種對焦模式:手動對焦和自動對焦。
    自動對焦是系統提供的能力,但有些機型並不支持自動對焦。手動對焦和自動對焦是互斥的,開啟自動對焦后,手動對焦將不生效。
    SDK 默認配置是手動對焦,您可以通過 TXLivePushConfig 的配置函數 setTouchFocus 接口進行切換:
    mLivePushConfig.setTouchFocus(mTouchFocus); mLivePusher.setConfig(mLivePushConfig); 

step 7: 設置Logo水印

最近相關政策規定,直播的視頻必須要打上水印,所以這個之前看起來並不是特別起眼的功能現在要重點說一下:
騰訊視頻雲目前支持兩種水印設置方式:一種是在推流SDK進行設置,原理是在SDK內部進行視頻編碼前就給畫面打上水印。另一種方式是在雲端打水印,也就是雲端對視頻進行解析並添加水印Logo。

這里我們特別建議您使用SDK添加水印,因為在雲端打水印有三個明顯的問題:
(1)這是一種很耗雲端機器的服務,而且不是免費的,會拉高您的費用成本;
(2)在雲端打水印對於推流期間切換分辨率等情況的兼容並不理想,會有很多花屏的問題發生。
(3)在雲端打水印會引入額外的3s以上的視頻延遲,這是轉碼服務所引入的。

SDK所要求的水印圖片格式為png,因為png這種圖片格式有透明度信息,因而能夠更好地處理鋸齒等問題。(您可千萬別把jpg圖片在windows下改個后綴名就塞進去了,專業的png圖標都是需要由專業的美工設計師處理的)

//設置視頻水印 mLivePushConfig.setWatermark(BitmapFactory.decodeResource(getResources(),R.drawable.watermark), 10, 10); mLivePusher.setConfig(mLivePushConfig); 

step 8: 硬件編碼

TXLivePushConfig 中的 setHardwareAcceleration 設置接口可以開啟或關閉硬件編碼。

if (!HWSupportList.isHWVideoEncodeSupport()){ Toast.makeText(getActivity().getApplicationContext(), "當前手機型號未加入白名單或API級別過低(最低18),請慎重開啟硬件編碼!", Toast.LENGTH_SHORT).show(); } mLivePushConfig.setHardwareAcceleration(mHWVideoEncode); mLivePusher.setConfig(mLivePushConfig); 

mHWVideoEncode 有以下選項。

硬件加速選項 含義
ENCODE_VIDEO_HARDWARE 開啟硬件加速
ENCODE_VIDEO_SOFTWARE 禁用硬件加速,默認禁用硬件加速
ENCODE_VIDEO_AUTO 自動選擇是否啟用硬件加速
  • 兼容性評估
    Android 手機目前對硬件加速的支持已較前兩年有明顯的進步,目前支持度還是不錯的,但仍有個別機型有兼容性問題,目前 RTMP SDK 通過一個內部的黑名單進行控制,避免在部分兼容性差的機型上出現問題。如果您使用硬件編碼失敗,SDK 內部會自動切換為軟件編碼。

  • 效果差異
    開啟硬件加速后手機耗電量會有明顯降低,機身溫度也會比較理想,但畫面大幅運動時馬賽克感會比軟編碼要明顯很多,而且越是早起的低端機,馬賽克越是嚴重。所以如果您是對畫質要求很高的客戶,不推薦開啟硬件加速。

  • 推薦的設計
    我們在 setVideoQuality 的高清檔(推薦檔位)和標清檔均推薦使用軟件編碼,如果您擔心CPU和發熱問題,可以做一個簡單的保護邏輯:

    如果發現推流的 FPS ( 通過 TXLivePushListener 的 NET_STATUS_VIDEO_FPS 事件可以獲知 ) 持續過低,比如半分鍾內持續低於 10 幀/秒,表示 CPU 負載過重,則切換為硬編碼。

step 9: 后台推流

常規模式下,App一旦切到后台,攝像頭的采集能力就被 Android 系統停掉了,這就意味着 SDK 不能再繼續采集並編碼出音視頻數據。如果我們什么都不做,那么故事將按照如下的劇本發展下去:

  • 階段一(切后台開始 -> 之后的10秒內)- CDN因為沒有數據所以無法向觀眾提供視頻流,觀眾看到畫面卡主。
  • 階段二(10秒 -> 70秒內)- 觀眾端的播放器因為持續收不到直播流而直接退出,直播間已經人去樓空。
  • 階段三(70秒以后)- 推流的 RTMP 鏈路被服務器直接斷掉,主播需要重新開啟直播才能繼續。
    主播可能只是短暫接個緊急電話而已,但各雲商的安全保護措施會讓主播的直播被迫提前結束。

我們可以采用如下方案規避:

  • 9.1) 設置pauseImg
    在開始推流前,使用 TXLivePushConfig 的 setPauseImg 接口設置一張等待圖片,圖片含義推薦為“主播暫時離開一下下,稍后回來”。
  • 9.2) 設置setPauseFlag
    在開始推流前,使用 TXLivePushConfig 的 setPauseFlag 接口設置切后台pause推流時需要停止哪些采集,停止視頻采集則會推送pauseImg設置的默認圖,停止音頻采集則會推送靜音數據。

    setPauseFlag(PAUSE_FLAG_PAUSE_VIDEO|PAUSE_FLAG_PAUSE_AUDIO);//表示同時停止視頻和音頻采集,並且推送填充用的音視頻流;

    setPauseFlag(PAUSE_FLAG_PAUSE_VIDEO);//表示停止攝像頭采集視頻畫面,但保持麥克風繼續采集聲音,用於主播更衣等場景;

  • 9.3) 切后台處理
    推流中,如果App被切了后台,調用 TXLivePusher 中的 pausePush 接口函數,之后,SDK 雖然采集不到攝像頭的畫面了,但可以用您剛才設置的 PauseImg 持續推流。

    // activity 的 onStop 生命周期函數 @Override public void onStop(){ super.onStop(); mCaptureView.onPause(); // mCaptureView 是攝像頭的圖像渲染view mLivePusher.pausePusher(); // 通知 SDK 進入“后台推流模式”了 } 
  • 9.4) 切前台處理
    等待App切回前台之后,調用 TXLivePusher 的 resumePush 接口函數,之后,SDK 會繼續采集攝像頭的畫面進行推流。
    // activity 的 onStop 生命周期函數 @Override public void onResume() { super.onResume(); mCaptureView.onResume(); // mCaptureView 是攝像頭的圖像渲染view mLivePusher.resumePusher(); // 通知 SDK 重回前台推流 } 

step 10: 提醒主播“網絡不好”

step 13 中會介紹 SDK 的推流事件處理,其中 PUSH_WARNING_NET_BUSY 這個很有用,它的含義是:當前主播的上行網絡質量很差,觀眾端已經出現了卡頓。

當收到此WARNING時,您可以通過UI提醒主播換一下網絡出口,或者離WiFi近一點,或者讓她吼一嗓子:“領導,我在直播呢,別上淘寶了行不!什么?沒上淘寶?那韓劇也是一樣的啊。”

step 11: 橫屏推流

有時候用戶在直播的時候需要更廣的視角,則拍攝的時候需要“橫屏持握”,這個時候其實是期望觀看端能看到橫屏畫面,就需要做橫屏推流,下面兩幅示意圖分別描述了橫豎屏持握進行橫豎屏推流在觀眾端看到的效果:

  • 調整觀眾端表現
    通過對 LivePushConfig 中的 setHomeOrientation 設置項進行配置,它控制的是觀眾端看到的視頻寬高比是 16:9 還是 6:19,調整后的結果可以用播放器Demo查看以確認是否符合預期。

  • 調整主播端表現
    觀眾端的畫面表現符合預期以后,剩下要做的就是調整主播端的預覽畫面,這時可以通過 TXLivePusher 中的 setRenderRotation 接口,來旋轉主播端看到的畫面旋轉方向,此接口提供了 0,90,180,270 四個參數供設置旋轉角度。

  • Activity自動旋轉
    Android 系統的 Activity 本身支持跟隨手機的重力感應進行旋轉(設置 android:configChanges),CODE演示了如何做到下面這種重力感應效果:

step 12: 背景混音

SDK 1.6.1 開始支持背景混音,支持主播帶耳機和不帶耳機兩種場景,您可以通過 TXLivePusher 中的如下這組接口實現背景混音功能:

接口 說明
playBGM 通過path傳入一首歌曲,小直播Demo中我們是從iOS的本地媒體庫中獲取音樂文件
stopBGM 停止播放背景音樂
pauseBGM 暫停播放背景音樂
resumeBGM 繼續播放背景音樂
setMicVolume 設置混音時麥克風的音量大小,推薦在UI上實現相應的一個滑動條,由主播自己設置
setBGMVolume 設置混音時背景音樂的音量大小,推薦在UI上實現相應的一個滑動條,由主播自己設置

step 13: 結束推流

結束推流很簡單,不過要做好清理工作,因為用於推流的 TXLivePusher 和用於顯示影像的 TXCloudVideoView 都是不能多實例並行運轉的,所以清理工作不當會導致下次直播遭受不良的影響。

//結束推流,注意做好清理工作 public void stopRtmpPublish() { mLivePusher.stopCameraPreview(true); //停止攝像頭預覽 mLivePusher.stopPusher(); //停止推流 mLivePusher.setPushListener(null); //解綁 listener } 

事件處理

1. 事件監聽

SDK 通過 TXLivePushListener 代理來監聽推流相關的事件,注意 TXLivePushListener 只能監聽得到 PUSH_ 前綴的推流事件。

2. 常規事件

一次成功的推流都會通知的事件,比如收到1003就意味着攝像頭的畫面會開始渲染了

事件ID 數值 含義說明
PUSH_EVT_CONNECT_SUCC 1001 已經成功連接到騰訊雲推流服務器
PUSH_EVT_PUSH_BEGIN 1002 與服務器握手完畢,一切正常,准備開始推流
PUSH_EVT_OPEN_CAMERA_SUCC 1003 推流器已成功打開攝像頭(Android部分手機這個過程需要1-2秒)

3. 錯誤通知

SDK發現了一些嚴重問題,推流無法繼續了,比如用戶禁用了APP的Camera權限導致攝像頭打不開。

事件ID 數值 含義說明
PUSH_ERR_OPEN_CAMERA_FAIL -1301 打開攝像頭失敗
PUSH_ERR_OPEN_MIC_FAIL -1302 打開麥克風失敗
PUSH_ERR_VIDEO_ENCODE_FAIL -1303 視頻編碼失敗
PUSH_ERR_AUDIO_ENCODE_FAIL -1304 音頻編碼失敗
PUSH_ERR_UNSUPPORTED_RESOLUTION -1305 不支持的視頻分辨率
PUSH_ERR_UNSUPPORTED_SAMPLERATE -1306 不支持的音頻采樣率
PUSH_ERR_NET_DISCONNECT -1307 網絡斷連,且經三次搶救無效,可以放棄治療,更多重試請自行重啟推流

4. 警告事件

SDK發現了一些問題,但這並不意味着無可救葯,很多 WARNING 都會觸發一些重試性的保護邏輯或者恢復邏輯,而且有很大概率能夠恢復,所以,千萬不要“小題大做”哦。

  • WARNING_NET_BUSY
    主播網絡不給力。如果您需要UI提示,這個 warning 相對比較有用(step10)。

  • WARNING_SERVER_DISCONNECT
    推流請求被后台拒絕了。出現這個問題一般是由於推流地址里的 txSecret 計算錯了,或者是推流地址被其他人占用了(一個推流URL同時只能有一個端推流)。

事件ID 數值 含義說明
PUSH_WARNING_NET_BUSY 1101 網絡狀況不佳:上行帶寬太小,上傳數據受阻
PUSH_WARNING_RECONNECT 1102 網絡斷連, 已啟動自動重連 (自動重連連續失敗超過三次會放棄)
PUSH_WARNING_HW_ACCELERATION_FAIL 1103 硬編碼啟動失敗,采用軟編碼
PUSH_WARNING_DNS_FAIL 3001 RTMP -DNS解析失敗(會觸發重試流程)
PUSH_WARNING_SEVER_CONN_FAIL 3002 RTMP服務器連接失敗(會觸發重試流程)
PUSH_WARNING_SHAKE_FAIL 3003 RTMP服務器握手失敗(會觸發重試流程)
PUSH_WARNING_SERVER_DISCONNECT 3004 RTMP服務器主動斷開連接(會觸發重試流程)

全部事件定義請參閱頭文件“TXLiveConstants.java”

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM