一、前提条件
在开始之前,请你先完成 登录与注册 文档中跑通 login 登录功能。如果你已经完成,可以跳过该操作。
注意:说明:
注意:监控推流依赖摄像头与麦克风采集,请确保已在 AndroidManifest.xml 中声明 android.permission.CAMERA、android.permission.RECORD_AUDIO 权限,并在运行时向用户申请授权。
二、步骤 1:注册监控事件回调
登录成功后,通过 TXIoTMonitorSession.getInstance().addListener 注册 TXIoTMonitorSession.Listener,实时监控相关的回调如下:
| 回调 | 说明 |
| onMonitorBegin | APP 发起监控查看请求时触发,携带 option(清晰度等)与 customData(自定义数据)。 |
| onMonitorEnd | 对端结束监控查看时触发。 |
| onMonitorSwitch | APP 在监控查看期间切换清晰度时触发,携带切换后的 quality(可选实现,详见 步骤 4)。 |
| onPTZCommandReceived | APP 下发云台控制指令时触发,携带 command(方向/变焦等)与 speed(速度),仅支持云台的设备需实现。 |
import com.tencent.liteav.iot.TXIoTMonitorSession;TXIoTMonitorSession monitorSession = TXIoTMonitorSession.getInstance();TXIoTMonitorSession.Listener listener = new TXIoTMonitorSession.Listener() { @Override public void onMonitorBegin(TXIoTMonitorSession.Option option, String customData) { // APP 发起监控,开启摄像头/麦克风采集推流(详见步骤 2、步骤 3) } @Override public void onMonitorEnd() { // APP 结束监控,关闭采集推流(详见步骤 5) } @Override public void onMonitorSwitch(TXIoTMonitorSession.VideoQuality quality) { // APP 切换清晰度(详见步骤 4) } @Override public void onPTZCommandReceived(TXIoTMonitorSession.PTZCommand command, int speed) { // 云台控制指令(可选实现) }};monitorSession.addListener(listener);
三、步骤 2:响应 onMonitorBegin,开启摄像头推流
在 onMonitorBegin 回调中,必须调用 openCamera 开启摄像头采集并推流,只需传入 Option 与用于本地预览的 TXCloudVideoView 即可:
| 接口 | 说明 |
| openCamera(Option option, TXCloudVideoView view) | 开启摄像头采集并推流,option 指定视频清晰度(可复用回调传入的 option);view 为本地预览渲染控件,若无需本地预览可传 null,返回 0(TXIoTError.SUCCESS)表示调用成功。 |
| closeCamera() | 关闭摄像头采集与推流(详见 步骤 5)。 |
private TXCloudVideoView mVideoView; // 在布局中放置 <com.tencent.rtmp.ui.TXCloudVideoView/> 并获取实例@Overridepublic void onMonitorBegin(TXIoTMonitorSession.Option option, String customData) { // 开启摄像头采集并推流,同时在 mVideoView 上本地预览 int ret = TXIoTMonitorSession.getInstance().openCamera(option, mVideoView); if (ret != TXIoTError.SUCCESS) { Log.e(TAG, "openCamera failed: " + ret); } // 若需要音频,继续开启麦克风推流(详见步骤 3) TXIoTMonitorSession.getInstance().openMicrophone();}
四、步骤 3:开启麦克风推流
若监控需要音频,调用 openMicrophone 开启麦克风就可实现音频采集并推流。
| 接口 | 说明 |
| openMicrophone() | 开启麦克风采集并推流。 |
| closeMicrophone() | 关闭麦克风采集与推流(详见 步骤 5)。 |
注意:开启摄像头与麦克风前,请确保已获得 CAMERA 与 RECORD_AUDIO 运行时权限,否则采集会失败导致对端无画面或无声音。
int ret = TXIoTMonitorSession.getInstance().openMicrophone();if (ret != TXIoTError.SUCCESS) { Log.e(TAG, "openMicrophone failed: " + ret);}
五、步骤 4:响应 onMonitorSwitch,切换视频清晰度(可选)
APP 端在监控查看期间切换清晰度时,设备端会通过 onMonitorSwitch 回调收到通知,携带切换后的 quality,在 onMonitorSwitch 回调中调用 switchVideoQuality 传入新的清晰度即可完成清晰度切换。quality 的可选取值(TXIoTMonitorSession.VideoQuality)如下:
| 取值 | 说明 |
| VideoQuality.UNKNOWN | 未知/未设置。 |
| VideoQuality.LD | 流畅(低清晰度)。 |
| VideoQuality.SD | 标清。 |
| VideoQuality.HD | 高清。 |
| VideoQuality.FHD | 超清(全高清)。 |
@Overridepublic void onMonitorSwitch(TXIoTMonitorSession.VideoQuality quality) { int ret = TXIoTMonitorSession.getInstance().switchVideoQuality(quality); if (ret != TXIoTError.SUCCESS) { Log.e(TAG, "switchVideoQuality failed: " + ret); }}
六、步骤 5:响应 onMonitorEnd,关闭采集推流
对端结束监控查看时触发 onMonitorEnd,此时应关闭摄像头与麦克风,停止采集推流:
@Overridepublic void onMonitorEnd() { TXIoTMonitorSession.getInstance().closeCamera(); TXIoTMonitorSession.getInstance().closeMicrophone();}
七、示例代码
以下示例展示在一个 Activity 中完成监听注册与监控推流的完整流程,设备登录与初始化请参考 登录与注册。
package com.example.iotdemo;import android.os.Bundle;import android.util.Log;import androidx.annotation.Nullable;import androidx.appcompat.app.AppCompatActivity;import com.tencent.liteav.iot.TXIoTError;import com.tencent.liteav.iot.TXIoTMonitorSession;import com.tencent.rtmp.ui.TXCloudVideoView;public class MonitorActivity extends AppCompatActivity { private static final String TAG = "MonitorActivity"; private TXIoTMonitorSession mMonitorSession; private TXCloudVideoView mVideoView; private final TXIoTMonitorSession.Listener mListener = new TXIoTMonitorSession.Listener() { @Override public void onMonitorBegin(TXIoTMonitorSession.Option option, String customData) { Log.i(TAG, "onMonitorBegin, customData=" + customData); // 开启摄像头采集并推流,同时本地预览 int ret = mMonitorSession.openCamera(option, mVideoView); if (ret != TXIoTError.SUCCESS) { Log.e(TAG, "openCamera failed: " + ret); } // 开启麦克风采集并推流 ret = mMonitorSession.openMicrophone(); if (ret != TXIoTError.SUCCESS) { Log.e(TAG, "openMicrophone failed: " + ret); } } @Override public void onMonitorSwitch(TXIoTMonitorSession.VideoQuality quality) { Log.i(TAG, "onMonitorSwitch, quality=" + quality); int ret = mMonitorSession.switchVideoQuality(quality); if (ret != TXIoTError.SUCCESS) { Log.e(TAG, "switchVideoQuality failed: " + ret); } } @Override public void onMonitorEnd() { Log.i(TAG, "onMonitorEnd"); mMonitorSession.closeCamera(); mMonitorSession.closeMicrophone(); } @Override public void onPTZCommandReceived(TXIoTMonitorSession.PTZCommand command, int speed) { Log.i(TAG, "onPTZCommandReceived, command=" + command + ", speed=" + speed); // 仅支持云台的设备需实现,驱动云台电机执行对应动作 } }; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_monitor); mVideoView = findViewById(R.id.video_view); // 前提:SDK 已完成初始化并登录成功(参见「登录与注册」) mMonitorSession = TXIoTMonitorSession.getInstance(); mMonitorSession.addListener(mListener); Log.i(TAG, "monitor session ready, waiting for monitor request from app…"); } @Override protected void onDestroy() { // 释放资源 mMonitorSession.closeCamera(); mMonitorSession.closeMicrophone(); mMonitorSession.removeListener(mListener); super.onDestroy(); }}
八、常见问题
| 现象 | 排查建议 |
| 发起监控查看后,设备端未收到 onMonitorBegin | 确认设备已成功登录;确认已通过 addListener 注册监听器且未在收到回调前被 removeListener 移除。 |
| APP 端看不到监控画面 | 确认已在 onMonitorBegin 中调用 openCamera 且返回 TXIoTError.SUCCESS;确认已获得 CAMERA 运行时权限;确认摄像头未被其他应用占用。 |
| APP 端听不到声音 | 确认已调用 openMicrophone 且返回 TXIoTError.SUCCESS;确认已获得 RECORD_AUDIO 运行时权限。 |
| 切换清晰度后,设备端未收到 onMonitorSwitch | 确认设备已成功登录且监听器已注册;确认监控会话已建立(onMonitorBegin 已触发)。 |
| 收到 onMonitorSwitch 回调但画面清晰度未变化 | 确认在回调中调用了 switchVideoQuality 且返回 TXIoTError.SUCCESS;确认传入的 quality 与回调携带的值一致。 |
| 监控结束后摄像头/麦克风仍被占用 | 确认在 onMonitorEnd 回调及页面销毁(onDestroy)时调用了 closeCamera 与 closeMicrophone 释放采集资源。 |
九、联系我们
如果你在接入或使用过程中有任何疑问或者建议,欢迎 联系我们 提交反馈。