新浪雲直播技術研究
新浪雲平臺直播功能實現
1 新浪雲直播申請與開通
新浪雲直播(SLS)的優勢在於,支援斷點續流,海量CDN多線全網分發,可以滿足海量使用者同時觀看實現高併發,而且能保證畫面的流暢穩定。除此之外,SLS還支援各平臺的相容,可以輕鬆實現跨平臺,這一點對於我們的跨平臺線上教育而言至關重要,SLS的官方文件提供了網頁端、安卓端和iOS端的介面,通過對這些介面的呼叫可以實現直播的跨平臺,並且可以直接接入我們之前開發的應用當中去,無需重複開發產生額外工作。
新浪雲直播的主頁地址是http://www.sinacloud.com/live.html,在這個網頁中點選立即使用,對於第一次使用SLS的使用者,需要按格式要求傳送一封郵件到[email protected],郵件中需要遞交的資訊包括:安全郵箱、直播用途和使用者類別(個人使用者還是企業使用者)。根據官方說明是遞交之後等待稽核,稽核通過後才能使用直播功能。但在實際使用中發現,這個郵件得不到任何響應,需要在支援中心提交工單,直接和客服取得聯絡,讓客服開通直播功能,如圖1。
圖1 申請開通雲直播
申請成功後就可以建立頻道,頻道可以理解為直播平臺中的一個直播間,系統會自動會這個直播間分配一個頻道ID,這個ID需要記下來,在配置本地推流軟體的時候會用到。
2 本地推流軟體配置
直播平臺是由主播和觀眾組成的,觀眾只需要開啟直播間的網址就能在網頁或手機客戶端上觀看直播,而主播要提供直播就需要在本地安裝推流軟體,將視訊內容推送到雲伺服器,再由雲伺服器將視訊通過CDN等加速手段提供給觀眾,具體框架如圖2所示。
圖2 直播平臺框架
如圖2所示,推流軟體採用的是最流行的Open Broadcaster Software,包括鬥魚、戰旗在內的多個大型直播平臺推薦主播使用的都是這款軟體,在鬥魚直播平臺的直播教程中http://www.douyu.com/cms/zhibo/201311/13/250.shtml,詳細的說明的如何配置OBS,唯一需要注意的是,如圖3所示,在廣播設定中,串流服務選擇Custom,然後將SLS提供的直播地址的前半段,即除去頻道ID的部分,填入到FMS URL中,然後將頻道ID填入到播放路徑/串碼流中。
圖3 OBS廣播設定
3 新浪雲直播HTTP API
新浪雲的所有API都是以PHP為例的,此處也不例外,所有API呼叫是都是用GET方法發起請求,下面不再一一申明。
介面列表:
·建立頻道:
GET /tube/create
引數包括name(頻道名稱)和despcrition(頻道描述),具體實現程式碼如下所示。
***************************************************************************
curl -u username:passowrd 'http://liveapi.sinacloud.com/tube/create'-d 'name=賽科資訊保安線上教育直播&despcrition=賽科資訊保安線上教育直播'
***************************************************************************
成功後會得到如下返回資訊,獲得頻道ID。
·刪除頻道:
GET /tube/delete
引數包括tube_id(頻道id), name(頻道名稱)和despcrition(頻道描述),具體實現程式碼如下所示。
***************************************************************************
curl -u username:passowrd 'http://liveapi.sinacloud.com/tube/delete'-d 'tube_id= db0c1d2d695fb75b393d8f99fe926721&name=賽科資訊保安線上教育直播&despcrition=賽科資訊保安線上教育直播'
***************************************************************************
請求成功後返回程式碼0。
{"code":0,"data":null}
·更新頻道資訊:
GET /tube/update
引數包括tube_id(頻道id)。
成功返回頻道相應的資訊,失敗返回相應錯誤資訊。其中status為0表示頻道關閉,為1表示開啟但無訊號,為2表示直播進行中。
·查詢頻道資訊:
GET /tube/query
引數包括tube_id(頻道id)。
·開始直播:
GET /tube/start
·停止直播:
GET /tube/stop
引數包括tube_id(頻道id)。
·查詢所有頻道資訊:
GET /tube/list
無引數。
4 安卓推流SDK
許可權宣告:
使用前需要在 Android App 的 AndroidManifest.xml 中宣告如下許可權:
<uses-featureandroid:name="android.hardware.camera" />
<!-- 申明應用需要用到相機 -->
<uses-featureandroid:name="android.hardware.camera.autofocus"android:required="false" />
<!-- 申明應用需要用到自動對焦 -->
<uses-permissionandroid:name="android.permission.CAMERA" />
<!-- 申請相機使用許可權 -->
<uses-permissionandroid:name="android.permission.RECORD_AUDIO" />
<!-- 申明錄音許可權 -->
<uses-permissionandroid:name="android.permission.INTERNET" />
<!-- 申明網路許可權 -->
QUICK START
初始化 LiveSession
LiveSession是對視訊採集、編碼、推流等功能模組介面進行封裝後的介面類,為您提供友好的程式設計介面。
LiveSession mLiveSession= new LiveSession(MainActivity.this);
// 使用該初始化介面後,預設採用後置攝像頭採集,視訊編碼、音訊編碼均使用預設引數
// 如需定製其他引數請使用附錄其他兩種方式初始化
設定預覽 View
初始化成功後,使用bindPreviewDisplay 介面為 LiveSession 物件設定預覽View,否則無法啟動相機。
SurfaceViewcameraView = (SurfaceView) findViewById(R.id.cameraView);
mLiveSession.bindPreviewDisplay(cameraView.getHolder());
啟動音視訊採集裝置
在開始推流前,我們還需要啟動音視訊採集裝置(即相機和 MIC)。
mLiveSession.prepareSessionAsync();
開始推流
當採集裝置成功啟動後(即收到 onSessionPrepared 回撥後,參考附錄處理推流SDK 狀態變化事件),可以通過呼叫 startRtmpSession方法設定推流地址並開始推流。 推流URL的具體值為你從新浪雲視訊直播服務獲得的推送地址,例如: rtmp://xxxx。
final Stringurl1 = "rtmp://xxxx";
if(mLiveSession.startRtmpSession(url1)) {
Log.d(TAG, "Starting Streaming inright state!");
} else {
Log.e(TAG, "Starting Streaming inwrong state!");
}
結束推流。
mLiveSession.stopRtmpSession();
推流 SDK 提供如下三種方法完成初始化:
1.使用 LiveSession(Context cxt)
LiveSessionmLiveSession = new LiveSession(MainActivity.this);
// 使用該初始化介面後,預設採用後置攝像頭採集
// 視訊編碼引數為720p@24fps、位元速率1024kbps
// 音訊編碼引數為雙聲道、取樣率44.1khz、位元速率64kbps
2.使用 LiveSession(Context cxt, intwidth, int height, int fps, int bitrate)
LiveSessionmLiveSession = new LiveSession(this, 640, 480, 15, 512000);
// 使用該初始化介面後,仍然採用後置攝像頭採集
// 解析度、幀率、位元速率將使用使用者傳入的引數
// 本示例程式碼所設定的視訊編碼引數為解析度640x480、幀率15fps、位元速率512kbps
// 音訊編碼引數仍為預設值(雙聲道、取樣率44.1khz、位元速率64kbps)
3.使用LiveSession(Context cxt, intwidth, int height, int fps, int bitrate, int cameraId)
int cameraId =Camera.CameraInfo.CAMERA_FACING_FRONT;
LiveSessionmLiveSession = new LiveSession(this, 1280, 720, 15, 1024000, cameraId);
// 如示例程式碼中,使用該初始化介面後,將採用前置攝像頭採集
// 同時設定了視訊的解析度、幀率、位元速率
// 音訊編碼引數仍為預設值(雙聲道、取樣率44.1khz、位元速率64kbps)
處理推流 SDK 狀態變化事件:
在推流 SDK 中,我們定義了名為SessionStateListener 的interface,您可以實現該介面並將其傳遞給 LiveSession 物件(通過呼叫setStateListener 介面實現),這樣就可以實時接收到推流 SDK的一些屬性及狀態更新資訊。
interface 定義如下:
public interfaceSessionStateListener {
/**
* 錄製裝置準備完畢
* @param code 固定為RESULT_CODE_OF_OPERATION_SUCCEEDED
*/
void onSessionPrepared(int code);
/**
* 推流開始後的回撥
* @param code 固定為RESULT_CODE_OF_OPERATION_SUCCEEDED
*/
void onSessionStarted(int code);
/**
* 推流結束後的回撥
* @param code 固定為RESULT_CODE_OF_OPERATION_SUCCEEDED
*/
void onSessionStopped(int code);
/**
* 推流 SDK 出錯後的回撥
* @param code 錯誤型別如下:
* ERROR_CODE_OF_OPEN_MIC_FAILED
* ERROR_CODE_OF_OPEN_CAMERA_FAILED
* ERROR_CODE_OF_PREPARE_SESSION_FAILED
* ERROR_CODE_OF_CONNECT_TO_SERVER_FAILED
* ERROR_CODE_OF_DISCONNECT_FROM_SERVER_FAILED
* ERROR_CODE_OF_UNKNOWN_STREAMING_ERROR
* ERROR_CODE_OF_PACKET_REFUSED_BY_SERVER
* ERROR_CODE_OF_WEAK_CONNECTION
* ERROR_CODE_OF_SERVER_INTERNAL_ERROR
* ERROR_CODE_OF_CONNECTION_TIMEOUT
*/
void onSessionError(int code);
}
注意:prepareSessionAsync、startRtmpSession、stopRtmpSession均為非同步介面,即介面被呼叫後,不會立即得到結果,需要實現SessionStateListener interface偵聽回撥結果。如果執行成功,onSessionPrepared、onSessionStarted、onSessionStopped方法將分別被呼叫,且引數固定為RESULT_CODE_OF_OPERATION_SUCCEEDED。如果執行失敗,只有onSessionError 方法將被呼叫,引數及意義如下:
ERROR_CODE_OF_OPEN_MIC_FAILED// MIC裝置無法開啟
ERROR_CODE_OF_OPEN_CAMERA_FAILED// 相機裝置無法開啟
ERROR_CODE_OF_PREPARE_SESSION_FAILED// onSessionPrepared 介面呼叫失敗,原因只能是 MIC 或相機開啟失敗
ERROR_CODE_OF_CONNECT_TO_SERVER_FAILED// startRtmpSession 介面呼叫失敗,原因通常為連線不上推流伺服器
ERROR_CODE_OF_DISCONNECT_FROM_SERVER_FAILED// stopRtmpSession 介面呼叫失敗,原因通常是網路異常。