海康摄像头音频方案(播放音频文件+语音对讲+语音转发)-支持window/Linux-java版本

应用场景:

1. 有告警出现时,海康摄像头能自动播报(如:禁止游泳,请快速里离开);

2. 在web页面点击“开始对讲”,能讲PC上的麦克风声音传输到海康摄像头进行对讲;点击“停止对讲”,海康摄像头停止对讲;

技术实现:
使用海康的SDK实现,nettyserver框架,提供webapi接口及websocket接口,兼容window、linux

警告:经测试linux稳定,window容易出现J 1031 C1 com.sun.proxy.$Proxy0.NET_DVR_EncodeG711Frame(Lcom/sun/jna/Pointer;Lcommon/HCNetSDK$NET_DVR_AUDIOENC_PROCESS_PARAM;)Z (43 bytes) @ 0x00000000035202fc [0x000000000351ff00+0x3fc]

软件功能:

1. 集成海康SDK

2. WebAPI接口(PlayMedia,StartTalk,StopTalk),采集的是本地音频数据

 

 

3. WebSocket接口,讲web用户的音频数据转发到Server程序,通过SDK发送至海康摄像机

对讲初始化

H5->Server 发送指令 StartTalk::{ "ip": "192.168.3.2", "port": 8000, "name": "admin", "password": "yswy123456" }

Server->H5 返回指令 StartTalk::ACK_OK

Server->H5 返回指令 StartTalk::ACK_ERROE

开始对讲

H5->Server 发送指令 Base64音频字符串

结束对讲

H5->Server 发送指令 StopTalk::

Server->H5 返回指令 StopTalk::ACK_OK

Server->H5 返回指令 StartTalk::ACK_ERROR

4.  链路检查超时退出SDK

测试报告 

音频播放

开始对讲

 

结束对讲

 

方案内容

 

 

相关配置

1. 海康相机音频配置

 

 2. 将dll/so文件拷贝至系统目录下

window:C:/Windows/System32
linux: /usr/lib

3. pcm制作

1. 安装ekho-5.8.exe

2. 安装girl_xiaokun.exe

3. 运行ttsapp.exe

4.使用UltraEdit编辑,然后选中文件头的44个字节并剪切(因为退格键不管用),将这44个字节删掉,另存为pcm文件

核心代码

复制代码

 // 开始音频文件
    static void StartMedia(Camera entity, String sfilePath)
    { 
        lockAudio.lock();
        
        HCNetSDK.NET_DVR_COMPRESSION_AUDIO lpCompressAudio = new HCNetSDK.NET_DVR_COMPRESSION_AUDIO();
        boolean net_DVR_GetCurrentAudioCompress = hCNetSDK.NET_DVR_GetCurrentAudioCompress(entity.UserID, lpCompressAudio); if (!net_DVR_GetCurrentAudioCompress) return;
        byte byAudioEncType = lpCompressAudio.byAudioEncType;
        byte byAudioSamplingRate = lpCompressAudio.byAudioSamplingRate;
        byte byAudioBitRate = lpCompressAudio.byAudioBitRate;
        byte bySupport = lpCompressAudio.bySupport;
        System.out.println("音频编码类型=" + byAudioEncType + "  音频采样率=" + byAudioSamplingRate + "    音频码率=" + byAudioBitRate + "   bySupport=" + bySupport);

        NativeLong mr = hCNetSDK.NET_DVR_StartVoiceCom_MR_V30(entity.UserID, 1, null, null); 
        File file = new File(sfilePath); 

        FileInputStream inputStream = null;
        
        try
        {
            inputStream = new FileInputStream(file);
            
            Memory pInBuff = new Memory(file.length());
            pInBuff.clear();
            
            if (pInBuff != Memory.NULL) 
            {
                int buffLen = 320; long currFileLen = 0; int readLen;
                byte[] buffer = new byte[buffLen];
                
                Memory pIB = new Memory(buffLen);
                while (currFileLen < file.length()) 
                {
                    entity.LastTime = System.currentTimeMillis();
                    
                    readLen = inputStream.read(buffer);
                    pIB.write(0, buffer, 0, readLen);
                    currFileLen += readLen;
                    Memory pOutBuffer = new Memory(buffLen);
                    HCNetSDK.NET_DVR_AUDIOENC_INFO enc_info = new HCNetSDK.NET_DVR_AUDIOENC_INFO();
                    enc_info.in_frame_size = buffLen;
                    Pointer encoder = hCNetSDK.NET_DVR_InitG711Encoder(enc_info);
                    //
                    HCNetSDK.NET_DVR_AUDIOENC_PROCESS_PARAM param = new HCNetSDK.NET_DVR_AUDIOENC_PROCESS_PARAM();
                    param.in_buf = pIB;
                    param.out_buf = pOutBuffer;
                    param.out_frame_size = 160;
                    param.g711_type = 0;
                    boolean frame = hCNetSDK.NET_DVR_EncodeG711Frame(encoder, param);
                    if (!frame) 
                    {
                        int iErr = hCNetSDK.NET_DVR_GetLastError();
                        System.out.println("G711音频编码失败!iErr = " + iErr);
                        break;
                    } 
                    frame = hCNetSDK.NET_DVR_ReleaseG711Encoder(encoder); 
                    if (!frame) 
                    {
                        int iErr = hCNetSDK.NET_DVR_GetLastError();
                        System.out.println("G711音频编码失败!iErr = " + iErr);
                        break;
                    }
                    boolean sendData = hCNetSDK.NET_DVR_VoiceComSendData(mr, pOutBuffer, 160);
                    if (!sendData) 
                    {
                        int iErr = hCNetSDK.NET_DVR_GetLastError();
                        System.out.println("转发语音数据!iErr = " + iErr);
                        break;
                    }

                    Thread.sleep(20);
                }
            } 
        } 
        catch (Exception ex)
        {
            DataHelper.AddExceptionStackTrace("[Error] StartMedia", ex); 
        }
        finally
        {
            if (null != inputStream) { try { inputStream.close(); } catch(Exception e) {} }
            
            lockAudio.unlock();
        } 
        
        hCNetSDK.NET_DVR_StopVoiceCom(mr);
        System.out.println("读取完成"); 
    }  

复制代码

qq:505645074

  • 2
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
首先,你需要确保已经导入了onvifcamera-jvm的类库,并且已经建立了与摄像头的连接。然后,可以通过以下步骤来实现控制海康摄像头转动: 1. 创建PTZ控制对象 ```java OnvifDevice device = new OnvifDevice("http://192.168.1.100/onvif/device_service"); OnvifProfile profile = device.getMedia().getProfiles()[0]; OnvifPtz ptz = device.getPtz(profile.getToken()); ``` 其中,"http://192.168.1.100/onvif/device_service"是海康摄像头的设备服务地址,可以根据实际情况进行修改。 2. 获取PTZ节点信息 ```java OnvifPtzNode[] nodes = ptz.getNodes(); OnvifPtzNode panNode = null; OnvifPtzNode tiltNode = null; for (OnvifPtzNode node : nodes) { if (node.getName().toLowerCase().contains("pan")) { panNode = node; } if (node.getName().toLowerCase().contains("tilt")) { tiltNode = node; } } ``` 通过调用getNodes()方法可以获取到PTZ节点信息,包括名称、范围等。在海康摄像头中,通常会有一个"pan"节点和一个"tilt"节点,分别控制摄像头水平和垂直方向的转动。 3. 控制PTZ转动 ```java // 控制摄像头向左转动 ptz.continuousMove(panNode.getToken(), -0.1f, 0.0f, null); // 控制摄像头向右转动 ptz.continuousMove(panNode.getToken(), 0.1f, 0.0f, null); // 控制摄像头向上转动 ptz.continuousMove(tiltNode.getToken(), 0.0f, -0.1f, null); // 控制摄像头向下转动 ptz.continuousMove(tiltNode.getToken(), 0.0f, 0.1f, null); ``` 通过调用continuousMove()方法可以控制摄像头的转动。其中,第一个参数为节点的Token,第二个参数为水平方向的速度,第三个参数为垂直方向的速度,第四个参数为可选参数,用于设置持续时间等。在这个例子中,我们通过控制速度的正负来控制转动方向。 注意:以上代码仅为示例,实际使用中需要根据具体情况进行修改。另外,需要注意的是,海康摄像头的PTZ控制可能存在一些特殊的问题,需要根据实际情况进行调整。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值