一、应用端接入
语音对讲需要设备端与应用端协同:设备端负责音频的采集与播放(见下文 设备端接入),应用端则在查看监控期间开启本地麦克风采集,将 APP 语音传输给设备端。如需双向画面,还可同时开启本地摄像头。
注意:开启本地麦克风与摄像头前,请确保已在工程中申请并获取麦克风、摄像头权限,否则 startLocalAudio / startLocalVideo 会返回 ERR_MIC_NOT_AUTHORIZED / ERR_CAMERA_NOT_AUTHORIZED 等错误码。
二、接口说明
| 方法 | 说明 |
| startLocalAudio | 开始采集、传输本地麦克风音频。 |
| stopLocalAudio | 停止采集、传输本地麦克风音频。 |
| muteLocalAudio | mute 为 true 时静音本地麦克风。 |
| startLocalVideo | 开始采集、传输本地摄像头画面,view 为本地渲染视图,编码参数为 TXIoTVideoEncoderParams。 |
| stopLocalVideo | 停止采集、传输本地摄像头画面。 |
三、调用示例
AndroidiOS// 本地麦克风(对讲)session.startLocalAudio();session.muteLocalAudio(false);// session.stopLocalAudio();// 本地摄像头(可选,用于双向视频)TXCloudVideoView localView = findViewById(R.id.local_view);TXIoTVideoEncoderParams params = new TXIoTVideoEncoderParams();params.resolution = TXIoTVideoResolution.RESOLUTION_640_360;session.startLocalVideo(localView, params);// session.stopLocalVideo();// 本地麦克风(对讲)[session startLocalAudio];[session muteLocalAudio:NO];// [session stopLocalAudio];// 本地摄像头(可选,用于双向视频)UIView *localView = self.localVideoView;TXIoTVideoEncoderParams *params = [[TXIoTVideoEncoderParams alloc] init];params.resolution = TXIoTVideoResolution_640_360;[session startLocalVideo:localView videoEncoderParams:params];// [session stopLocalVideo];
四、错误处理
语音对讲需开启本地麦克风与摄像头,以下错误码在对讲过程中可能返回,完整错误码定义见 TXIoTErrorCode。
AndroidiOS
| 错误码 | 说明 | 建议处理方式 |
| ERR_CAMERA_START_FAIL | 摄像头启动失败。 | 检查设备摄像头是否被占用或硬件异常。 |
| ERR_CAMERA_NOT_AUTHORIZED | 摄像头权限未授权。 | 在工程中申请并获取摄像头权限。 |
| ERR_CAMERA_OCCUPY | 摄像头被占用。 | 停止其他占用摄像头的功能后再试。 |
| ERR_MIC_START_FAIL | 麦克风启动失败。 | 检查麦克风是否被占用或硬件异常。 |
| ERR_MIC_NOT_AUTHORIZED | 麦克风权限未授权。 | 在工程中申请并获取麦克风权限。 |
| ERR_MIC_OCCUPY | 麦克风被占用。 | 停止其他占用麦克风的功能后再试。 |
| 错误码 | 数值 | 说明 | 建议处理方式 |
| TXIoTErrorCodeCameraStartFail | -2000 | 摄像头启动失败。 | 检查设备摄像头是否被占用或硬件异常。 |
| TXIoTErrorCodeCameraNotAuthorized | -2001 | 摄像头权限未授权。 | 在工程中申请并获取摄像头权限。 |
| TXIoTErrorCodeCameraOccupy | -2002 | 摄像头被占用。 | 停止其他占用摄像头的功能后再试。 |
| TXIoTErrorCodeMicStartFail | -2003 | 麦克风启动失败。 | 检查麦克风是否被占用或硬件异常。 |
| TXIoTErrorCodeMicNotAuthorized | -2004 | 麦克风权限未授权。 | 在工程中申请并获取麦克风权限。 |
| TXIoTErrorCodeMicOccupy | -2005 | 麦克风被占用。 | 停止其他占用麦克风的功能后再试。 |
五、步骤 1:注册 on_audio_frame_received 回调
调用 tc_iot_av_init 注册 tc_iot_av_observer_s 时,为 on_audio_frame_received 赋值。APP 端在查看监控期间发起语音对讲时,设备端会通过该回调持续收到音频帧:
#include "tc_iot_av.h"static void on_audio_frame_received(const tc_iot_audio_frame *frame);tc_iot_av_observer_s observer;memset(&observer, 0, sizeof(observer));observer.on_audio_frame_received = on_audio_frame_received;tc_iot_error_e av_rc = tc_iot_av_init(&observer);if (av_rc != TC_IOT_ERR_SUCCESS) { printf("tc_iot_av_init failed: %d\\n", av_rc);}
六、步骤 2:解析音频帧
on_audio_frame_received 回调携带的 tc_iot_audio_frame 结构体字段如下:
| 字段 | 说明 |
| codec | 音频编码格式,固定为 TC_IOT_AUDIO_CODEC_PCM。 |
| sample_rate | 采样率,如 TC_IOT_AUDIO_SAMPLE_RATE_16000。 |
| channels | 声道数,TC_IOT_AUDIO_CHANNEL_MONO(单声道)或 TC_IOT_AUDIO_CHANNEL_STEREO(双声道)。 |
| frame_duration_ms | 单帧时长(毫秒)。 |
| data / data_size | PCM 音频数据指针与长度,可直接送入播放器。 |
| pts_ms | 帧时间戳(毫秒)。 |
注意:说明:
注意:目前 codec 固定为 TC_IOT_AUDIO_CODEC_PCM,无需考虑其他编码格式。
七、步骤 3:将音频数据送入播放器
将 data 指向的 PCM 数据写入设备的本地播放器(扬声器)完成播放。播放器接口由具体硬件平台提供,以下以自定义 speaker_play_pcm 函数表示,请替换为你设备实际的音频输出接口:
// speaker_play_pcm 由业务自行实现,对接具体硬件平台的音频输出接口extern void speaker_play_pcm(const uint8_t *pcm_data, size_t pcm_size);static void on_audio_frame_received(const tc_iot_audio_frame *frame) { if (!frame || !frame->data || frame->data_size == 0) { return; } speaker_play_pcm(frame->data, frame->data_size);}
八、常见问题
| 现象 | 排查建议 |
| 开启语音对讲后,设备端未收到 on_audio_frame_received。 | 确认设备已成功登录且 tc_iot_av_init 调用成功;确认 on_audio_frame_received 已正确赋值(未被 memset 清零覆盖);确认监控会话已建立(on_monitor_begin 已触发)。 |
| 设备端收到回调但播放无声音。 | 确认已正确对接本地音频播放硬件接口;检查 sample_rate、channels 与播放器初始化参数是否一致。 |
| 播放声音卡顿或有杂音。 | 检查 on_audio_frame_received 内是否有耗时阻塞操作(如同步写文件、网络请求等),建议将数据快速拷贝到缓冲队列后异步播放,避免阻塞回调影响后续帧接收。 |