easycamera
最近公司需求搞视频监控视频对讲,但个人对视频这块基本全无了解。在网上翻了一圈之后,使用EasyDarwin家的源码做了基础尝试。
easycamera
首先是移植EasyCamera。既然要移植,当然要分析源码。
EasyCamera的主要UI在StreamActivity上,如果是只是想抓一个视频界面来用,只要把这个Activity搬过去就好。不过我的需求是在我自己的项目的界面上进行显示。因此还要拆分啊。
UI方面的暂且不提。
mMediaStream = new MediaStream(getAPPlicationcontext(), surfaceview.getHolder());
mMediaStream.updateResolution(width, height);
mMediaStream.setDgree(getDgree());
以上是初始化一个流媒体
接下来我们看一下它的构造。
public MediaStream(Context context, surfaceholder holder) {
mApplicationContext = context;
mSurfaceHolderRef = new weakreference(holder);
mEasyPusher = new EasyPusher();
audiOStream = new AudioStream(mEasyPusher, null, EasyApplication.aio, EasyApplication.sMainBus);
mReceiver = new BroadcastReceiver() {
@Override
public void onreceive(Context context, intent intent) {
Log.d(TAG, "kim onReceive: "+intent.getAction());
mrequestSnapshot = true;
}
};
IntentFilter filter = new IntentFilter();
filter.addAction(MediaStream.ACTION_SNAPSHOT_REQ);
localBroadcastManager.getinstance(mApplicationContext).registerreceiver(mReceiver, filter);
}
其中EasyPusher是直接对接jni方法。对于jni我也全无研究,今后要适当看点资料了。
而AudioStream内提供了一个编码方法。
回到StreamActivity,再看下一步:
mPusherCallBack = new EasyPusher.OnInitPusherCallback() {
@Override
public void onCallback(int code) {
switch (code) {
case CODE.EASY_ACTIVATE_INvalid_KEY:
sendmessage("无效Key");
break;
case CODE.EASY_ACTIVATE_SUCCESS:
sendMessage("激活成功");
break;
case CODE.EASY_PUSH_STATE_connecting:
sendMessage("连接中");
这个功能是什么就不用多说了吧。
之后注册的一个广播也是核心功能。
mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (commandService.ACTION_START_STREAM.equals(intent.getAction())) {
} else if (CommandService.ACTION_STOP_STREAM.equals(intent.getAction())) {
} else if (CommandService.ACTION_COMMOND_RESTART_THREAD.equals(intent.getAction())) {
}
};
其中ACTION_START_STREAM内便是开始启动视频对接。具体内容请去看源码。
我需要的功能也很简单,就是移植。因此把初始化内的内容照原样搬过去就可以了。不过在搬过去的途中遇到了一个小坑,主要来自于移植所用的SurfaceView
<SurfaceView
Android:id="@+id/sv_surfaceview"
android:keepScreenOn="true"
android:layout_width="match_parent"
android:layout_height="match_parent" />
这个SurfaceView在android测试中似乎必须显示,移出视图外也不行,若不显示则在某些机子上会出现对面的Client可以听见声音,但是无法观看视频的现象。具体原因是什么我也不知道,如果有知道的大牛希望可以不吝赐教。
EasyClient中的列表与EasyCamera配对的方式主要是通过Serial,因此如果有需求对指定用户名进行匹配的情况,就把这句修改就好了。
public String getDeviceSerial(){
return InfoSharedPreference.getString(this , Config.device_serial_key);
}
EasyCilent
下一步是移植EasyClient。
移植EasyClient的途中没遇上太多坑,还算是比较顺利的。公司需求是点击用户的监视按钮,则对已开启EasyCamera的用户进行监视。
EasyClient中我主要使用的就是
EasyPlayerActivity这个activity。原样搬过去基本就可以了,当然途中若修改了包名,则需要去官方申请一个key值。
- 注意申请时填写的必须是ApplicationID而不是包名。
key替换在这里。
private void startRending(Surface surface) {
mStreamRender = new EasyRTSPClient(this, "79393674363536526D3432413254315A7073496D4A655A76636D63755A57467A65575268636E64706269356C59584E35593278705A573530567778576F502B6C34456468646D6C754A6B4A68596D397A595541794D4445325257467A65555268636E6470626C526C5957316C59584E35", surface, mResultReceiver);
Log.i("SpeedTalk" , "Url>>>" + mRTSPUrl + ",TCP>>" + RTSPClient.TRANSTYPE_TCP);
mStreamRender.start(mRTSPUrl, RTSPClient.TRANSTYPE_TCP, RTSPClient.EASY_SDK_VIDEO_FRAME_FLAG | RTSPClient.EASY_SDK_AUDIO_FRAME_FLAG, "admin", "admin");
}
在点击打开这个Activity之前,还需要对已开启EasyCamera的用户进行一个查询。
查询的代码在CameraFragment中,主页的三个碎片都是继承自这个界面的,只需要替换
protected String mType = "ARM_linux";
就可以进行切换。
MyApplication.asyncGet(url, new Callbackwrapper<DeviceListbody>(DeviceListBody.class) {
@Override
public void onBefore(Request request) {
mSwipeRefreshLayout.setRefreshing(false);
activity.showWaitprogress("");
}
@Override
public void onAfter() {
activity.hideWaitProgress();
}
@Override
public void onERROR(Call call, Exception e) {
toast.maketext(mContext, "onError:" + e.toString(), Toast.LENGTH_LONG).show();
}
@Override
public void onresponse(DeviceListBody body) {
List<DeviceListBody.Device> devices = body.getDevices();
if (devices.size() == 0) {
activity.showToadMessage("暂无直播信息");
liveVOAdapter = new OnlineCameraAdapter(new ArrayList<DeviceListBody.Device>());
} else {
liveVOAdapter = new OnlineCameraAdapter(devices);
int screenW = mContext.getresources().getdisplayMetrics().widthPixels;
int columnum = mGrid_live.getNumColumns();
int space = (int) (mContext.getResources().getDimension(R.dimen.gridview_horizontalspacing));
int itemWidth = (int) ((screenW - (columnum - 1) * space) / columnum);
int itemHeight = getItemHeight(itemWidth);
liveVOAdapter.setmSnapshotWidth(itemWidth);
liveVOAdapter.setmSnapshotHeight(itemHeight);
// int screenW = mContext.getResources().getDisplayMetrics().widthPixels;
// int columnum = mGrid_live.getNumColumns();
// int space = (int)(mContext.getResources().getDimension(R.dimen.gridview_horizontalspacing));
// int itemWidth = (int)((screenW-(columnum-1)*space)/columnum);
// int itemHeight = (int) (itemWidth * 4 / 3.0 + 0.5f);
// liveVOAdapter.setmSnapshotWidth(itemWidth);
// liveVOAdapter.setmSnapshotHeight(itemHeight);
}
mGrid_live.setAdapter(liveVOAdapter);
}
});
上面的onResponse就是进行了直播列表查询的相关方法。在使用时只需要原样替换就好。
移植两边之后,就可以进行正常的监视操作了。至于实现对讲,还在继续研究。至少这个案例当两边同时监听的时候,Android端会崩溃。
EasyDarwin这个平台稍微有点不稳定,后续需要调整的部分估计有不少。
上个官网源码。
https://github.com/EasyDarwin
相关阅读
EasyDarwin EasyCamera支持海康摄像机接入了
本文转自EasyDarwin开源团队成员Alex的博客:http://blog.csdn.net/cai6811376/article/details/52709816EasyCamera默认使用海思方