Android平台上集成海康SDK

在项目中需要接入海康设备,因此我们集成了海康Android版本SDK。它分为Device Network SDK和Player SDK。前者用于设备连接、网络通信;后者用于解码、播放。

在APP中,关于海康设备,我们实现了以下功能:添加设备、获取通道、实时预览、远程回放。


接下来我们一个一个来分析如何实现:

首先,登录设备,用到的是这个方法:HCNetSDK.getInstance().NET_DVR_Login_V30(String sDvrIp, int iDvrPort, String sUsername, String sPassword, NET_DVR_DEVICEINFO_V30 deviceInfo)

具体代码实现如下:

HCNetSDK.getInstance().NET_DVR_Init();  //初始化SDK
NET_DVR_DEVICEINFO_V30 m_oNetDvrDeviceInfoV30 = new NET_DVR_DEVICEINFO_V30();
if ( null == m_oNetDvrDeviceInfoV30) { Log. e( "Hikvision" , "HKNetDvrDeviceInfoV30 new is failed!") ; Message msg = Message. obtain() ; msg. what = 1 ; if (!AddDeviceActivity. this.isFinishing()) { msg. obj = getResources().getString(R.string. loginFailed) ; } handler.sendMessage(msg) ; return;} int iLogID = HCNetSDK. getInstance().NET_DVR_Login_V30( ipAddress , port , userName , password , m_oNetDvrDeviceInfoV30) ; // 登录设备

接着,获取通道

如果iLogID不小于0,则登录成功。

获取开始通道号、通道个数,代码如下:

一般情况时,

if(m_oNetDvrDeviceInfoV30.byChanNum > 0) {
    m_iStartChan = m_oNetDvrDeviceInfoV30.byStartChan;
    m_iChanNum = m_oNetDvrDeviceInfoV30.byChanNum;
} else if(m_oNetDvrDeviceInfoV30.byIPChanNum > 0) {
    m_iStartChan = m_oNetDvrDeviceInfoV30.byStartDChan;
    m_iChanNum = m_oNetDvrDeviceInfoV30.byIPChanNum + m_oNetDvrDeviceInfoV30.byHighDChanNum * 256;
}
 
  

复杂情况时(比如模拟通道和数字通道混合、所获取的通道并不都是valid可用的等)

NET_DVR_IPPARACFG_V40 net_dvr_ipparacfg_v40 = new NET_DVR_IPPARACFG_V40();  //IP Device Resource and IP Channel Resource Configuration
HCNetSDK.getInstance().NET_DVR_GetDVRConfig(iLogID, HCNetSDK.NET_DVR_GET_IPPARACFG_V40, 0, net_dvr_ipparacfg_v40);  //Get Device Settings Information
Log.i("Hik_An_CHANNEL_NUM", net_dvr_ipparacfg_v40.dwAChanNum + "");
Log.i("Hik_Di_CHANNEL_NUM", net_dvr_ipparacfg_v40.dwDChanNum + "");
NET_DVR_DIGITAL_CHANNEL_STATE net_dvr_digital_channel_state = new NET_DVR_DIGITAL_CHANNEL_STATE();  //Channel Status
HCNetSDK.getInstance().NET_DVR_GetDVRConfig(iLogID, HCNetSDK.NET_DVR_GET_DIGITAL_CHANNEL_STATE, 0xFFFFFFFF, net_dvr_digital_channel_state);
byte[] byAnalogChanState = net_dvr_digital_channel_state.byAnalogChanState;
byte[] byDigitalChanState = net_dvr_digital_channel_state.byDigitalChanState;
SQLiteDatabase db = mySqliteHelper.getWritableDatabase();
for (int i = 0; i < net_dvr_ipparacfg_v40.dwAChanNum; i++) {
    if (byAnalogChanState[i] == 1)
        mCount ++;
}
for (int i = 0; i < net_dvr_ipparacfg_v40.dwDChanNum; i++) {
    if (byDigitalChanState[i] == 1)
        mCount ++;
}
Log.i("Hik_VALID_CHANNEL_NUM", mCount + "");
for (int i = 0; i < net_dvr_ipparacfg_v40.dwAChanNum; i++) {
    if (byAnalogChanState[i] == 1)
        DbManger.execDataSql(db, "insert into " + Dbutils.TABLE_NAME + "(" +
                Dbutils.CAMERA_NAME + "," + Dbutils.CAMERA_ID + "," + Dbutils.SITE_NAME + "," + Dbutils.DEVICE_NAME + ","
                + Dbutils.ADDRESS + "," + Dbutils.TCP + "," + Dbutils.USERNAME + "," + Dbutils.PASSWORD + "," +
                Dbutils.CAMERA_NUM + "," + Dbutils.DEVICE_TYPE + ") values('" + "HikCAM " + (i + 1) + "',"
                + (m_oNetDvrDeviceInfoV30.byStartChan + i) + ",'" + site_name + "','" + device_name + "','" + ipAddress + "',"
                + port + ",'" + userName + "','" + password + "'," + mCount + ",'" + "Hikvision Device" + "')");
}
for (int i = 0; i < net_dvr_ipparacfg_v40.dwDChanNum; i++) {
    if (byDigitalChanState[i] == 1)
        DbManger.execDataSql(db, "insert into " + Dbutils.TABLE_NAME + "(" +
                Dbutils.CAMERA_NAME + "," + Dbutils.CAMERA_ID + "," + Dbutils.SITE_NAME + "," + Dbutils.DEVICE_NAME + ","
                + Dbutils.ADDRESS + "," + Dbutils.TCP + "," + Dbutils.USERNAME + "," + Dbutils.PASSWORD + "," +
                Dbutils.CAMERA_NUM + "," + Dbutils.DEVICE_TYPE + ") values('" + "HikCAM " + (i + 1) + "',"
                + (net_dvr_ipparacfg_v40.dwStartDChan + i) + ",'" + site_name + "','" + device_name + "','" + ipAddress + "',"
                + port + ",'" + userName + "','" + password + "'," + mCount + ",'" + "Hikvision Device" + "')");
}
//以下处理是针对net_dvr_ipparacfg_v40.dwAChanNumnet_dvr_ipparacfg_v40.dwDChanNum均为0,但是仍然有通道的海康设备
if (net_dvr_ipparacfg_v40.dwAChanNum == 0 && net_dvr_ipparacfg_v40.dwDChanNum == 0) {
    if(m_oNetDvrDeviceInfoV30.byChanNum > 0) {
        m_iStartChan = m_oNetDvrDeviceInfoV30.byStartChan;
        m_iChanNum = m_oNetDvrDeviceInfoV30.byChanNum;
    } else if(m_oNetDvrDeviceInfoV30.byIPChanNum > 0) {
        m_iStartChan = m_oNetDvrDeviceInfoV30.byStartDChan;
        m_iChanNum = m_oNetDvrDeviceInfoV30.byIPChanNum + m_oNetDvrDeviceInfoV30.byHighDChanNum * 256;
    }
    mCount = m_iChanNum;
    for (int i = 0 ; i < m_iChanNum ; i ++) {
        int cameraId = m_iStartChan + i;
        DbManger.execDataSql(db, "insert into " + Dbutils.TABLE_NAME + "(" +
                Dbutils.CAMERA_NAME + "," + Dbutils.CAMERA_ID + "," + Dbutils.SITE_NAME + "," + Dbutils.DEVICE_NAME + ","
                + Dbutils.ADDRESS + "," + Dbutils.TCP + "," + Dbutils.USERNAME + "," + Dbutils.PASSWORD + "," +
                Dbutils.CAMERA_NUM + "," + Dbutils.DEVICE_TYPE + ") values('" + "HikCAM " + (i + 1) + "',"
                + cameraId + ",'" + site_name + "','" + device_name + "','" + ipAddress + "',"
                + port + ",'" + userName + "','" + password + "'," + mCount + ",'" + "Hikvision Device" + "')");
    }
}


对海康摄像头进行实时预览:用到的方法是HCNetSDK.getInstance().NET_DVR_RealPlay_V40(int var1, NET_DVR_PREVIEWINFO var2, RealPlayCallBack var3)

具体实现代码如下:

用之前登录成功返回的iLogID和之前获取的通道号

NET_DVR_PREVIEWINFO previewInfo = new NET_DVR_PREVIEWINFO();
previewInfo.lChannel = channelNo;  //通道号
previewInfo.dwStreamType = streamType;  //码流类型
previewInfo.bBlocked = 1;
RealPlayCallBack fRealDataCallBack = getRealPlayerCbf();
int m_iPlayID = HCNetSDK.getInstance().NET_DVR_RealPlay_V40(iLogID, previewInfo, fRealDataCallBack);
private RealPlayCallBack getRealPlayerCbf() {
    RealPlayCallBack cbf = new RealPlayCallBack() {
        public void fRealDataCallBack(int iRealHandle, int iDataType, byte[] pDataBuffer, int iDataSize) {
            processRealData(1, iDataType, pDataBuffer, iDataSize, Player.STREAM_REALTIME);
        }
    };
    return cbf;
}

private void processRealData(int iPlayViewNo, int iDataType, byte[] pDataBuffer, int iDataSize, int iStreamMode) {
    if (m_bNeedDecode) {
        if (HCNetSDK.NET_DVR_SYSHEAD == iDataType) {
            m_iPort = Player.getInstance().getPort();
            if (m_iPort == -1) {
                Log.e(TAG_ERROR, "getPort is failed with: " + Player.getInstance().getLastError(m_iPort));
                return;
            }
            Log.i(TAG, "getPort success with: " + m_iPort);
            if (iDataSize > 0) {
                if (!Player.getInstance().setStreamOpenMode(m_iPort, iStreamMode))  //set stream mode
                {
                    Log.e(TAG_ERROR, "setStreamOpenMode failed");
                    return;
                }
                if (!Player.getInstance().openStream(m_iPort, pDataBuffer, iDataSize, 2 * 1024 * 1024)) //open stream
                {
                    Log.e(TAG_ERROR, "openStream failed");
                    return;
                }
                if (!Player.getInstance().play(m_iPort, surfaceView.getHolder())) {
                    Log.e(TAG_ERROR, "play failed");
                    return;
                }
                if (!Player.getInstance().playSound(m_iPort)) {
                    Log.e(TAG_ERROR, "playSound failed with error code:" + Player.getInstance().getLastError(m_iPort));
                    return;
                }
            }
        } else {
            if (!Player.getInstance().inputData(m_iPort, pDataBuffer, iDataSize)) {
                for (int i = 0; i < 4000 && m_iPlaybackID >= 0 && !m_bStopPlayback; i++) {
                    if (Player.getInstance().inputData(m_iPort, pDataBuffer, iDataSize)) {
                        break;
                    }
                    if (i % 100 == 0) {
                        Log.e(TAG_ERROR, "inputData failed with: " + Player.getInstance().getLastError(m_iPort) + ", i:" + i);
                    }
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}
如果返回的m_iPlayID不小于0,则实时预览成功,于是可以看到海康摄像头的实时视频。

停止实时预览,具体实现代码如下:

/**
 * 停止实时预览
 * @param playId
 * @param port
 */
public void stopLive(int playId, int port) {
    if (playId >= 0) {
        if (HCNetSDK.getInstance().NET_DVR_StopRealPlay(playId)) {
            Player.getInstance().stopSound();
            if (Player.getInstance().stop(port)) {
                if (Player.getInstance().closeStream(port)) {
                    if (Player.getInstance().freePort(port)) {
                        Log.i(TAG, "close success");
                    } else {
                        Log.e(TAG_ERROR, "freePort is failed!" + port);
                    }
                } else {
                    Log.e(TAG_ERROR, "closeStream is failed!");
                }
            } else {
                Log.e(TAG_ERROR, "stop is failed!");
            }
        } else {
            Log.e(TAG_ERROR, "StopRealPlay is failed!Err:" + HCNetSDK.getInstance().NET_DVR_GetLastError());
        }
    }
}

对海康摄像头进行录像回放,我们这里是采用按照时间进行回放,用到的方法是HCNetSDK.getInstance().NET_DVR_PlayBackByTime(int var1, int var2, NET_DVR_TIME var3, NET_DVR_TIME var4)

具体实现代码如下:

用之前登录成功返回的iLogID和之前获取的通道号

NET_DVR_TIME struBegin = new NET_DVR_TIME();  //开始时间
NET_DVR_TIME struEnd = new NET_DVR_TIME();  //结束时间
struBegin.dwYear = bgYear;
struBegin.dwMonth = bgMonth;
struBegin.dwDay = bgDay;
struBegin.dwHour = bgHour;
struBegin.dwMinute = bgMinute;
struBegin.dwSecond = bgSecond;
struEnd.dwYear = endYear;
struEnd.dwMonth = endMonth;
struEnd.dwDay = endDay;
struEnd.dwHour = endHour;
struEnd.dwMinute = endMinute;
struEnd.dwSecond = endSecond;
PlaybackCallBack fPlaybackCallBack = getPlayerbackPlayerCbf();
  private PlaybackCallBack getPlayerbackPlayerCbf() {
        PlaybackCallBack cbf = new PlaybackCallBack() {
            @Override
            public void fPlayDataCallBack(int iPlaybackHandle, int iDataType, byte[] pDataBuffer, int iDataSize) {
                processRealData(1, iDataType, pDataBuffer, iDataSize, Player.STREAM_FILE);
            }
        };
        return cbf;
    }

  public void processRealData(int iPlayViewNo, int iDataType, byte[] pDataBuffer, int iDataSize, int iStreamMode) {
        if(m_bNeedDecode) {
            if(HCNetSDK.NET_DVR_SYSHEAD == iDataType) {
                /*if(m_iPort >= 0)
                {
                    return;
                }*/
                m_iPort = Player.getInstance().getPort();
                if(m_iPort == -1) {
                    Log.e(TAG, "Hikvision getPort is failed with: " + Player.getInstance().getLastError(m_iPort));
                    return;
                }
                Log.i(TAG, "Hikvision getPort succ with: " + m_iPort);
                if (iDataSize > 0) {
                    if (!Player.getInstance().setStreamOpenMode(m_iPort, iStreamMode)) {  //set stream mode
                        Log.e(TAG, "Hikvision setStreamOpenMode failed");
                        return;
                    }
                    if (!Player.getInstance().openStream(m_iPort, pDataBuffer, iDataSize, 2*1024*1024)) {  //open stream
                        Log.e(TAG, "Hikvision openStream failed");
                        return;
                    }
                    if (!Player.getInstance().play(m_iPort, surfaceView.getHolder())) {
                        Log.e(TAG, "Hikvision play failed");
                        return;
                    }
                    if(!Player.getInstance().playSound(m_iPort)) {
                        Log.e(TAG, "Hikvision playSound failed with error code:" + Player.getInstance().getLastError(m_iPort));
                        return;
                    }
                }
            } else {
                if (!Player.getInstance().inputData(m_iPort, pDataBuffer, iDataSize)) {
//              Log.e(TAG, "inputData failed with: " + Player.getInstance().getLastError(m_iPort));
                    for(int i = 0; i < 4000 && m_iPlaybackID >=0 && !m_bStopPlayback; i++) {
                        if (Player.getInstance().inputData(m_iPort, pDataBuffer, iDataSize)) {
                            break;
                        }
                        if(i % 100 == 0) {
                            Log.e(TAG, "Hikvision inputData failed with: " + Player.getInstance().getLastError(m_iPort) + ", i:" + i);
                        }
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
int m_iPlaybackID = HCNetSDK.getInstance().NET_DVR_PlayBackByTime(iLogID, channelNo, struBegin, struEnd);
if(m_iPlaybackID >= 0) {
    if(!HCNetSDK.getInstance().NET_DVR_SetPlayDataCallBack(m_iPlaybackID, fPlaybackCallBack)) {
        Log.e(TAG, "Hikvision set playback callback failed!");
        Message msg = Message.obtain();
        msg.what = 1;
        if (!PlaybackActivity.this.isFinishing()) {
            msg.obj = getResources().getString(R.string.fail_start_playback);
        }
        handler.sendMessage(msg);
        return ;
    }
    NET_DVR_PLAYBACK_INFO struPlaybackInfo = null ;
    if(!HCNetSDK.getInstance().NET_DVR_PlayBackControl_V40(m_iPlaybackID, PlaybackControlCommand.NET_DVR_PLAYSTART, null, 0, struPlaybackInfo)) {
        Log.e(TAG, "Hikvision net sdk playback start failed!");
        Message msg = Message.obtain();
        msg.what = 1;
        if (!PlaybackActivity.this.isFinishing()) {
            msg.obj = getResources().getString(R.string.fail_start_playback);
        }
        handler.sendMessage(msg);
        return ;
    }
    m_bStopPlayback = false;
    loadFinish = true;
    Message msg = Message.obtain();
    msg.what = 2;
    handler.sendMessage(msg);
    Thread thread = new Thread()
    {
        public void run()
        {
            int nProgress = -1;
            while(true) {
                nProgress = HCNetSDK.getInstance().NET_DVR_GetPlayBackPos(m_iPlaybackID);
                if(nProgress < 0 || nProgress >= 100) {
                    break;
                }

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    };
    thread.start();
} else {
    Log.e(TAG, "Hikvision NET_DVR_PlayBackByTime failed, error code: " + HCNetSDK.getInstance().NET_DVR_GetLastError());
}

停止回放,具体实现代码如下:

public void stopPlaybackHikvision() {
    m_bStopPlayback = true;
    if(!HCNetSDK.getInstance().NET_DVR_StopPlayBack(m_iPlaybackID)) {
        Log.e(TAG, "Hikvision net sdk stop playback failed");
    }
    stopSinglePlayer();
    Log.i(TAG, "Hikvision close success");
}

private void stopSinglePlayer() {
    Player.getInstance().stopSound();
    // player stop play
    if (!Player.getInstance().stop(m_iPort)) {
        Log.e(TAG, "Hikvision stop is failed!");
        return;
    }

    if(!Player.getInstance().closeStream(m_iPort)) {
        Log.e(TAG, "Hikvision closeStream is failed!");
        return;
    }
    if(!Player.getInstance().freePort(m_iPort)) {
        Log.e(TAG, "Hikvision freePort is failed!" + m_iPort);
        return;
    }
    m_iPort = -1;
}

你可能感兴趣的:(音视频)