本文将介绍设备如何实现实时监控场景下的语音对讲功能(设备端与 APP 进行语音对话)。
应用端接入
注意:
开启本地麦克风与摄像头前,请确保已在工程中申请并获取麦克风、摄像头权限,否则 startLocalAudio / startLocalVideo 会返回
ERR_MIC_NOT_AUTHORIZED / ERR_CAMERA_NOT_AUTHORIZED 等错误码。接口说明
方法 | 说明 |
开始采集、传输本地麦克风音频。 | |
停止采集、传输本地麦克风音频。 | |
mute 为 true 时静音本地麦克风。 | |
停止采集、传输本地摄像头画面。 |
调用示例
// 本地麦克风(对讲)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];
错误处理
错误码 | 说明 | 建议处理方式 |
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 内是否有耗时阻塞操作(如同步写文件、网络请求等),建议将数据快速拷贝到缓冲队列后异步播放,避免阻塞回调影响后续帧接收。 |