海康威视sdk语⾳转发(实现)implementation‘com.hikvision.e。。。
海康威视sdk语⾳转发实现。
⼀、使⽤版本
implementation 'viz:ezviz-sdk:4.8.3'
⼆、语⾳格式转化代码
public class G711Code {
private final static int SIGN_BIT = 0x80;
private final static int QUANT_MASK = 0xf;
private final static int SEG_SHIFT = 4;
private final static int SEG_MASK = 0x70;
static short[] seg_end = {0xFF, 0x1FF, 0x3FF, 0x7FF,0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
static short search(short val,short[] table,short size){
for (short i = 0 ; i < size; i++) {
if(val <= table[i]){
return i;
}
}
return size;
}
static byte linear2alaw(short pcm_val){
short mask;
short seg;
char aval;
if(pcm_val >= 0){
mask = 0xD5;  //* sign (7th) bit = 1 ⼆进制的11010101
}else{
mask = 0x55; //* sign bit = 0  ⼆进制的01010101
pcm_val = (short) (-pcm_val - 1);//负数转换为正数计算
if(pcm_val < 0){
pcm_val = 32767;
}
}
/* Convert the scaled magnitude to segment number. */
seg = search(pcm_val, seg_end, (short) 8); //查采样值对应哪⼀段折线
/* Combine the sign, segment, and quantization bits. */
if (seg >= 8)      /* out of range, return maximum value. */
return (byte) (0x7F ^ mask);
else {
//以下按照表格第⼀⼆列进⾏处理,低4位是数据,5~7位是指数,最⾼位是符号
aval = (char) (seg << SEG_SHIFT);
if (seg < 2)
aval |= (pcm_val >> 4) & QUANT_MASK;
else
aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;
return (byte) (aval ^ mask);
}
}
static short alaw2linear(byte a_val){
short      t;
short      seg;
a_val ^= 0x55;
t = (short) ((a_val & QUANT_MASK) << 4);
seg = (short) ((a_val & SEG_MASK) >> SEG_SHIFT);
switch (seg) {
case 0:
t += 8;
break;
case 1:
t += 0x108;
break;
default:
t += 0x108;
t <<= seg - 1;
}
return (a_val & SIGN_BIT) != 0 ? t : (short) -t;
}
/
**
* pcm 转 G711 a率
* @param pcm
* @param code
* @param size
*/
public static void G711aEncoder(short[] pcm,byte[] code,int size){
for(int i=0;i<size;i++){
code[i]=linear2alaw(pcm[i]);
}
}
/
**
* G.711 转 PCM
* @param pcm
* @param code
* @param size
*/
public static void G711aDecoder(short[] pcm,byte[] code,int size)
{
for(int i=0;i<size;i++){
pcm[i]=alaw2linear(code[i]);
}
}
}
三、语⾳获取
static final int freq = 8000;
//static final int freq = 14400;
// static final int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
static final int channelConfiguration = AudioFormat.CHANNEL_IN_MONO;
// static final int channelout = AudioFormat.CHANNEL_OUT_MONO;
static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
int recBuffSize = MinBufferSize(freq, channelConfiguration, audioEncoding);
sdk//  int playBufSize = MinBufferSize(freq, channelout, audioEncoding);
AudioRecord audioRecord =new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION,  freq,AudioFormat.CHANNEL_IN_MONO, AudioF ormat.ENCODING_PCM_16BIT, recBuffSize);
/*  AudioTrack audioTrack =new AudioTrack(AudioManager.STREAM_MUSIC, freq, channelConfiguration, audioEncoding, playBufSize, AudioTrack.MOD E_STREAM);*/
四、实现代码
private volatile boolean isVudio=false;
private int hk;
//开始语⾳转发
public void  voide(){
hk= Instance().NET_DVR_StartVoiceCom_MR_V30(m_iLogID, channel,getVoiceDataCallBack());
int pp= Instance().NET_DVR_GetLastError(); //获取执⾏返回的错误信息
isVudio=true;
NET_DVR_COMPRESSION_AUDIO lpCompressAudio=new NET_DVR_COMPRESSION_AUDIO();
boolean net_DVR_GetCurrentAudioCompress= Instance().NET_DVR_GetCurrentAudioCompress(m_iLogID, lpCompressAudio);
byte byAudioEncType = lpCompressAudio.byAudioEncType;// ⾳频编码类型 0- G722,1- G711_U,2- G711_A,5- MP2L2,6- G726,7- AAC,8-PCM ,9-G722,10-G723,11-G729
byte byAudioSamplingRate = lpCompressAudio.byAudioSamplingRate;// ⾳频采样率:0- 默认,1- 16kHZ,2- 32kHZ,3- 48kHZ,4- 44.1kHZ,5- 8kHZ    byte byAudioBitRate = lpCompressAudio.byAudioBitRate;// ⾳频码率
byte bySupport = lpCompressAudio.bySupport;// Mp2l2前4个字节的含义表⽰后⾯内容⾳频数据长度
System.out.println("⾳频编码类型=" + byAudioEncType + "  ⾳频采样率=" + byAudioSamplingRate + "    ⾳频码率=" + byAudioBitRate + "  bySupport=" + bySupport);
try {
//  byte[] buffer = new byte[recBuffSize];
short[] inG711Buffer = new short[recBuffSize];
byte[] outG711Buffer = new byte[recBuffSize];
audioRecord.startRecording(); // 开始录⾳
//  audioTrack.play(); // 开始放⾳
while (isVudio) {
// 从MIC保存数据到buffer
//  int bufferReadResult = ad(buffer, 0, recBuffSize);
//    System.out.println("---------------------------------------------------"+bufferReadResult);
//    byte[] tmpBuffer = new byte[bufferReadResult];
//    System.arraycopy(buffer, 0, tmpBuffer, 0, bufferReadResult);
/
/ 写⼊数据到AudioTrack即可播放
//    audioTrack.write(tmpBuffer, 0, tmpBuffer.length);
//  注釋的代碼是本地录播
int nReadBytes = ad(inG711Buffer,0,recBuffSize);
G711Code.G711aEncoder(inG711Buffer,outG711Buffer,nReadBytes);
//因为每次写⼊outG711Buffer.length是640,所以需要分四次发送。
final int len=160;
final byte[] tmpBuffer = new byte[len];
for (int i=0;i<outG711Buffer.length;i+=160){
System.arraycopy(outG711Buffer, i, tmpBuffer, 0, 160); //需要复制分包发送每次发送160
}
}
// audioTrack.stop();
audioRecord.stop();
} catch (Throwable t) {
//    audioTrack.stop();
audioRecord.stop();
}
}
//停⽌语⾳转发
public boolean HkstopVoice(){
isVudio=false;
//  recordPlayThread.interrupt();
Instance().NET_DVR_StopVoiceCom(hk);
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。