这篇文章,就Android平台上如何集成乐橙SDK进行讲解。
前言:
乐橙是浙江大华技术股份有限公司旗下的一家专注视频智能硬件,视频云和视频智能技术,为视频应用提供云视频能力的服务商。
我们接入乐橙设备,实现实时预览、远程回放、抓图、切换画质等功能。
类似于萤石的处理方式,我们也需要在乐橙开放平台注册应用,得到应用配置,并且我们也需要获取AccessToken,关于这些东西,大家可移步乐橙开放平台。
下面我们直接上代码:
/**
* Created by Administrator on 2017/11/29.
* 封装的乐橙播放库
*/
public class PlayerLeChange {
private static final String TAG = "LeChange";
private Handler handler;
public LCOpenSDK_PlayWindow lcOpenSDK_playWindow; //播放窗口
public PlayerLeChange(Context context, ViewGroup viewGroup, Handler handler) {
LCOpenSDK_Api.setHost("openapi.lechange.cn:443"); //设置乐橙服务地址
lcOpenSDK_playWindow = new LCOpenSDK_PlayWindow();
lcOpenSDK_playWindow.initPlayWindow(context, viewGroup, 0); //初始化播放功能,父窗口绑定到LCOpenSDK_playWindow的实例上
this.handler = handler;
}
/**
* 实时预览
* @param token
* @param deviceId
* @param encryptKey
* @param channelNo
* @param quality
*/
public void live(String token, String deviceId, String encryptKey, int channelNo, int quality) {
lcOpenSDK_playWindow.playRtspReal(token, deviceId, encryptKey, channelNo, quality);
/**
* 为播放窗口设置监听
*/
lcOpenSDK_playWindow.setWindowListener(new LCOpenSDK_EventListener() {
@Override
public void onPlayerResult(int index, String code, int resultSource) {
super.onPlayerResult(index, code, resultSource);
if (resultSource == 0 && "4".equals(code)) {
messageFeedback(null);
} else {
messageFeedback("实时预览失败");
}
}
});
}
/**
* 远程回放
* @param token
* @param deviceId
* @param encryptKey
* @param channelNo
* @param beginTime
* @param endTime
*/
public void playback(String token, String deviceId, String encryptKey, int channelNo, long beginTime, long endTime) {
lcOpenSDK_playWindow.playRtspPlaybackByUtcTime(token, deviceId, encryptKey, channelNo, beginTime, endTime);
lcOpenSDK_playWindow.setWindowListener(new LCOpenSDK_EventListener() {
@Override
public void onPlayerResult(int index, String code, int resultSource) {
super.onPlayerResult(index, code, resultSource);
if (resultSource == 0 && "4".equals(code)) {
messageFeedback(null);
} else {
messageFeedback("远程回放失败");
}
}
});
}
/**
* 停止实时预览
*/
public void stopLive() {
lcOpenSDK_playWindow.stopRtspReal();
}
/**
* 停止远程回放
*/
public void stopPlayback() {
lcOpenSDK_playWindow.stopRtspPlayback();
}
/**
* 查询录像段文件数量
* @param token
* @param deviceId
* @param channelNo
* @param beginTime
* @param endTime
*/
public int queryRecordNum(String token, String deviceId, int channelNo, String beginTime, String endTime) {
QueryLocalRecordNum req = new QueryLocalRecordNum();
req.data.token = token;
req.data.deviceId = deviceId;
req.data.channelId = channelNo + "";
req.data.beginTime = beginTime;
req.data.endTime = endTime;
RetObject retObject = request(req, 60 * 1000);
QueryLocalRecordNum.Response resp = (QueryLocalRecordNum.Response) retObject.resp;
if (retObject.mErrorCode != 0) { //查询录像失败
return -1;
} else {
if (resp.data == null) { //录像数据为空
return 0;
} else {
return resp.data.recordNum;
}
}
}
/**
* 获取录像段文件
* @param token
* @param deviceId
* @param channelNo
* @param beginTime
* @param endTime
* @param queryRange
* @return
*/
public List<LeChangeRecordInfo> getRecordFile(String token, String deviceId, int channelNo, String beginTime, String endTime, String queryRange) {
List<LeChangeRecordInfo> recordInfoList = new ArrayList<LeChangeRecordInfo>();
QueryLocalRecords req = new QueryLocalRecords();
req.data.token = token;
req.data.deviceId = deviceId;
req.data.channelId = channelNo + "";
req.data.beginTime = beginTime;
req.data.endTime = endTime;
req.data.queryRange = queryRange;
RetObject retObject = request(req);
QueryLocalRecords.Response resp = (QueryLocalRecords.Response) retObject.resp;
if (retObject.mErrorCode == 0 && resp.data != null && resp.data.records != null) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (QueryLocalRecords.ResponseData.RecordsElement element:resp.data.records) {
LeChangeRecordInfo recordInfo = new LeChangeRecordInfo();
try {
recordInfo.setStartTime(sdf.parse(element.beginTime).getTime());
recordInfo.setEndTime(sdf.parse(element.endTime).getTime());
recordInfoList.add(recordInfo);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
return recordInfoList;
}
public static class RetObject {
public int mErrorCode = 0; //错误码表示符 -1:返回体为null,0:成功,1:http错误,2:业务错误
public String mMsg;
public Object resp;
}
/**
* 发送网络请求,并对请求结果的错误码进行处理
* @param req
* @return
*/
private RetObject request(BaseRequest req) {
return request(req, 5 * 1000);
}
/**
* 发送网络请求,并对请求结果的错误码进行处理
* @param req
* @param timeout
* @return
*/
private RetObject request(BaseRequest req, int timeout) {
RetObject retObject = new RetObject();
BaseResponse t = null;
try {
t = LCOpenSDK_Api.request(req, timeout); //openAPI请求方法
if (t.getCode() == 200) { //请求成功
if (!t.getApiRetCode().equals("0")) { //业务错误
retObject.mErrorCode = 2;
retObject.mMsg = "业务错误码:" + t.getApiRetCode() + ",错误消息:"
+ t.getApiRetMsg();
LogUtils.i(TAG, "retObject.mMsg:" + retObject.mMsg);
}
} else {
retObject.mErrorCode = 1; //http错误
retObject.mMsg = "HTTP错误码:" + t.getCode() + ",错误消息:" + t.getDesc();
LogUtils.i(TAG, "retObject.mMsg:" + retObject.mMsg);
}
} catch (Exception e) {
e.printStackTrace();
retObject.mErrorCode = -1000;
retObject.mMsg = "内部错误码 : -1000, 错误消息 :" + e.getMessage();
LogUtils.i(TAG, "retObject.mMsg:" + retObject.mMsg);
}
retObject.resp = t;
return retObject;
}
private void messageFeedback(String msg) {
Message message = Message.obtain();
message.obj = msg;
handler.sendMessage(message);
}
}
public class LeChangeRecordInfo {
public enum RecordType
{
DeviceLocal, // 设备本地录像
PrivateCloud, // 私有云
PublicCloud, // 公有云
}
public enum RecordEventType
{
All, // 所有录像
Manual, // 手动录像
Event, // 事件录像
}
private String id = UUID.randomUUID().toString();
private RecordType type; // 录像类型
private float fileLength; // 文件长度
private float downLength = -1; // 已下载长度
private long startTime; // 开始时间
private long endTime; // 结束时间
private String deviceId; //设备ID
private String deviceKey;
private String backgroudImgUrl; // 录像文件Url
private String chnlUuid; // 通道的uuid
private RecordEventType eventType; // 事件类型
private long recordID; //录像ID
private String recordPath; //录像ID(设备录像)
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public String getDeviceKey() {
return deviceKey;
}
public void setDeviceKey(String deviceKey) {
this.deviceKey = deviceKey;
}
public RecordType getType() {
return type;
}
public void setType(RecordType type) {
this.type = type;
}
public long getStartTime() {
return startTime;
}
public float getFileLength() {
return fileLength;
}
public void setFileLength(float fileLength) {
this.fileLength = fileLength;
}
public float getDownLength() {
return downLength;
}
public void setDownLength(float downLength) {
this.downLength = downLength;
}
public void setStartTime(long startTime) {
this.startTime = startTime;
}
public long getEndTime() {
return endTime;
}
public void setEndTime(long endTime) {
this.endTime = endTime;
}
public String getBackgroudImgUrl() {
return backgroudImgUrl;
}
public void setBackgroudImgUrl(String backgroudImgUrl) {
this.backgroudImgUrl = backgroudImgUrl;
}
public String getChnlUuid() {
return chnlUuid;
}
public void setChnlUuid(String chnlUuid) {
this.chnlUuid = chnlUuid;
}
public RecordEventType getEventType() {
return eventType;
}
public void setEventType(RecordEventType eventType) {
this.eventType = eventType;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public void setRecordID(long id) {
this.recordID = id;
}
public long getRecordID() {
return this.recordID;
}
public boolean isDownload() {
return downLength >= 0;
}
public String getRecordPath() {
return recordPath;
}
public void setRecordPath(String recordPath) {
this.recordPath = recordPath;
}
}
补充:
1、抓图:
直接调用LCOpenSDK_PlayWindow的snapShot(String filePath)方法就可以了。
2、切换画质:
直接调用LCOpenSDK_PlayWindow的playRtspReal(final String token, final String deviceID, final String encryptKey, final int channelID, final int bateMode)方法就可以了。
bateMode:0-高清;1-流畅。
注:只有实时预览支持切换画质,远程回放不支持。