应用场景:
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),采集的是本地音频数据
![](https://img-blog.csdnimg.cn/img_convert/4fa5244c853452a926fd9593921f2161.png)
![](https://img-blog.csdnimg.cn/img_convert/53aba543d9c7daa254203f0f0b6c83e6.png)
![](https://img-blog.csdnimg.cn/img_convert/b83835da4d1b3c913d4104f4cdc5088e.png)
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
测试报告
![](https://img-blog.csdnimg.cn/img_convert/85003743258168e38f47dcf74a951c06.png)
音频播放
![](https://img-blog.csdnimg.cn/img_convert/e9fa8e8d752babb8ab5f61514d041039.png)
开始对讲
![](https://img-blog.csdnimg.cn/img_convert/c91b1b52aa7dbff5138b4e5f8b72337a.png)
![](https://img-blog.csdnimg.cn/img_convert/a38e8bb32a5daca9c2a43293fce7c4ba.png)
结束对讲
![](https://img-blog.csdnimg.cn/img_convert/f8ca0af739eb432957b6bca018c4c1c5.png)
![](https://img-blog.csdnimg.cn/img_convert/1419bd74c2d2aae57bea082962541e55.png)
方案内容
![](https://img-blog.csdnimg.cn/img_convert/9a3befdb564f13e45f3a3971fa2072ae.png)
![](https://img-blog.csdnimg.cn/img_convert/02e6169dbe9df7e273bf0e851182866c.png)
![](https://img-blog.csdnimg.cn/img_convert/c854a6b96697fd6454fcc0b21a0c15aa.png)
相关配置
1. 海康相机音频配置
![](https://img-blog.csdnimg.cn/img_convert/5710bc7e556d65a2932aadd2ef7235bd.png)
![](https://img-blog.csdnimg.cn/img_convert/0360af1d71035f7cd900bb7838d4a6e5.png)
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文件
核心代码
![复制代码](https://img-blog.csdnimg.cn/img_convert/23236e9ee5504732b8b3e3d870ccdc5f.gif)
// 开始音频文件
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("读取完成");
}
![复制代码](https://img-blog.csdnimg.cn/img_convert/f1e4c3558d3c839d7adaf590c6672e0b.gif)
qq:505645074
|