基于Android的海康威视的二次开发

基于Android的海康威视的二次开发

在最近的项目中使用到了海康监控的使用及简单的控制,经过网上的一番搜查及整合,在使用中我是在同一个局域网实现效果的。

  1. 首先是导入相应的sdk和jar包,网上有很多资源这里就不再讲述了
  2. 导入完包后再build.gradle中添加以下代码进行同步
android{
	...
	sourceSets.main {
        jniLibs.srcDirs = ['libs']
    }
}
dependencies {
	...
	compile files('libs/jna.jar')
    compile files('libs/AudioEngineSDK.jar')
    compile files('libs/HCNetSDK.jar')
    compile files('libs/PlayerSDK.jar')
    }
  1. 记得在AndroidManifest.xml中添加网络权限等
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<!--允许应用程序完全使用网络-->
<uses-permission android:name="android.permission.INTERNET"/>
  1. 设置简单的布局文件activity_sxt.xml,通过控件SurfaceView放置监控内容,这里我用的是悬浮按钮FloatingActionButton进行接下来的控制操作
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:fab="http://schemas.android.com/apk/res-auto">
    <SurfaceView
        android:id="@+id/video_surfaceview"
        android:layout_width="match_parent"
        android:layout_height="250dp"
        android:layout_alignParentLeft="true" />
    <com.getbase.floatingactionbutton.FloatingActionsMenu
        android:layout_below="@id/video_surfaceview"
        android:id="@+id/multiple_actions"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        fab:fab_expandDirection="right"
        >

        <com.getbase.floatingactionbutton.FloatingActionButton
            android:id="@+id/action_right"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            fab:fab_size="mini"
            fab:fab_title="右转"
            android:background="@mipmap/sx"/>

        <com.getbase.floatingactionbutton.FloatingActionButton
            android:id="@+id/action_left"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            fab:fab_size="mini"
            fab:fab_title="左转"/>

        <com.getbase.floatingactionbutton.FloatingActionButton
            android:id="@+id/action_down"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            fab:fab_size="mini"
            fab:fab_title="向下" />
        <com.getbase.floatingactionbutton.FloatingActionButton
            android:id="@+id/action_up"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            fab:fab_size="mini"
            fab:fab_title="向上" />
    </com.getbase.floatingactionbutton.FloatingActionsMenu>
</RelativeLayout>
  1. 添加HikUtil.java文件,在文件中我添加了,向上向下向左向右放大缩小的功能
package com.....haikang.utils;
//新建HikUtil.java文件复制以下内容即可
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.TextureView;
import com.hikvision.netsdk.ExceptionCallBack;
import com.hikvision.netsdk.HCNetSDK;
import com.hikvision.netsdk.NET_DVR_DEVICEINFO_V30;
import com.hikvision.netsdk.NET_DVR_PREVIEWINFO;
import com.hikvision.netsdk.PTZCommand;
import com.hikvision.netsdk.RealPlayCallBack;

import org.MediaPlayer.PlayM4.Player;

import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;

/**
 * Created date: 2017/4/11
 * Author:  Leslie
 * 1.HikUtil.initSDK();
 * 2.HikUtil hikUtil = new HikUtil();
 * 2.hikUtil.initView(surfaceView);
 * 3.hikUtil.setDeviceData("192.168.1.22",8000,"admin","eyecool2016");
 * 4.hikUtil.loginDevice(mHandler,LOGIN_SUCCESS_CODE);
 * 5.hikUtil.playOrStopStream();
 */

public class HikUtil {
    private static final String TAG = "HikUtil";
    private static final int HIK_MAIN_STREAM_CODE = 0;      //主码流
    private static final int HIK_SUB_STREAM_CODE = 1;      //子码流
    private NET_DVR_DEVICEINFO_V30 m_oNetDvrDeviceInfoV30 = null;
    private static int m_iStartChan = 0;
    private  int m_iPort = -1;
    private  int m_iPlaybackID = -1;
    private static int logId = -1;
    private  int playId = -1;
    private SurfaceView mSurfaceView;
    private TextureView mtextureView;
    public String mIpAddress;
    private  int mPort;
    private String mUserName;
    private String mPassWord;
    public  onPicCapturedListener mPicCapturedListener;
    private SimpleDateFormat sDateFormat;
    private  Player.MPInteger stWidth;
    private  Player.MPInteger stHeight;
    private  Player.MPInteger stSize;

    /**
     * 定义接口,用于监听图片截图成功
     */
    public interface onPicCapturedListener {
        void onPicCaptured(Bitmap bitmap, String bitmapFileAbsolutePath);

        void onPicDataSaved(byte[] picData);
    }

    public HikUtil() {
    }

    /**
     * 初始化HCNet SDK
     *
     * @return
     */
    public static boolean initSDK() {

        if (!HCNetSDK.getInstance().NET_DVR_Init()) {
            Log.e(TAG, "HCNetSDK ---------初始化失败!");
            return false;
        }
        //打印日志到本地,暂时不用打印
//        HCNetSDK.getInstance().NET_DVR_SetLogToFile(3, "/mnt/sdcard/sdklog/", true);
        return true;
    }
    /**
     * 停止播放
     */
    public synchronized void stopPlay() {
        if (playId < 0) {
            Log.d(TAG, "已经停止?");
            return;
        }
        // 停止网络播放
        if (HCNetSDK.getInstance().NET_DVR_StopRealPlay(playId)) {
            Log.i(TAG, "停止实时播放成功!");
        } else {
            Log.e(TAG, "停止实时播放失败!" );
            return;
        }
        // 停止本地播放
        if (Player.getInstance().stop(m_iPort)) {
            Log.i(TAG, "停止本地播放成功!");
        } else {
            Log.e(TAG, "停止本地播放失败!");
            return;
        }
        // 关闭视频流
        if (Player.getInstance().closeStream(m_iPort)) {
            Log.i(TAG, "关闭视频流成功!");
        } else {
            Log.e(TAG, "关闭视频流失败!");
            return;
        }
        // 释放播放端口
        if (Player.getInstance().freePort(m_iPort)) {
            Log.i(TAG, "释放播放端口成功!");
        } else {
            Log.e(TAG, "释放播放端口失败!");
            return;
        }
        // 播放端口复位
        m_iPort = -1;
        // 正在播放标记复位
        playId = -1;
        Log.i(TAG, "停止播放成功!");
    }
    /**
     * 登出设备
     */
    public void logoutDevice() {
//        if (HCNetSDK.getInstance().NET_DVR_Logout_V30(logId)) {
//            playId = -1;
//            Log.i(TAG, "登出设备成功!");
//        } else {
//            playId = 0;
//            Log.e(TAG, "登出设备失败!");
//        }
        // 是否登出
        if (!HCNetSDK.getInstance().NET_DVR_Logout_V30(logId)) {
            Log.e(TAG, " 用户注销失败!");
        }else {
            Log.e(TAG,"用户注销成功!");
        }
        logId = -1;
    }
    /**
     * 释放海康SDK
     */
    public void freeSDK() {
        // 清理缓存
        if (HCNetSDK.getInstance().NET_DVR_Cleanup()) {
            Log.i(TAG, "释放SDK资源成功!");
        } else {
            Log.e(TAG, "释放SDK资源失败!");
        }
    }

    //控制台操作
    public static void startup(){
        if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(
            logId, m_iStartChan, PTZCommand.TILT_UP, 0)) {
        Log.e(TAG,
                "start PAN_LEFT failed with error code: "
                        + HCNetSDK.getInstance()
                        .NET_DVR_GetLastError());
        } else {
            Log.i(TAG, "start TILT_UP succ");
        }
    }
    public static void stopup(){
        if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(
                logId, m_iStartChan, PTZCommand.TILT_UP, 1)) {
            Log.e(TAG,
                    "start PAN_LEFT failed with error code: "
                            + HCNetSDK.getInstance()
                            .NET_DVR_GetLastError());
        } else {
            Log.i(TAG, "stop TILT_UP succ");
        }
    }
    public static void startdown(){
        if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(
                logId, m_iStartChan, PTZCommand.TILT_DOWN, 0)) {
            Log.e(TAG,
                    "start PAN_LEFT failed with error code: "
                            + HCNetSDK.getInstance()
                            .NET_DVR_GetLastError());
        } else {
            Log.i(TAG, "start TILT_DOWN succ");
        }
    }
    public static void stopdown(){
        if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(
                logId, m_iStartChan, PTZCommand.TILT_DOWN, 1)) {
            Log.e(TAG,
                    "start PAN_LEFT failed with error code: "
                            + HCNetSDK.getInstance()
                            .NET_DVR_GetLastError());
        } else {
            Log.i(TAG, "stop TILT_DOWN succ");
        }
    }
    public static void startleft(){
        if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(
                logId, m_iStartChan, PTZCommand.PAN_LEFT, 0)) {
            Log.e(TAG,
                    "start PAN_LEFT failed with error code: "
                            + HCNetSDK.getInstance()
                            .NET_DVR_GetLastError());
        } else {
            Log.i(TAG, "start PAN_LEFT succ");
        }
    }
    public static void stopleft(){
        if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(
                logId, m_iStartChan, PTZCommand.PAN_LEFT, 1)) {
            Log.e(TAG,
                    "start PAN_LEFT failed with error code: "
                            + HCNetSDK.getInstance()
                            .NET_DVR_GetLastError());
        } else {
            Log.i(TAG, "stop PAN_LEFT succ");
        }
    }
    public static void startright(){
        if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(
                logId, m_iStartChan, PTZCommand.PAN_RIGHT, 0)) {
            Log.e(TAG,
                    "start PAN_LEFT failed with error code: "
                            + HCNetSDK.getInstance()
                            .NET_DVR_GetLastError());
        } else {
            Log.i(TAG, "start PAN_RIGHT succ");
        }
    }
    public static void stopright(){
        if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(
                logId, m_iStartChan, PTZCommand.PAN_RIGHT, 1)) {
            Log.e(TAG,
                    "start PAN_LEFT failed with error code: "
                            + HCNetSDK.getInstance()
                            .NET_DVR_GetLastError());
        } else {
            Log.i(TAG, "stop PAN_RIGHT succ");
        }
    }
    public static void startfd(){
        if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(
                logId, m_iStartChan, PTZCommand.ZOOM_IN, 0)) {
            Log.e(TAG,
                    "start PAN_LEFT failed with error code: "
                            + HCNetSDK.getInstance()
                            .NET_DVR_GetLastError());
        } else {
            Log.i(TAG, "start ZOOM_IN succ");
        }
    }
    public static void stopfd(){
        if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(
                logId, m_iStartChan, PTZCommand.ZOOM_IN, 1)) {
            Log.e(TAG,
                    "start PAN_LEFT failed with error code: "
                            + HCNetSDK.getInstance()
                            .NET_DVR_GetLastError());
        } else {
            Log.i(TAG, "stop ZOOM_IN succ");
        }
    }
    public static void startsx(){
        if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(
                logId, m_iStartChan, PTZCommand.ZOOM_OUT   , 0)) {
            Log.e(TAG,
                    "start PAN_LEFT failed with error code: "
                            + HCNetSDK.getInstance()
                            .NET_DVR_GetLastError());
        } else {
            Log.i(TAG, "start ZOOM_OUT succ");
        }
    }
    public static void stopsx(){
        if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(
                logId, m_iStartChan, PTZCommand.ZOOM_OUT   , 1)) {
            Log.e(TAG,
                    "start PAN_LEFT failed with error code: "
                            + HCNetSDK.getInstance()
                            .NET_DVR_GetLastError());
        } else {
            Log.i(TAG, "stop ZOOM_OUT succ");
        }
    }

    public  void initView(SurfaceView surfaceView) {
        mSurfaceView = surfaceView;
        mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                mSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
                Log.i(TAG, "surface is created" + m_iPort);
                if (-1 == m_iPort) {
                    return;
                }
                Surface surface = holder.getSurface();
                if (surface.isValid()) {
                    if (!Player.getInstance().setVideoWindow(m_iPort, 0, holder)) {
                        Log.e(TAG, "播放器设置或销毁显示区域失败!");
                    }else {
                        Log.e(TAG, "播放器设置或销毁显示区域成功!");
                    }
                }
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                Log.i(TAG, "Player setVideoWindow release!" + m_iPort);
                if (-1 == m_iPort) {
                    return;
                }
                if (holder.getSurface().isValid()) {
                    if (!Player.getInstance().setVideoWindow(m_iPort, 0, null)) {
                        Log.e(TAG, "播放器设置或销毁显示区域失败!");
                    }
                }
            }
        });
    }

    /**
     * 配置网络摄像头参数
     * @param ipAddress IP 地址
     * @param port 端口号,默认是 8000
     * @param userName 用户名
     * @param passWord 密码
     */
    public  void setDeviceData(String ipAddress, int port, String userName, String passWord) {
        mIpAddress = ipAddress;
        mPort = port;
        mUserName = userName;
        mPassWord = passWord;

    }

    public  void loginDevice(final Handler handler, final int resultCode) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                boolean loginState = login(mIpAddress, mPort, mUserName, mPassWord);
                Message message = handler.obtainMessage();
                message.obj = loginState;
                message.what = resultCode;
                handler.sendMessage(message);
            }
        }).start();
    }

    /**
     * 播放或者停止播放视频流
     */
    public  void playOrStopStream() {

        if (logId < 0) {
            Log.e(TAG, "请先登录设备");
            return;
        }
        if (playId < 0) {   //播放

            RealPlayCallBack fRealDataCallBack = getRealPlayerCbf();
            if (fRealDataCallBack == null) {
                Log.e(TAG, "fRealDataCallBack object is failed!");
                return;
            }
            Log.i(TAG, "m_iStartChan:" + m_iStartChan);

            NET_DVR_PREVIEWINFO previewInfo = new NET_DVR_PREVIEWINFO();
            previewInfo.lChannel = m_iStartChan;
            previewInfo.dwStreamType = HIK_SUB_STREAM_CODE;                                                             //子码流
            previewInfo.bBlocked = 1;
            // HCNetSDK start preview
            playId = HCNetSDK.getInstance().NET_DVR_RealPlay_V40(logId, previewInfo, fRealDataCallBack);
            if (playId < 0) {
                Log.e(TAG, "实时预览失败!-----------------Err:" + HCNetSDK.getInstance().NET_DVR_GetLastError());
                return;
            }

            Log.i(TAG, "NetSdk 播放成功 !");
//            mPlayButton.setText("停止");
        } else {    //停止播放
            if (playId < 0) {
                Log.e(TAG, "m_iPlayID < 0");
                return;
            }

            //  net sdk stop preview
            if (!HCNetSDK.getInstance().NET_DVR_StopRealPlay(playId)) {
                Log.e(TAG, "停止预览失败!----------------错误:" + HCNetSDK.getInstance().NET_DVR_GetLastError());
                return;
            }

            playId = -1;
            Player.getInstance().stopSound();
            // player stop play
            if (!Player.getInstance().stop(m_iPort)) {
                Log.e(TAG, "-------------------暂停失败!");
                return;
            }else {
                Log.e(TAG, "-------------------暂停成功!");
            }

            if (!Player.getInstance().closeStream(m_iPort)) {
                Log.e(TAG, "-------------------关流失败!");
                return;
            }
            if (!Player.getInstance().freePort(m_iPort)) {
                Log.e(TAG, "-------------------释放播放端口失败!" + m_iPort);
                return;
            }
            m_iPort = -1;
            logId = -1;
            playId = -1;
//            mPlayButton.setText("播放");
        }

    }

    private RealPlayCallBack getRealPlayerCbf() {
        RealPlayCallBack cbf = new RealPlayCallBack() {
            public void fRealDataCallBack(int iRealHandle, int iDataType, byte[] pDataBuffer, int iDataSize) {
                // 播放通道1
                processRealData(1, iDataType, pDataBuffer, iDataSize, Player.STREAM_REALTIME);
            }
        };
        return cbf;
    }

    public  void processRealData(int iPlayViewNo, int iDataType, byte[] pDataBuffer, int iDataSize, int iStreamMode) {
        if (HCNetSDK.NET_DVR_SYSHEAD == iDataType) {
            if (m_iPort >= 0) {
                return;
            }
            m_iPort = Player.getInstance().getPort();
            if (m_iPort == -1) {
                Log.e(TAG, "获取端口失败!: " + Player.getInstance().getLastError(m_iPort));
                return;
            }
            Log.i(TAG, "获取端口成功!: " + m_iPort);
            if (iDataSize > 0) {
                if (!Player.getInstance().setStreamOpenMode(m_iPort, iStreamMode))  //set stream mode
                {
                    Log.e(TAG, "设置流播放模式失败!");
                    return;
                }
                if (!Player.getInstance().openStream(m_iPort, pDataBuffer, iDataSize, 2 * 1024 * 1024)) //open stream
                {
                    Log.e(TAG, "打开流失败!");
                    return;
                }
                if (!Player.getInstance().play(m_iPort, mSurfaceView.getHolder())) {
                    Log.e(TAG, "播放失败!");
                    return;
                }
                if (!Player.getInstance().playSound(m_iPort)) {
                    Log.e(TAG, "以独占方式播放音频失败!失败码 :" + 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; i++) {
                    if (!Player.getInstance().inputData(m_iPort, pDataBuffer, iDataSize))
                        Log.e(TAG, "输入流数据失败: " + Player.getInstance().getLastError(m_iPort));
                    else
                        break;
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();

                    }
                }
            }

        }

    }

    private  boolean login(String ipAddress, int portNum, String userName, String passWord) {
        try {
            if (logId < 0) {
                // 登录设备
                logId = loginDevice(ipAddress, portNum, userName, passWord);
                if (logId < 0) {
                    Log.e(TAG, "设备登录失败!");
                    return false;
                }
                // 获取异常回调和异常设置的回调
                ExceptionCallBack oexceptionCbf = getExceptiongCbf();
                if (oexceptionCbf == null) {
                    Log.e(TAG, "异常回调对象失败!");
                    return false;
                }

                if (!HCNetSDK.getInstance().NET_DVR_SetExceptionCallBack(oexceptionCbf)) {
                    Log.e(TAG, "注册接收异常、重连消息回调函数失败 !");
                    return false;
                }

//                loginButton.setText("注销");
                Log.i(TAG, "登录成功 !");
                return true;
            } else {
                // 是否登出
                if (!HCNetSDK.getInstance().NET_DVR_Logout_V30(logId)) {
                    Log.e(TAG, " 用户注销失败!");
                    return false;
                }else {
                    Log.e(TAG,"用户注销成功!");
                }
//                loginButton.setText("登录");
                logId = -1;
                return true;
            }
        } catch (Exception err) {
            Log.e(TAG, "错误: " + err.toString());
            return false;
        }
    }

    private  int loginDevice(String ipAddress, int portNum, String userName, String passWord) {
        //实例化设备信息对象
        m_oNetDvrDeviceInfoV30 = new NET_DVR_DEVICEINFO_V30();
        if (null == m_oNetDvrDeviceInfoV30) {
            Log.e(TAG, "实例化设备信息(NET_DVR_DEVICEINFO_V30)失败!");
            return -1;
        }
        // call NET_DVR_Login_v30 to login on, port 8000 as default
        int iLogID = HCNetSDK.getInstance().NET_DVR_Login_V30(ipAddress, portNum, userName, passWord, m_oNetDvrDeviceInfoV30);
        if (iLogID < 0) {
            Log.e(TAG, "网络设备登录失败!-------------Err:" + HCNetSDK.getInstance().NET_DVR_GetLastError());
            return -1;
        }
        if (m_oNetDvrDeviceInfoV30.byChanNum > 0) {
            m_iStartChan = m_oNetDvrDeviceInfoV30.byStartChan;
        } else if (m_oNetDvrDeviceInfoV30.byIPChanNum > 0) {
            m_iStartChan = m_oNetDvrDeviceInfoV30.byStartDChan;
        }
        Log.i(TAG, "网络设备登录成功!");

        return iLogID;
    }

    private ExceptionCallBack getExceptiongCbf() {
        ExceptionCallBack oExceptionCbf = new ExceptionCallBack() {
            public void fExceptionCallBack(int iType, int iUserID, int iHandle) {
                System.out.println("recv exception------------------------------, type:" + iType);
            }
        };
        return oExceptionCbf;
    }

    /**
     * 截取一帧图片,成功返回bitmap对象,失败返回null
     * 经测试得出:
     * 获取截图数据耗时 <10ms
     * 获取截图数据后保存到磁盘耗时 ≈25ms
     * 从获取截图数-保存到磁盘-解码文件到 bitmap 耗时 ≈45ms
     */
    public Bitmap captureFrame(onPicCapturedListener picCapturedListener) {
        try {
            long time1 = System.currentTimeMillis();
            mPicCapturedListener = picCapturedListener;
            Player.MPInteger stWidth = new Player.MPInteger();
            Player.MPInteger stHeight = new Player.MPInteger();
            if (!Player.getInstance().getPictureSize(m_iPort, stWidth, stHeight)) {
                Log.e(TAG, "获取图片尺寸失败---> error code:" + Player.getInstance().getLastError(m_iPort));
                return null;
            }
            int nSize = 5 * stWidth.value * stHeight.value;
            byte[] picBuf = new byte[nSize];
            Player.MPInteger stSize = new Player.MPInteger();
            if (!Player.getInstance().getBMP(m_iPort, picBuf, nSize, stSize)) {
                Log.e(TAG, "获取位图失败----> error code:" + Player.getInstance().getLastError(m_iPort));
                return null;
            }
            long time2 = System.currentTimeMillis();
            if (sDateFormat == null) {
                sDateFormat = new SimpleDateFormat("yyyy-MM-dd-hh_mm_ss_Sss");
            }
            String date = sDateFormat.format(new java.util.Date());
            File dir = new File(Environment.getExternalStorageDirectory() + "/capture");
            if (!dir.exists()) {
                dir.mkdir();
            }
            File file = new File(dir, date + ".jpg");
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(picBuf, 0, stSize.value);
            fos.close();
            long time3 = System.currentTimeMillis();
            Bitmap bitmap = BitmapFactory.decodeFile(dir.getAbsolutePath() + "/" + date + ".jpg");
            long time4 = System.currentTimeMillis();
            //图片保存成功了,通知给外面
            mPicCapturedListener.onPicCaptured(bitmap, file.getAbsolutePath());
            return bitmap;
        } catch (Exception err) {
            Log.e(TAG, "error: " + err.toString());
        } finally {

            return null;
        }
    }

    /**
     * 截取一帧图片,成功返回bitmap对象,失败返回null
     * 图片数据存放在内存中
     */
    public  byte[] captureFrameOnMemroy(onPicCapturedListener picCapturedListener, Handler handler) {
        try {
            long start = System.currentTimeMillis();
            mPicCapturedListener = picCapturedListener;
            if (stWidth == null) {
                stWidth = new Player.MPInteger();
            }
            if (stHeight == null) {
                stHeight = new Player.MPInteger();
            }
            if (!Player.getInstance().getPictureSize(m_iPort, stWidth, stHeight)) {
                Log.e(TAG, "获取图片尺寸失败---> error code:" + Player.getInstance().getLastError(m_iPort));
                return null;
            }
            int nSize = 5 * stWidth.value * stHeight.value;
            byte[] picBuf = new byte[nSize];
            if (stSize == null) {

                stSize = new Player.MPInteger();
            }
            if (!Player.getInstance().getBMP(m_iPort, picBuf, nSize, stSize)) {
//                mPicCapturedListener.onPicDataSavedError();
                Log.e(TAG, "获取位图失败----> error code:" + Player.getInstance().getLastError(m_iPort));
                return null;
            }
            //图片保存数据获取成功了,通知给外面。或者用handler发送出去
           /* mPicCapturedListener.onPicDataSaved(picBuf);
            Message message = handler.obtainMessage();
            message.obj = picBuf;
            message.what = Constant.VIDEO_FRAME_PIC_DATA_SAVED;
            handler.sendMessage(message);
            long end = System.currentTimeMillis();*/
            return picBuf;
        } catch (Exception err) {
            Log.e(TAG, "error: " + err.toString());
        }
        return null;
    }
}

  1. 接下来就是设置连接摄像头进行登录播放操作,连接摄像头需要的参数包括IP,账号,密码,端口信息(我这里用的端口信息是8000)
public class sxt extends Activity{
	private static final String TAG = "sxt";
    //----------------------------------------------------------------------------------------------
    SurfaceView video_surfaceview;
    //----------------------------------------------------------------------------------------------
    private static final int PLAY_HIK_STREAM_CODE = 1001;
    private static final int PLAY_HIK_STREAM_CODE_2 = 1002;
    private  String IP_ADDRESS ="设置自己摄像头的ip地址";
    private static final int PORT = 8000;
    private static final String USER_NAME = "用户名";
    private static final String PASSWORD = "密码";
    //----------------------------------------------------------------------------------------------

    private Handler mHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what) {
                case PLAY_HIK_STREAM_CODE:
                    hikUtil.playOrStopStream();
                    break;
                case PLAY_HIK_STREAM_CODE_2:
                    hikUtil2.playOrStopStream();
                    break;
                default:
                    break;
            }
            return false;
        }
    });
    private HikUtil hikUtil;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sxt);
        video_surfaceview = findViewById(R.id.video_surfaceview); 
        /*
        设置三个悬浮按钮的监听事件
         */
        //摄像头向上转动
        final FloatingActionButton actionA = (FloatingActionButton) findViewById(R.id.action_up);
        actionA.setOnTouchListener(new View.OnTouchListener() {
        //由于调用向左转动的方法,会停不下来,所以这里我加了监听点击按键不放即调用启动向左转动方法,松开按键即调用停止向左转动的方法
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    HikUtil.startup();
                }else if (event.getAction() == MotionEvent.ACTION_UP) {
                    HikUtil.stopup();
                }
                return false;
            }
        });
        //摄像头向下转动
        final FloatingActionButton actionB = (FloatingActionButton) findViewById(R.id.action_down);
        actionB.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    HikUtil.startdown();
                }else if (event.getAction() == MotionEvent.ACTION_UP) {
                    HikUtil.stopdown();
                }
                return false;
            }
        });
        //左转
        final FloatingActionButton actionC = (FloatingActionButton) findViewById(R.id.action_left);
        actionC.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    HikUtil.startleft();
                }else if (event.getAction() == MotionEvent.ACTION_UP) {
                    HikUtil.stopleft();
                }
                return false;
            }
        });
        //右转
        final FloatingActionButton actionD = (FloatingActionButton) findViewById(R.id.action_right);
        actionD.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    HikUtil.startright();
                }else if (event.getAction() == MotionEvent.ACTION_UP) {
                    HikUtil.stopright();
                }
                return false;
            }
        });
        HikUtil.initSDK();
        hikUtil = new HikUtil();
        hikUtil.initView(video_surfaceview);
        hikUtil.setDeviceData(IP_ADDRESS, PORT, USER_NAME, PASSWORD);
        //登录设备
        hikUtil.loginDevice(mHandler, PLAY_HIK_STREAM_CODE);
        //播放设备
        hikUtil.playOrStopStream();
    }
}
  1. 到此为止即可正常调用摄像头,但是有些项目会遇到只有一个SurfaceView控件进行切换摄像头的操作,切换摄像头就是通过改变之前提到的四个参数来调用其他的摄像头,重点来了,再改变参数之前需要释放掉在原控件中的sdk资源,只需要调用以下方法,再使用步骤七中的登录方法即可
	//停止播放
	hikUtil.stopPlay();
	//注销设备
    hikUtil.logoutDevice();
    //释放sdk资源
    hikUtil.freeSDK();

希望对大家有所帮助,如有疑问欢迎在评论区留言。

  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 19
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值