Springboot java基于海康威视SDK二次开发

        最近项目中用到海康威视的摄像头实现人员移动检测以及前端页面手机端等查看实时摄像头。由于第一次基于海康SDK开发,留一笔记用于记录,同时希望帮助到后来人。废话不多说,直接开始:

注:本文中所有的代码和工具包的下载地址如下(可导入idea直接运行)

传送门 海康威视SpringBoot运行demo

PS:本文实现的功能如下(后期如用到会增加功能)

  • 设备的布防、撤防(布防成功后可实现对客流量统计、移动侦测、设备遮挡、人脸侦测报警等。更多报警类型查看官方文档,本文只实现移动侦测作为例子。)
  • 摄像头实时视频(用于web端、手机端观看)

传送门:官方SDK下载

本文所用sdk版本:

CH-HCNetSDKV6.1.6.45_build20210302_linux64

CH-HCNetSDKV6.1.6.45_build20210302_win64

一、流程分析

  1. 集成海康sdk到项目

  2. 实现登录布防、撤防、注销、监听等功能

  3. 获取摄像头的rtsp视频流转成rtmp直播流网页显示

  4. 搭建流媒体服务器

二、具体实现过程

1. 集成海康sdk到项目

        由于服务器用的是CentOS,所以本文用的是Linux版SDK。但是本地开发调试一般我们用的是windows系统,所以兼容的windowsSDK。

ps:为了方便调试先以windowsSDK为例

下载sdk后解压

把jna.jar examples.jar加入到本地maven库中

Maven 安装 JAR 包的命令:

<dependency>
    <groupId>net.java.jna</groupId>-----------------(参数二)
    <artifactId>jna </artifactId>-----------(参数三)
    <version>1.0.0</version>------------(参数四)
</dependency>

#语法
mvn install:install-file -Dfile=jar包的位置(参数一) -DgroupId=groupId(参数二) -DartifactId=artifactId(参数三) -Dversion=version(参数四) -Dpackaging=jar

mvn install:install-file -Dfile="D:\jna.jar" -DgroupId=net.java.jna -DartifactId=jna -Dversion=1.0.0 -Dpackaging=jar

在项目根目录创建lib文件,把库文件里的所有文件复制到项目lib文件里(如需精简请查看官方sdk里的txt文件)。如下图:

由于项目需要部署到Linux服务器所以打开LinuxSDK文件夹下》LinuxJavaDemo》src》test》把HCNetSDK.java复制到项目中,如果部署到windows服务器,复制windowSDK的Demo里的此文件。(HCNetSDK.java在不同的sdk中的方法不一样)

项目部署到Linux系统时,需要使用Linux版的sdk包,把LinuxSDK中的lib包上传到服务器,可以使用绝对路径、也可以使用官方文档中的方法。

2.实现登录布防、撤防、注销、监听等功能

初始化sdk实例

 注册登录,登录成功会返回用户id,用户id用于布防和注销登录

   /**
     * 注册登录
     *
     * @param m_sDeviceIP 设备ip
     * @param m_sUsername 设备用户名
     * @param m_sPassword 设备密码
     * @param m_sPort     设备端口
     * @return
     */
    public Integer login(String m_sDeviceIP, String m_sUsername, String m_sPassword, short m_sPort) {
        // 初始化
        if (!hCNetSDK.NET_DVR_Init()) {
            log.error("SDK初始化失败");
        }
        //设置连接时间与重连时间
        hCNetSDK.NET_DVR_SetConnectTime(2000, 1);
        hCNetSDK.NET_DVR_SetReconnect(100000, true);
        //设备信息, 输出参数
        HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
        HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
        // 注册设备-登录参数,包括设备地址、登录用户、密码等
        m_strLoginInfo.sDeviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
        System.arraycopy(m_sDeviceIP.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, m_sDeviceIP.length());
        m_strLoginInfo.sUserName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
        System.arraycopy(m_sUsername.getBytes(), 0, m_strLoginInfo.sUserName, 0, m_sUsername.length());
        m_strLoginInfo.sPassword = new byte[HCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
        System.arraycopy(m_sPassword.getBytes(), 0, m_strLoginInfo.sPassword, 0, m_sPassword.length());
        m_strLoginInfo.wPort = m_sPort;
        //是否异步登录:0- 否,1- 是  windowsSDK里是true和false
        m_strLoginInfo.bUseAsynLogin = 0;
        m_strLoginInfo.write();
        NativeLong lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo.getPointer(), m_strDeviceInfo.getPointer());
        if (lUserID.intValue() < 0) {
            //释放SDK资源
            hCNetSDK.NET_DVR_Cleanup();
            log.error("登录失败");
        }
        return lUserID.intValue();
    }

传入登录返回的用户id,布防成功会返回一个id,此id用于撤防

    /**
     * 布防
     *
     * @param lUserID
     * @return
     */
    public Integer setupAlarmChan(Integer lUserID) {
        //设置监听回调函数
        if (!hCNetSDK.NET_DVR_SetDVRMessageCallBack_V30(new FMSGCallBack(), null)) {
            log.error("设置回调函数失败");
        }
        //启用布防
        NativeLong lAlarmHandle = hCNetSDK.NET_DVR_SetupAlarmChan_V30(new NativeLong(lUserID));
        if (lAlarmHandle.intValue() < 0) {
            hCNetSDK.NET_DVR_Logout(new NativeLong(lUserID));
            hCNetSDK.NET_DVR_Cleanup();
            log.error("布防失败");
        }
        return lAlarmHandle.intValue();
    }

传入布防成功返回的id

   /**
     * 撤防
     *
     * @param lAlarmHandle
     */
    public void closeAlarmChan(Integer lAlarmHandle) {
        if (lAlarmHandle.intValue() > -1) {
            if (!hCNetSDK.NET_DVR_CloseAlarmChan_V30(new NativeLong(lAlarmHandle))) {
                log.error("撤防失败");
            }
        }
    }

传入登录返回的用户id注销登录

    /**
     * 注销
     *
     * @param lUserID
     */
    public void logout(Integer lUserID) {
        hCNetSDK.NET_DVR_Logout(new NativeLong(lUserID));
        hCNetSDK.NET_DVR_Cleanup();
    }

布防之后会有一个回调类用于监听,可以监听多项事件,具体事件类型查看官方文档。

@Slf4j
public class FMSGCallBack implements HCNetSDK.FMSGCallBack {

    /**
     * 报警信息回调函数
     *
     * @param lCommand   上传消息类型
     * @param pAlarmer   报警设备信息
     * @param pAlarmInfo 报警信息
     * @param dwBufLen   报警信息缓存大小
     * @param pUser      用户数据
     */
    @Override
    public void invoke(NativeLong lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, HCNetSDK.RECV_ALARM pAlarmInfo, int dwBufLen, Pointer pUser) {
        //报警类型
        String sAlarmType = "lCommand=0x" + Integer.toHexString(lCommand.intValue());
        //报警时间
        String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        //序列号
        String sSerialNumber = byteToString(pAlarmer.sSerialNumber);
        //用户id
        String lUserID = new String(String.valueOf(pAlarmer.lUserID));
        //ip地址
        String sDeviceIP = byteToString(pAlarmer.sDeviceIP);

        //lCommand是传的报警类型
        switch (lCommand.intValue()) {
            //移动侦测
            case HCNetSDK.COMM_ALARM_V30:
                //报警类型
                log.info("sAlarmType:======{}", sAlarmType);
                //设备序列号
                log.info("sSerialNumber:======{}", sSerialNumber);
                //用户id
                log.info("lUserID:======{}", lUserID);
                //设备ip
                log.info("sDeviceIP:======{}", sDeviceIP);
                //当前时间
                log.info("date:======{}", date);
                break;
            default:
                log.info("其他报警信息=========={}");
                break;
        }
    }

    /**
     * 处理返回的信息 字节转字符串
     *
     * @param bytes
     * @return
     */
    private static String byteToString(byte[] bytes) {
        String[] strings = new String(bytes).split("\0", 2);
        StringBuilder sb = new StringBuilder();
        if (strings != null && strings.length > 0) {
            for (int i = 0; i < strings.length - 1; i++) {
                sb.append(strings[i]);
            }
        }
        return sb.toString();
    }
}

实现效果:(可在监听回调中,做一些自己的业务逻辑)

(新增)摄像头控制

新增摄像头控制功能,如需要相关功能请自行加入到代码中。userId是摄像头登录成功后换回的id标识!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

  /**
     * 控制上-开始
     *
     * @param userId
     */
    public void startUp(Integer userId) {
        boolean bool = hCNetSDK.NET_DVR_PTZControl_Other(new NativeLong(userId), new NativeLong(1), 21, 0);
        if (!bool) {
            throw new ServiceException("控制失败,请稍后重试");
        }

    }

    /**
     * 控制上-结束
     *
     * @param userId
     */
    public void endUp(Integer userId) {
        boolean bool = hCNetSDK.NET_DVR_PTZControl_Other(new NativeLong(userId), new NativeLong(1), 21, 1);
        if (!bool) {
            throw new ServiceException("控制失败,请稍后重试");
        }

    }

    /**
     * 控制下-开始
     *
     * @param userId
     */
    public void startDown(Integer userId) {
        boolean bool = hCNetSDK.NET_DVR_PTZControl_Other(new NativeLong(userId), new NativeLong(1), 22, 0);
        if (!bool) {
            throw new ServiceException("控制失败,请稍后重试");
        }

    }

    /**
     * 控制下-结束
     *
     * @param userId
     */
    public void endDown(Integer userId) {
        boolean bool = hCNetSDK.NET_DVR_PTZControl_Other(new NativeLong(userId), new NativeLong(1), 22, 1);
        if (!bool) {
            throw new ServiceException("控制失败,请稍后重试");
        }

    }

    /**
     * 控制左-开始
     *
     * @param userId
     */
    public void startLeft(Integer userId) {
        boolean bool = hCNetSDK.NET_DVR_PTZControl_Other(new NativeLong(userId), new NativeLong(1), 23, 0);
        if (!bool) {
            throw new ServiceException("控制失败,请稍后重试");
        }

    }

    /**
     * 控制左-结束
     *
     * @param userId
     */
    public void endLeft(Integer userId) {
        boolean bool = hCNetSDK.NET_DVR_PTZControl_Other(new NativeLong(userId), new NativeLong(1), 23, 1);
        if (!bool) {
            throw new ServiceException("控制失败,请稍后重试");
        }

    }

    /**
     * 控制右-开始
     *
     * @param userId
     */
    public void startRight(Integer userId) {
        boolean bool = hCNetSDK.NET_DVR_PTZControl_Other(new NativeLong(userId), new NativeLong(1), 24, 0);
        if (!bool) {
            throw new ServiceException("控制失败,请稍后重试");
        }

    }

    /**
     * 控制右-结束
     *
     * @param userId
     */
    public void endRight(Integer userId) {
        boolean bool = hCNetSDK.NET_DVR_PTZControl_Other(new NativeLong(userId), new NativeLong(1), 24, 1);
        if (!bool) {
            throw new ServiceException("控制失败,请稍后重试");
        }

    }

    /**
     * 控制上左-开始
     *
     * @param userId
     */
    public void startUpLeft(Integer userId) {
        boolean bool = hCNetSDK.NET_DVR_PTZControl_Other(new NativeLong(userId), new NativeLong(1), 25, 0);
        if (!bool) {
            throw new ServiceException("控制失败,请稍后重试");
        }

    }

    /**
     * 控制上左-结束
     *
     * @param userId
     */
    public void endUpLeft(Integer userId) {
        boolean bool = hCNetSDK.NET_DVR_PTZControl_Other(new NativeLong(userId), new NativeLong(1), 25, 1);
        if (!bool) {
            throw new ServiceException("控制失败,请稍后重试");
        }

    }

    /**
     * 控制上右-开始
     *
     * @param userId
     */
    public void startUpRight(Integer userId) {
        boolean bool = hCNetSDK.NET_DVR_PTZControl_Other(new NativeLong(userId), new NativeLong(1), 26, 0);
        if (!bool) {
            throw new ServiceException("控制失败,请稍后重试");
        }

    }

    /**
     * 控制上右-结束
     *
     * @param userId
     */
    public void endUpRight(Integer userId) {
        boolean bool = hCNetSDK.NET_DVR_PTZControl_Other(new NativeLong(userId), new NativeLong(1), 26, 1);
        if (!bool) {
            throw new ServiceException("控制失败,请稍后重试");
        }

    }

    /**
     * 控制下左-开始
     *
     * @param userId
     */
    public void startDownLeft(Integer userId) {
        boolean bool = hCNetSDK.NET_DVR_PTZControl_Other(new NativeLong(userId), new NativeLong(1), 27, 0);
        if (!bool) {
            throw new ServiceException("控制失败,请稍后重试");
        }

    }

    /**
     * 控制下左-结束
     *
     * @param userId
     */
    public void endDownLeft(Integer userId) {
        boolean bool = hCNetSDK.NET_DVR_PTZControl_Other(new NativeLong(userId), new NativeLong(1), 27, 1);
        if (!bool) {
            throw new ServiceException("控制失败,请稍后重试");
        }

    }

    /**
     * 控制下右-开始
     *
     * @param userId
     */
    public void startDownRight(Integer userId) {
        boolean bool = hCNetSDK.NET_DVR_PTZControl_Other(new NativeLong(userId), new NativeLong(1), 28, 0);
        if (!bool) {
            throw new ServiceException("控制失败,请稍后重试");
        }

    }

    /**
     * 控制下右-结束
     *
     * @param userId
     */
    public void endDownRight(Integer userId) {
        boolean bool = hCNetSDK.NET_DVR_PTZControl_Other(new NativeLong(userId), new NativeLong(1), 28, 1);
        if (!bool) {
            throw new ServiceException("控制失败,请稍后重试");
        }

    }

    /**
     * 焦距变大-开始
     *
     * @param userId
     */
    public void startZoomIn(Integer userId) {
        boolean bool = hCNetSDK.NET_DVR_PTZControl_Other(new NativeLong(userId), new NativeLong(1), 11, 0);
        if (!bool) {
            throw new ServiceException("控制失败,请稍后重试");
        }

    }

    /**
     * 焦距变大-结束
     *
     * @param userId
     */
    public void endZoomIn(Integer userId) {
        boolean bool = hCNetSDK.NET_DVR_PTZControl_Other(new NativeLong(userId), new NativeLong(1), 11, 1);
        if (!bool) {
            throw new ServiceException("控制失败,请稍后重试");
        }

    }

    /**
     * 焦距变小-开始
     *
     * @param userId
     */
    public void startZoomOut(Integer userId) {
        boolean bool = hCNetSDK.NET_DVR_PTZControl_Other(new NativeLong(userId), new NativeLong(1), 12, 0);
        if (!bool) {
            throw new ServiceException("控制失败,请稍后重试");
        }

    }

    /**
     * 焦距变小-结束
     *
     * @param userId
     */
    public void endZoomOut(Integer userId) {
        boolean bool = hCNetSDK.NET_DVR_PTZControl_Other(new NativeLong(userId), new NativeLong(1), 12, 1);
        if (!bool) {
            throw new ServiceException("控制失败,请稍后重试");
        }

    }

    /**
     * 焦点前调-开始
     *
     * @param userId
     */
    public void startFocusNear(Integer userId) {
        boolean bool = hCNetSDK.NET_DVR_PTZControl_Other(new NativeLong(userId), new NativeLong(1), 13, 0);
        if (!bool) {
            throw new ServiceException("控制失败,请稍后重试");
        }

    }

    /**
     * 焦点前调-结束
     *
     * @param userId
     */
    public void endFocusNear(Integer userId) {
        boolean bool = hCNetSDK.NET_DVR_PTZControl_Other(new NativeLong(userId), new NativeLong(1), 13, 1);
        if (!bool) {
            throw new ServiceException("控制失败,请稍后重试");
        }

    }

    /**
     * 焦点后调-开始
     *
     * @param userId
     */
    public void startFocusFar(Integer userId) {
        boolean bool = hCNetSDK.NET_DVR_PTZControl_Other(new NativeLong(userId), new NativeLong(1), 14, 0);
        if (!bool) {
            throw new ServiceException("控制失败,请稍后重试");
        }

    }

    /**
     * 焦点后调-结束
     *
     * @param userId
     */
    public void endFocusFar(Integer userId) {
        boolean bool = hCNetSDK.NET_DVR_PTZControl_Other(new NativeLong(userId), new NativeLong(1), 14, 1);
        if (!bool) {
            throw new ServiceException("控制失败,请稍后重试");
        }

    }

    /**
     * 是否在线
     *
     * @param userId
     */
    public Boolean isOnLine(Integer userId) {
        boolean isOnLine = hCNetSDK.NET_DVR_RemoteControl(new NativeLong(userId), 20005, null, 0);
        return isOnLine;
    }

    /**
     * 截图
     *
     * @param userId
     */
    public void captureJPEGPicture(Integer userId, HttpServletResponse response) {
        HCNetSDK.NET_DVR_WORKSTATE_V30 devwork = new HCNetSDK.NET_DVR_WORKSTATE_V30();
        if (!hCNetSDK.NET_DVR_GetDVRWorkState_V30(new NativeLong(userId), devwork)) {
            // 返回Boolean值,判断是否获取设备能力
            throw new ServiceException("抓图失败,请稍后重试");
        }

        //图片质量
        HCNetSDK.NET_DVR_JPEGPARA jpeg = new HCNetSDK.NET_DVR_JPEGPARA();
        //设置图片分辨率
        jpeg.wPicSize = 0;
        //设置图片质量
        jpeg.wPicQuality = 0;
        IntByReference a = new IntByReference();
        //设置图片大小
        ByteBuffer jpegBuffer = ByteBuffer.allocate(1024 * 1024);
        // 抓图到内存,单帧数据捕获并保存成JPEG存放在指定的内存空间中
        boolean is = hCNetSDK.NET_DVR_CaptureJPEGPicture_NEW(new NativeLong(userId), new NativeLong(1), jpeg, jpegBuffer, 1024 * 1024, a);
        log.info("-----------这里开始图片存入内存----------" + is);

        ByteArrayInputStream in = new ByteArrayInputStream(jpegBuffer.array(), 0, a.getValue());
        OutputStream outputStream = null;
        try {
            //1、设置response 响应头 //设置页面不缓存,清空buffer
            response.reset();
            //字符编码
            response.setCharacterEncoding("UTF-8");
            //二进制传输数据
            response.setContentType("multipart/form-data");
            //设置响应头
            response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())+".jpeg", "UTF-8"));

            outputStream = response.getOutputStream();
            LoginUser loginUser = LoginContext.me().getLoginUser();
            WaterMarkUtil.markImageByIO(loginUser.getAccount(),in,outputStream,null,"jpeg");
            outputStream.flush();
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("抓图失败,请稍后重试");
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                throw new ServiceException("抓图失败,请稍后重试");
            }
        }
        log.info("-----------处理完成截图数据----------");

    }

    private void picCutCate(NativeLong lUserID, NativeLong chanLong, String imgPath) {
        //图片质量
        HCNetSDK.NET_DVR_JPEGPARA jpeg = new HCNetSDK.NET_DVR_JPEGPARA();
        //设置图片分辨率
        jpeg.wPicSize = 0;
        //设置图片质量
        jpeg.wPicQuality = 0;
        IntByReference a = new IntByReference();
        //设置图片大小
        ByteBuffer jpegBuffer = ByteBuffer.allocate(1024 * 1024);
        File file = new File(imgPath);
        // 抓图到内存,单帧数据捕获并保存成JPEG存放在指定的内存空间中
        log.info("-----------这里开始封装 NET_DVR_CaptureJPEGPicture_NEW---------");
        boolean is = hCNetSDK.NET_DVR_CaptureJPEGPicture_NEW(lUserID, chanLong, jpeg, jpegBuffer, 1024 * 1024, a);
        log.info("-----------这里开始图片存入内存----------" + is);
        if (is) {
            /**
             * 该方式使用内存获取 但是读取有问题无法预览
             * linux下 可能有问题
             * */
            log.info("hksdk(抓图)-结果状态值(0表示成功):" + hCNetSDK.NET_DVR_GetLastError());
            byte[] array = jpegBuffer.array();

            //存储到本地
            BufferedOutputStream outputStream = null;
            try {
                outputStream = new BufferedOutputStream(new FileOutputStream(file));
                outputStream.write(jpegBuffer.array(), 0, a.getValue());
                outputStream.flush();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (outputStream != null) {
                    try {
                        outputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        } else {
            log.info("hksdk(抓图)-抓取失败,错误码:" + hCNetSDK.NET_DVR_GetLastError());
        }
    }

 3.获取摄像头的rtsp视频流转成rtmp直播流网页显示

组装海康rtsp地址:

本文主要用onvif插件获取rtsp视频流,把onvif安装到本地meven库,引入到pom文件。(上方有jar包安装教程)

传送门:onvif包下载

由于权限问题,需要在视频流中拼接上账号密码,此方法获取的视频流为主码流,如需要子码流请查看上方视频流介绍修改视频流。获取rtsp视频流的代码如下:

    /**
     * 获取实时视频流
     *
     * @param m_sDeviceIP 设备ip
     * @param m_sUsername 设备用户名
     * @param m_sPassword 设备密码
     * @return
     */
    public String getStreamUri(String m_sDeviceIP, String m_sUsername, String m_sPassword) {
        OnvifDevice nvt = null;
        try {
            nvt = new OnvifDevice(m_sDeviceIP, m_sUsername, m_sPassword);
        } catch (ConnectException e) {
            log.error("获取实时视频流失败");
        } catch (SOAPException e) {
            log.error("获取实时视频流失败");
        } catch (MalformedURLException e) {
            log.error("获取实时视频流失败");
        }
        String streamUri = nvt.getStreamUri().replace("rtsp://", "");
        streamUri = "rtsp://" + m_sUsername + ":" + m_sPassword + "@" + streamUri;
        return streamUri;
    }

# 返回的rtsp视频流如下
# rtsp://admin:123456@172.19.33.88:554/Streaming/Channels/101?transportmode=unicast&profile=Profile_1

把rtsp转成rtmp视频流

本文使用ffmpeg把rtsp视频流转成rtmp视频流,并推流到流媒体服务器。

安装ffmpeg、把ffch4j.jar安装到本地meven库,引入到pom文件。

传送门:windows版ffmpeg

需要把ffmpeg的路径配置到环境变量path中。

Linux版请看下方流媒体服务器安装。

传送门:ffch4j.jar下载

   /**
     * 开始推流
     * @param appName 进程名称
     * @param m_sDeviceIP 设备ip
     * @param m_sUsername 设备用户名
     * @param m_sPassword 设备密码
     * @return
     */
    public String startTranscoding(String appName,String m_sDeviceIP,String m_sUsername,String m_sPassword)  {
        if(manager == null){
            manager = new CommandManagerImpl(10);
        }
        if(taskerIsRun(appName)){
            //如果进程存在,则直接返回进程名
            return appName;
        }
        String streamUri = hikVisionService.getStreamUri(m_sDeviceIP,m_sUsername,m_sPassword);

        Map<String,String> map = new HashMap<>();
        //进程名
        map.put("appName", appName);
        //组装rtsp流
        map.put("input", streamUri);
        //rtmp流.live为nginx-rtmp的配置
        map.put("output", "rtmp://localhost:1935/live/");
        map.put("codec", "h264");
        map.put("fmt", "flv");
        map.put("fps", "25");
        map.put("rs", "1280x720");
        map.put("twoPart", "1");
        // 执行任务,id就是appName,如果执行失败返回为null
        return manager.start(map);
    }
    /**
     * 关闭进程
     * @param appName
     * @return
     */
    public boolean stopTranscoding(String appName){
        if(!taskerIsRun(appName)) {
            return true;
        }
        return manager.stop(appName);
    }

在loadFFmpeg.properties配置文件中配置ffmpeg路径

#ffmpeg执行路径,一般为ffmpeg的安装目录,该路径只能是目录,不能为具体文件路径,否则会报错
path=C:/Users/Administrator/Desktop/ffmpeg-20200315-c467328-win64-static/bin/
#存放任务的默认Map的初始化大小
size=10
#事件回调通知接口地址
callback=http://127.0.0.1/callback
#网络超时设置(毫秒)
timeout=300

#开启保活线程
keepalive=true

#是否输出debug消息
debug=true

推流成功后可以通过播放 rtmp://流媒体服务器ip:1935/live/进程名,进行测试。

4.搭建流媒体服务器

由于篇幅过长,请移步一下文章查看详细搭建流程。

传送门:nginx流媒体服务器搭建

5.结束

本文内容纯手打!转载请注明出处,谢谢!

本文所有代码、jar包、运行demo可以最上方链接下载。

  • 26
    点赞
  • 125
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 36
    评论
### 回答1: Java是一种广泛应用的编程语言,而海康威视是一家知名的视听设备生产厂商,其提供的SDK包含了海康威视所生产的视频监控设备通信协议以及数据处理方案。基于海康威视SDK进行Java二次开发可以使开发者在海康威视设备的基础上构建出更加灵活、高效的应用程序,提高了开发效率和安全性。 使用Java的特性来实现对海康威视设备的二次开发,主要包括以下几个方面: 1. 处理设备的通信协议:使用Java的网络编程技术,基于海康威视SDK中所提供的设备通信协议进行二次开发,可以实现设备之间的数据交互。 2. 实现设备数据的解析:使用Java的数据处理技术,对从设备中获取的数据进行解析和处理,将数据转换成开发者想要的格式,以便进行进一步的数据处理。 3. 开发可视化界面:通过Java的图形用户界面(GUI)开发技术,基于海康威视SDK提供的数据处理方案,开发出用户友好的界面,实现对设备的远程控制和监控。 通过基于海康威视SDK进行Java二次开发开发者可以轻松地实现对海康威视设备的控制和监控,从而扩展了设备的功能和优化了用户体验。 ### 回答2: Java语言是当前应用非常广泛的编程语言之一,而海康威视则是国内领先的视频监控设备和解决方案的供应商之一,其SDK(软件开发工具包)提供了视频监控设备接口、流媒体接口等丰富的接口,使得设备厂商和软件开发者可以基于这些接口进行二次开发,实现更加专业化和个性化的应用。 如何通过Java语言来实现基于海康威视SDK二次开发呢?首先我们需要在Java开发环境中添加海康威视SDK的jar包,然后根据SDK提供的接口进行编程。一般来说,SDK的使用大致可以分为以下几个步骤: 1. 初始化SDK环境:调用SDK提供的初始化接口完成SDK环境的初始化工作,包括设备搜索、连接、登录等工作。此外,还可以设置获取日志信息、设置报警回调等操作。 2. 获取设备信息:通过SDK提供的接口,可以获取监控设备的相关信息,包括设备类型、通道数、分辨率、帧率等,这些信息可以用于后续的开发工作。 3. 获取实时视频流:通过SDK提供的接口,可以获取监控设备传输的视频流数据,包括码流类型、码率、分辨率等,将视频数据解码后可以进行实时展示或者录制等操作。 4. 控制设备操作:通过SDK提供的接口,可以对监控设备进行各种控制操作,包括云台控制、预置点设置、图像参数调节等。 以上是基于海康威视SDK进行Java开发的一些常用操作,具体实现方式还需要根据不同的业务需求进行具体的编码工作。在实际开发过程中,我们还需要根据SDK提供的文档和示例代码进行参考和学习,以便更好地掌握SDK的使用技巧和开发经验。同时,我们还需要考虑安全、稳定性等因素,在保证功能实现的前提下,尽可能地减少软件系统的风险和漏洞。 ### 回答3: Java 是一种广泛使用的编程语言,在现代软件开发中非常流行。而海康威视是一家全球领先的视频监控解决方案提供商,其SDK具有一定的开放性和可定制性,可以用于二次开发。因此,Java 基于海康威视SDK实现二次开发是可行的。 首先,使用Java开发需要具备基本的Java编程知识、IDE开发环境和海康威视SDK技术文档。开发者可以通过访问海康威视开发者网站,获取SDK开发包和相关说明文档,从而开始二次开发。 其次,海康威视SDK提供了丰富的接口和工具,便于Java开发者调用和使用。通过SDK中提供的API,我们可以实现视频监控的实时预览、录像回放、设备管理等功能。同时,SDK还提供了多种编程语言和操作系统的支持,使得Java程序可以在不同平台上进行开发和运行。 最后,Java开发者可以结合SDK提供的示例代码和测试工具,对开发的程序进行测试和调试,确保其功能和性能能够满足要求。同时,Java开发者还应该遵循海康威视SDK开发规范,尽可能地避免出现错误和异常。 总之,Java基于海康威视SDK实现二次开发是一项有挑战性的任务,需要具备Java编程技能和视频监控领域的相关经验。但是,通过充分利用SDK的开放性和可定制性,开发者可以实现更加灵活和高效的视频监控解决方案,为客户提供更好的用户体验。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cicigodd

你的鼓励将是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值