由于最近在开发海康威视摄像头,特此记录一下如何提取音频数据,这里主要依靠语音对讲返回的音频数据,通过回调函数写入文件中,加个WAV头即可播放,编码格式可以自己设置在代码中有注释
文件结构
其中CameraInfo内容可以参看海康威视摄像机SDK二次开发–实时预览视频流保存到指定文件中
- HIKSDKSaveRealData中的内容
package ClientDemo;
import ClientDemo.CameraInfo;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.ByteByReference;
import com.sun.jna.ptr.IntByReference;
import javax.swing.*;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.SimpleTimeZone;
public class HIKSDKSaveRealData {
private static Map configParam;
public static void main(String[] args) throws Exception {
HIKSDKSaveRealData HikSdk = new HIKSDKSaveRealData();
/* 此处创建对象也可以创建file对象 */
// 创建流对象
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("F:\\debug\\hksdk\\javademo\\src\\ClientDemo\\config.txt"));
configParam = new HashMap();
CameraInfo cameraInfo = new CameraInfo();
String line = null;
int count = 0;
while ((line = br.readLine()) != null) {
if (line != "" && line.length() > 0 && count > 0) {
String[] split = line.split("\\s+");
configParam.put(count + "param", split);
count++;
} else if (line != "" && line.length() > 0 && count == 0) {
String[] split = line.split("\\s+");
// 设置IP等参数到对象中
System.out.println(split[0]);
System.out.println(split[1]);
cameraInfo.setAddress(split[0]);
cameraInfo.setPort(Short.parseShort(split[1]));
cameraInfo.setUserName(split[2]);
cameraInfo.setPwd(split[3]);
count++;
}
}
br.close();
//查看当前DVR参数信息和初始化注册等 传入连接信息
// HikSdk.getDVRConfig(cameraInfo);
HikSdk.VoiceForward(cameraInfo);
} catch (IOException e) {
e.printStackTrace();
}
}
/*****************************************************************
* 语音方法
* parameters: cameraInfo
* return: null
* ****************************************************************/
FileWriter fLocal; //本地音频文件
FileWriter fDevice; //设备发送的音频文件
NativeLong nativeLong;
HCNetSDK sdk = HCNetSDK.INSTANCE;
void VoiceForward(CameraInfo cameraInfo) {
CameraInfo parameter = getParameter(cameraInfo);
//判断是否注册成功
if (parameter.getUserId().intValue() < 0) {
System.out.println("注册设备失败 错误码为: " + sdk.NET_DVR_GetLastError());
} else {
System.out.println("注册成功 Id为: " + cameraInfo.getUserId().intValue());
}
//判断是否获取到设备能力
HCNetSDK.NET_DVR_WORKSTATE_V30 devWork = new HCNetSDK.NET_DVR_WORKSTATE_V30();
if (!sdk.NET_DVR_GetDVRWorkState_V30(cameraInfo.getUserId(), devWork)) {
System.out.println("获取设备能力集失败,返回设备状态失败...............");
return;
}
try {
/*
* 设置语音对象的编码类型
* 编码类型: G711
* 音频数据采样率: 16000
* 格式: 16位采样并且单通道
* */
HCNetSDK.NET_DVR_COMPRESSION_AUDIO audio = new HCNetSDK.NET_DVR_COMPRESSION_AUDIO();
audio.byAudioEncType = 1;
fLocal = new FileWriter("F:\\debug\\hksdk\\javademo\\data\\local.pcm");
fDevice = new FileWriter("F:\\debug\\hksdk\\javademo\\data\\device.pcm");
FVoiceDataCallBack fVoiceDataCallBack = new FVoiceDataCallBack();
JComboBox jComboBoxDataType = new javax.swing.JComboBox();
nativeLong = sdk.NET_DVR_StartVoiceCom_V30(cameraInfo.getUserId(), 0, jComboBoxDataType.getSelectedIndex() == 2, fVoiceDataCallBack, null);
if (nativeLong.intValue() == -1) {
System.out.println(111);
}
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
sdk.NET_DVR_StopVoiceCom(nativeLong);
sdk.NET_DVR_Logout(nativeLong);
sdk.NET_DVR_Cleanup();
} catch (IOException e) {
e.printStackTrace();
}
}
/*
*语音对讲回调函数
*/
class FVoiceDataCallBack implements HCNetSDK.FVoiceDataCallBack_V30 {
//对对讲的音频数据进行回调操作,以下写入文件操作
public void invoke(NativeLong lVoiceComHandle, String pRecvDataBuffer, int dwBufSize, byte byAudioFlag, Pointer pUser) {
//byAudioFlag为0表示本地文件,为1表示设备的音频文件
if (byAudioFlag == 0) {
try {
fLocal.write(pRecvDataBuffer);
fLocal.flush();
} catch (IOException ex) {
// Logger.getLogger(JDialogVoiceTalk.class.getName()).log(Level.SEVERE, null, ex);
System.out.println('1');
}
} else {
if (byAudioFlag == 1) {
try {
fDevice.write(pRecvDataBuffer);
fDevice.flush();
} catch (IOException ex) {
// Logger.getLogger(JDialogVoiceTalk.class.getName()).log(Level.SEVERE, null, ex);
System.out.println('2');
}
}
}
}
}
/*****************************************************************
* 注册设备并返回参数
* 目的: 注册设备并返回key :Nativelong
* parameters: cameraInfo
*return: cameraInfo
* ****************************************************************/
private CameraInfo getParameter(CameraInfo cameraInfo) {
//设置设备通道号 查看Demo代码 通道号为1
NativeLong channel = new NativeLong(1);
cameraInfo.setChannel(channel);
if (!sdk.NET_DVR_Init()) {
System.out.println("初始化失败..................");
}
//创建设备
HCNetSDK.NET_DVR_DEVICEINFO_V30 deInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30();
//注册用户设备
NativeLong id = sdk.NET_DVR_Login_V30(cameraInfo.getAddress(), cameraInfo.getPort(),
cameraInfo.getUserName(), cameraInfo.getPwd(), deInfo);
cameraInfo.setUserId(id);
return cameraInfo;
}
}