新浪云平台直播功能实现
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。
{"code":0,"data":{"tube_id":"db0c1d2d695fb75b393d8f99fe926721"}}
·删除频道:
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
参数包括tube_id(频道id)。
·停止直播:
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 接口调用失败,原因通常是网络异常。