跳转至

语音对讲转发

实现语音对讲/转发的流程

接口概览

接口名称 功能描述
NET_SDK_StartVoiceCom 启动语音对讲
NET_SDK_StartVoiceCom_MR 开启语音转发
NET_SDK_VoiceComSendData 语音转发实时数据发送
NET_SDK_InitAudioEncoder 初始化音频编码器
NET_SDK_EncodeAudioFrame 音频编码
NET_SDK_ReleaseAudioEncoder 释放音频编码资源
NET_SDK_StopVoiceCom 结束语音对讲或语音转发
Note

接口详细参数见接口定义部分

流程说明

---
title: 语音对讲和转发
---

%%{
  init: {
    'theme': 'base',
    'themeVariables': {
      'primaryTextColor': 'var(--md-mermaid-label-fg-color)',
    }
  }
}%%

flowchart TD
    A(设备SDK初始化<br><strong>NET_SDK_Init</strong>)
    B(用户注册设备<br><strong>NET_SDK_Login</strong>或<br><strong>NET_SDK_LoginEx</strong>)
    C("启动语音对讲<br><strong>NET_SDK_StartVoiceCom</strong>")
    D("启动语音转发<br><strong>NET_SDK_StartVoiceCom_MR</strong>")

    subgraph 音频数据编码
        C1(初始化音频编码器<br><strong>NET_SDK_InitAudioEncoder</strong>)
        C2(音频编码<br><strong>NET_SDK_EncodeAudioFrame</strong>)
        C3(释放音频编码资源<br><strong>NET_SDK_ReleaseAudioEncoder</strong>)
        C1 --> C2 --> C3
    end

    E("发送音频数据<br><strong>NET_SDK_VoiceComSendData</strong>")

    style 音频数据编码 fill:#e7b13387,stroke:#f66,stroke-width:2px,stroke-dasharray: 5

    X("停止语音对讲或语音转发<br><strong>NET_SDK_StopVoiceCom</strong>")
    Y(注销设备<br><strong>NET_SDK_Logout</strong>)
    Z(释放SDK资源<br><strong>NET_SDK_Cleanup</strong>)

    A --> B --> C ----> X --> Y --> Z
    B ---> D --> 音频数据编码 --> E ---> X
  • 语音对讲功能实现 PC 机与设备间音频的发送和接收。在成功注册设备后调用 NET_SDK_StartVoiceCom 接口完成,同时在该接口中用户可以通过设置回调函数获取当前设备发送或者 PC 机采集的数据(按需要选择回调编码后或者 PCM 数据)。

  • 首先调用 NET_SDK_StartVoiceCom_MR 接口启动与设备的语音转发(此时已建立与设备之间的连接,等待发送数据)。

  • 准备好待发送的数据(需要经过编码),编码流程见上图中橙黄色框部分,如果数据已按本公司的压缩格式处理这部分就可以省略。数据源可以是从 PC 声卡中采集或是从文件中读取,但是需要经过本公司提供的压缩算法进行压缩处理。

  • 经过第二步的编码操作,我们可以每次得到固定大小的且经过编码后的数据,调用 NET_SDK_VoiceComSendData 接口发送这些数据给设备。

  • 等所有的转发操作完成后,调用 NET_SDK_StopVoiceCom 接口结束与设备的语音转发连接。

Note

设备接收的音频数据格式为:8000HZ采样率,16bit,单声道。

示例代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <string>
#include "stdafx.h"
#include "DVR_NET_SDK.h"

using namespace std;

void VoiceCom()
{
    // Initial
    NET_SDK_Init();
    // Device information
    const std::string device_ip = "10.80.1.177";
    const DWORD decice_port = 6036;
    const std::string username = "admin";
    const std::string password = "123456";
    //  Login
    NET_SDK_DEVICEINFO device_info = {0};
    int userid = NET_SDK_Login(const_cast<char *>(device_ip.c_str()), decice_port, const_cast<char *>(username.c_str()), const_cast<char *>(password.c_str()), &device_info);

    if (userid > 0)
    {
        cout << "Login successfully: " << userid << endl;
    }
    else
    {
        cout << "Failed to login: " << userid << endl;
        return;
    }

    // Start voice communication
    LONG lChannel = 0;
    LONG vchandle = NET_SDK_StartVoiceCom(userid, FALSE, NULL, NULL, lChannel);

    if (vchandle == -1)
    {
        DWORD err1 = NET_SDK_GetLastError();
        cout << "Failed to start voice communication! error code: " << err1 << endl;
    }
    else
    {
        cout << "Start voice communication successfully!" << endl;
    }

    // Stop voice communication
    NET_SDK_StopVoiceCom(vchandle);
    // Logout
    NET_SDK_Logout(userid);
    // Clean up the data
    NET_SDK_Cleanup();
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
#include <string>
#include "stdafx.h"
#include "DVR_NET_SDK.h"

using namespace std;

void VoiceForward()
{
    // Initial
    NET_SDK_Init();
    // Device information
    const std::string device_ip = "10.80.1.177";
    const DWORD decice_port = 6036;
    const std::string username = "admin";
    const std::string password = "123456";
    //  Login
    NET_SDK_DEVICEINFO device_info = {0};
    int userid = NET_SDK_Login(const_cast<char *>(device_ip.c_str()), decice_port, const_cast<char *>(username.c_str()), const_cast<char *>(password.c_str()), &device_info);

    if (userid > 0)
    {
        cout << "Login successfully: " << userid << endl;
    }
    else
    {
        cout << "Failed to login: " << userid << endl;
        return;
    }

    std::string fname = "./voice.pcm";

    LONG lChannel = -1;
    if (reinterpret_cast<CButton*>(GetDlgItem(IDC_CHECK_TALK_TO_CHANNEL))->GetCheck())
    {
        lChannel = m_comChannel.GetCurSel();
    }

    POINTERHANDLE handle = NET_SDK_StartVoiceCom_MR(m_userID, TRUE, nullptr, this, lChannel);
    if (handle == -1) {
        return;
    }

    FILE* hStreamFile = fopen(fname.c_str(), "rb+");
    if (NULL == hStreamFile)
    {
        return;
    }


    const int SAMPLE_RATE = 8000;   /* sample rate */
    const int CHANNELS = 1;         /* number of channels (i.e. mono, stereo...) */
    const int BITS_PER_SAMPLE = 16; /* Number of bits per sample of mono data */
    const size_t BUFFER_SIZE = 3200;  
    char buffer[BUFFER_SIZE];  
    size_t bytesRead;
    int sleepTime = 0;
    while ((bytesRead = fread(buffer, sizeof(char), BUFFER_SIZE, hStreamFile)) > 0) {
        NET_SDK_VoiceComSendData(handle, buffer, bytesRead);
        sleepTime = bytesRead *1000/ (SAMPLE_RATE* BITS_PER_SAMPLE* CHANNELS /8);
        Sleep(sleepTime);
    }

    fclose(hStreamFile);

    // Stop voice forwarding
    NET_SDK_StopVoiceCom(handle);
    // Logout
    NET_SDK_Logout(userid);
    // Clean up the data
    NET_SDK_Cleanup();
}

相关说明

错误码