代碼已經(jīng)上傳到github上可帽,喜歡的star下謝謝妓羊。
什么叫推流?
上一篇文章已經(jīng)說(shuō)過(guò)精拟,它是指將音視頻數(shù)據(jù)采集編碼之后承绸,推送到您指定的視頻云平臺(tái)上裸影。籠統(tǒng)一點(diǎn)就是军熏,推流是直播的主播端轩猩,把主播端采集的音視頻數(shù)據(jù)上傳到視頻云平臺(tái)上(我們這里是騰訊云平臺(tái)),然后粉絲通過(guò)我的房間號(hào)荡澎,進(jìn)入我的直播間均践。
騰訊視頻云sdk都為開(kāi)發(fā)者想好了,只需要一個(gè)推流URL就能驅(qū)動(dòng)摩幔。
因此我們第一步需要獲取測(cè)試的URL彤委,如下
-
獲取測(cè)試 URL
開(kāi)通直播服務(wù)后,可以使用 直播控制臺(tái)>>直播碼接入>>推流生成器 生成推流地址或衡,詳細(xì)信息可以參考獲得推流播放URL焦影。
由上面方法我們獲取到推流的url。
代碼對(duì)接
①添加界面元素
在xml 文件里添加如下代碼封断,它會(huì)在您的UI上安插一個(gè) TXCloudVideoView 控件斯辰,這是騰訊云用來(lái)顯示攝像頭影像的專用控件:
<com.tencent.rtmp.ui.TXCloudVideoView
android:id="@+id/txcloutvideo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true" />
②創(chuàng)建 Pusher 對(duì)象
我們首先創(chuàng)建一個(gè)TXLivePusher 對(duì)象,主要用它來(lái)完成推流工作坡疼。不過(guò)在創(chuàng)建 TXLivePusher 對(duì)象之前彬呻,還需要您指定一個(gè) LivePushConfig 對(duì)象,它的用途是決定 LivePush 推流時(shí)各個(gè)環(huán)節(jié)的配置參數(shù),比如推流用多大的分辨率闸氮、每秒鐘要多少幀畫面等等剪况。
TXLivePusher mLivePusher = new TXLivePusher(this);
TXLivePushConfig mLivePushConfig = new TXLivePushConfig();
mLivePusher.setConfig(mLivePushConfig);
③啟動(dòng)推流
經(jīng)過(guò)上面2個(gè)步驟之后,用下面這段代碼就可以啟動(dòng)推流了:
String rtmpUrl = "rtmp://24649.liveplay.myqcloud.com/live/24649_ef53d4eab4"; //我們從上面步驟得到的url
mLivePusher.startPusher(rtmpUrl); //告訴 SDK 音視頻流要推到哪個(gè)推流URL上去
mLivePusher.startCameraPreview(mTxCloudVideoView);c
運(yùn)行下效果如下:
④設(shè)定清晰度
騰訊云sdk提供了setVideoQuality()方法來(lái)設(shè)定推流的畫面清晰度蒲跨,該方法有三個(gè)參數(shù)译断,參數(shù)的意義詳情如下:
⑤美顏濾鏡
-
美顏
同樣,騰訊云提供了setBeautyFilter()方法可以設(shè)置美顏風(fēng)格或悲、磨皮程度镐作、美白級(jí)別和紅潤(rùn)級(jí)別//style 磨皮風(fēng)格: 0:光滑 1:自然 2:朦朧 //beautyLevel 磨皮等級(jí): 取值為 0-9.取值為 0 時(shí)代表關(guān)閉美顏效果.默認(rèn)值: 0,即關(guān)閉美顏效果. //whiteningLevel 美白等級(jí): 取值為 0-9.取值為 0 時(shí)代表關(guān)閉美白效果.默認(rèn)值: 0,即關(guān)閉美白效果. //ruddyLevel 紅潤(rùn)等級(jí): 取值為 0-9.取值為 0 時(shí)代表關(guān)閉美白效果.默認(rèn)值: 0,即關(guān)閉美白效果. public boolean setBeautyFilter(int style, int beautyLevel, int whiteningLevel, int ruddyLevel);
-
濾鏡
setFilter() 方法可以設(shè)置濾鏡效果,濾鏡本身是一張直方圖文件隆箩。騰訊提供了八種素材,可供自己選擇羔杨。
setSpecialRatio () 方法則可以設(shè)置濾鏡的程度捌臊,從 0 到 1,越大濾鏡效果越明顯兜材,默認(rèn)取值 0.5理澎。Bitmap bitmap = BitmapUtils.decodeResource(getResources(), R.drawable.langman); if (mLivePusher != null) { mLivePusher.setFilter(bmp); }
⑥控制攝像頭
騰訊云sdk默認(rèn)是前置攝像頭(可以通過(guò)修改 TXLivePushConfig 的配置函數(shù) setFrontCamera() 來(lái)修改這個(gè)默認(rèn)值),調(diào)用一次 switchCamera() 切換一次曙寡,注意切換攝像頭前必須保證 TXLivePushConfig 和 TXLivePusher 對(duì)象都已經(jīng)初始化糠爬。
mLivePushConfig.setFrontCamera(true); //默認(rèn)前置攝像頭
mLivePusher.switchCamera(); //切換攝像頭
⑦設(shè)置 Logo 水印
騰訊視頻云目前支持兩種水印設(shè)置方式:一種是在推流 SDK 進(jìn)行設(shè)置,原理是在 SDK 內(nèi)部進(jìn)行視頻編碼前就給畫面打上水印举庶。另一種方式是在云端打水印执隧,也就是云端對(duì)視頻進(jìn)行解析并添加水印 Logo。
這里建議使用SDK 添加水印户侥,因?yàn)樵谠贫舜蛩?huì)有問(wèn)題镀琉。這里介紹下sdk添加水印:
//設(shè)置視頻水印
mLivePushConfig.setWatermark(BitmapFactory.decodeResource(getResources(),R.drawable.watermark), 10, 10);
//后面兩個(gè)參數(shù)分別是水印位置的 X 軸坐標(biāo)和 Y 軸坐標(biāo)
mLivePusher.setConfig(mLivePushConfig);
如果您需要對(duì)水印圖片的位置做機(jī)型適配蕊唐,那么您需要調(diào)用水印歸一化接口屋摔。
//設(shè)置視頻水印
mLivePushConfig.setWatermark(mBitmap, 0.02f, 0.05f, 0.2f);
//參數(shù)分別是水印圖片的 Bitmap、水印位置的 X 軸坐標(biāo)替梨,水印位置的 Y 軸坐標(biāo)钓试,水印寬度。后面三個(gè)參數(shù)取值范圍是[0, 1]
//后面兩個(gè)參數(shù)分別是水印位置的X軸坐標(biāo)和 Y 軸坐標(biāo)
mLivePusher.setConfig(mLivePushConfig);
⑧硬件編碼
TXLivePushConfig 中的 setHardwareAcceleration()方法可以開(kāi)啟或關(guān)閉硬件編碼副瀑。
if (mHWVideoEncode){
if (mLivePushConfig != null) {
if(Build.VERSION.SDK_INT < 18){
Toast.makeText(getApplicationContext(), "硬件加速失敗弓熏,當(dāng)前手機(jī) API 級(jí)別過(guò)低(最低 18)",
Toast.LENGTH_SHORT).show();
mHWVideoEncode = false;
}
}
}
mLivePushConfig.setHardwareAcceleration(mHWVideoEncode ?
TXLiveConstants.ENCODE_VIDEO_HARDWARE : TXLiveConstants.ENCODE_VIDEO_SOFTWARE);
mLivePusher.setConfig(mLivePushConfig);
// 如果你不清楚要何時(shí)開(kāi)啟硬件加速, 建議設(shè)置為 ENCODE_VIDEO_AUTO
// 默認(rèn)是啟用軟件編碼, 但手機(jī) CPU 使用率超過(guò) 80% 或者幀率 <= 10, SDK 內(nèi)部會(huì)自動(dòng)切換為硬件編碼
⑨后臺(tái)推流
常規(guī)模式下,App 一旦切到后臺(tái)俗扇,攝像頭的采集能力就被 Android 系統(tǒng)停掉了硝烂,這就意味著 SDK 不能再繼續(xù)采集并編碼出音視頻數(shù)據(jù)。如果我們什么都不做,那么故事將按照如下的劇本發(fā)展下去:
- 階段一(切后臺(tái)開(kāi)始 -> 之后的 10 秒內(nèi))- CDN 因?yàn)闆](méi)有數(shù)據(jù)所以無(wú)法向觀眾提供視頻流滞谢,觀眾看到畫面卡主串稀。
- 階段二(10 秒 -> 70 秒內(nèi))- 觀眾端的播放器因?yàn)槌掷m(xù)收不到直播流而直接退出,直播間已經(jīng)人去樓空狮杨。
- 階段三(70 秒以后)- 推流的 RTMP 鏈路被服務(wù)器直接斷掉母截,主播需要重新開(kāi)啟直播才能繼續(xù)。
主播可能只是短暫接個(gè)緊急電話而已橄教,但各云商的安全保護(hù)措施會(huì)讓主播的直播被迫提前結(jié)束清寇。
1)設(shè)置setPauseFlag
在開(kāi)始推流前,使用 TXLivePushConfig 的 setPauseImg 接口設(shè)置一張等待圖片护蝶,圖片含義推薦為“主播暫時(shí)離開(kāi)一下下华烟,稍后回來(lái)”。
mLivePushConfig.setPauseImg(300,5);
// 300 為后臺(tái)播放暫停圖片的最長(zhǎng)持續(xù)時(shí)間,單位是秒
// 10 為后臺(tái)播放暫停圖片的幀率,最小值為 5,最大值為 20
Bitmap bitmap = decodeResource(getResources(), R.drawable.pause_publish);
mLivePushConfig.setPauseImg(bitmap);
// 設(shè)置推流暫停時(shí),后臺(tái)播放的暫停圖片, 圖片最大尺寸不能超過(guò) 1920*1920.
mLivePusher.setConfig(mLivePushConfig);
2)設(shè)置setPauseFlag
在開(kāi)始推流前持灰,使用 TXLivePushConfig 的setPauseFlag()方法設(shè)置切后臺(tái) pause 推流時(shí)需要停止哪些采集盔夜,停止視頻采集則會(huì)推送 pauseImg 設(shè)置的默認(rèn)圖,停止音頻采集則會(huì)推送靜音數(shù)據(jù)堤魁。
setPauseFlag(PAUSE_FLAG_PAUSE_VIDEO|PAUSE_FLAG_PAUSE_AUDIO);//表示同時(shí)停止視頻和音頻采集喂链,并且推送填充用的音視頻流;
setPauseFlag(PAUSE_FLAG_PAUSE_VIDEO);//表示停止攝像頭采集視頻畫面妥泉,但保持麥克風(fēng)繼續(xù)采集聲音椭微,用于主播更衣等場(chǎng)景;
3)切后臺(tái)處理
推流中盲链,如果App被切了后臺(tái)蝇率,調(diào)用 TXLivePusher 中的 pausePush 接口函數(shù),之后刽沾,SDK 雖然采集不到攝像頭的畫面了瓢剿,但可以用您剛才設(shè)置的 pauseImg 持續(xù)推流。
// activity 的 onStop 生命周期函數(shù)
@Override
public void onResume() {
super.onResume();
mCaptureView.onResume(); // mCaptureView 是攝像頭的圖像渲染view
mLivePusher.resumePusher(); // 通知 SDK 重回前臺(tái)推流
}
效果如下:
4)后臺(tái)推攝像頭采集數(shù)據(jù)
如果希望主播在切后臺(tái)或者跳轉(zhuǎn)其他界面還能看到攝像頭采集的畫面悠轩, 按照以下配置即可间狂。
1、1)和 2) 無(wú)需設(shè)置火架。
2鉴象、3) 中,注釋 mLivePusher.pausePusher() 該方法何鸡。
3纺弊、4) 中,注釋 mLivePusher.resumePusher() 該方法骡男。
⑩網(wǎng)絡(luò)質(zhì)量提示
通過(guò) TXLivePushListener 里的 onPlayEvent 可以捕獲 PUSH_WARNING_NET_BUSY事件淆游,它代表當(dāng)前主播的網(wǎng)絡(luò)已經(jīng)非常糟糕,出現(xiàn)此事件即代表觀眾端會(huì)出現(xiàn)卡頓。
此時(shí)可以提示主播 “您當(dāng)前的網(wǎng)絡(luò)狀況不佳犹菱,推薦您離 WiFi 近一點(diǎn)拾稳,盡量不要讓 WiFi 穿墻”。
到這里騰訊推流基本講解完成腊脱,下一篇說(shuō)下直播篇访得。