@tencentcloud/sdk-mcp 1.7.7 → 1.7.9-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/README.md +7 -9
- package/index.js +8 -8
- package/knowledge/chunker.js +1 -0
- package/knowledge/doc-url-resolver.js +16 -9
- package/knowledge/embedding/build-vectors.js +92 -0
- package/knowledge/embedding/embed-model.js +41 -0
- package/knowledge/embedding/vector-augment.js +126 -0
- package/knowledge/embedding/vector-index.js +70 -0
- package/knowledge/frontmatter-meta.js +23 -0
- package/knowledge/path-meta.js +56 -0
- package/knowledge/search/exact-lookup.js +145 -16
- package/knowledge/search/filter-pool.js +77 -33
- package/knowledge/search/rank-profile.js +25 -0
- package/knowledge/search/requires-framework.js +4 -1
- package/knowledge/search/search-core.js +74 -13
- package/knowledge/search/search-knowledge.js +24 -34
- package/knowledge/search/search-pass.js +495 -169
- package/knowledge/search/url-row-scorer.js +24 -6
- package/package.json +3 -1
- package/resource/index/manifest.json +1 -1
- package/resource/index/vectors/index.json +4 -0
- package/resource/integration/callkit/preset/android/integration.md +0 -2
- package/resource/integration/callkit/preset/ios/integration.md +0 -2
- package/resource/integration/chat/preset/react/integration.md +9 -5
- package/resource/integration/chat/preset/uni-app/integration.md +4 -0
- package/resource/integration/chat/preset/vue/integration.md +10 -6
- package/resource/integration/livekit/preset/live/android/prepare-integration.md +0 -4
- package/resource/integration/livekit/preset/live/ios/prepare-integration.md +0 -4
- package/resource/integration/roomkit/preset/vue/integration.md +154 -208
- package/resource/knowledge/callkit/best-practice/android/video-chat-dating.md +0 -2
- package/resource/knowledge/callkit/core-sdk/android/answer-call.md +0 -2
- package/resource/knowledge/callkit/core-sdk/android/make-call.md +0 -2
- package/resource/knowledge/callkit/core-sdk/flutter/answer-call.md +0 -4
- package/resource/knowledge/callkit/core-sdk/flutter/make-call.md +0 -2
- package/resource/knowledge/callkit/core-sdk/flutter/offline-push.md +0 -2
- package/resource/knowledge/callkit/core-sdk/ios/answer-call.md +0 -2
- package/resource/knowledge/callkit/core-sdk/ios/make-call.md +0 -4
- package/resource/knowledge/callkit/core-sdk/ios/offline-push.md +0 -2
- package/resource/knowledge/callkit/core-sdk/uni-app/answer-call.md +0 -2
- package/resource/knowledge/callkit/core-sdk/uni-app/make-call.md +0 -2
- package/resource/knowledge/callkit/faq/ios.md +0 -2
- package/resource/knowledge/callkit/faq/uniapp-app.md +0 -2
- package/resource/knowledge/callkit/preset/miniprogram/integration.md +2 -3
- package/resource/knowledge/callkit/preset/miniprogram/uniapp-integration.md +0 -2
- package/resource/knowledge/chat/preset/ios-uikit/integration.md +0 -16
- package/resource/knowledge/chat/preset/react/h5/integration.md +16 -5
- package/resource/knowledge/chat/preset/vue/features/conversation-list.md +6 -3
- package/resource/knowledge/chat/preset/vue/h5/integration.md +7 -4
- package/resource/knowledge/iot/app/activate-service.md +95 -0
- package/resource/knowledge/iot/app/demo/android.md +93 -0
- package/resource/knowledge/iot/app/demo/ios.md +87 -0
- package/resource/knowledge/iot/app/demo/miniprogram.md +79 -0
- package/resource/knowledge/iot/app/device-binding.md +378 -0
- package/resource/knowledge/iot/app/device-sharing.md +414 -0
- package/resource/knowledge/iot/app/family-management.md +762 -0
- package/resource/knowledge/iot/app/integration/android.md +328 -0
- package/resource/knowledge/iot/app/integration/harmonyos.md +326 -0
- package/resource/knowledge/iot/app/integration/ios.md +351 -0
- package/resource/knowledge/iot/app/integration/miniprogram.md +268 -0
- package/resource/knowledge/iot/app/monitor-playback.md +557 -0
- package/resource/knowledge/iot/app/remote-control.md +139 -0
- package/resource/knowledge/iot/app/video-call.md +559 -0
- package/resource/knowledge/iot/app/wechat-call/device-call-miniprogram.md +204 -0
- package/resource/knowledge/iot/app/wechat-call/miniprogram-call-device.md +193 -0
- package/resource/knowledge/iot/client-api/app/android/txiotcallsession.md +189 -0
- package/resource/knowledge/iot/client-api/app/android/txiotcloudstorage.md +77 -0
- package/resource/knowledge/iot/client-api/app/android/txiotdevicemanager.md +175 -0
- package/resource/knowledge/iot/client-api/app/android/txiotengine.md +172 -0
- package/resource/knowledge/iot/client-api/app/android/txiotenginedef.md +163 -0
- package/resource/knowledge/iot/client-api/app/android/txiotfamilymanager.md +146 -0
- package/resource/knowledge/iot/client-api/app/android/txiotmonitorsession.md +246 -0
- package/resource/knowledge/iot/client-api/app/harmonyos/txiotcallsession.md +191 -0
- package/resource/knowledge/iot/client-api/app/harmonyos/txiotcloudstorage.md +77 -0
- package/resource/knowledge/iot/client-api/app/harmonyos/txiotdevicemanager.md +183 -0
- package/resource/knowledge/iot/client-api/app/harmonyos/txiotengine.md +186 -0
- package/resource/knowledge/iot/client-api/app/harmonyos/txiotenginedef.md +164 -0
- package/resource/knowledge/iot/client-api/app/harmonyos/txiotfamilymanager.md +150 -0
- package/resource/knowledge/iot/client-api/app/harmonyos/txiotmonitorsession.md +252 -0
- package/resource/knowledge/iot/client-api/app/ios/txiotcallsession.md +199 -0
- package/resource/knowledge/iot/client-api/app/ios/txiotcloudstorage.md +76 -0
- package/resource/knowledge/iot/client-api/app/ios/txiotdevicemanager.md +173 -0
- package/resource/knowledge/iot/client-api/app/ios/txiotengine.md +173 -0
- package/resource/knowledge/iot/client-api/app/ios/txiotenginedef.md +171 -0
- package/resource/knowledge/iot/client-api/app/ios/txiotfamilymanager.md +146 -0
- package/resource/knowledge/iot/client-api/app/ios/txiotmonitorsession.md +250 -0
- package/resource/knowledge/iot/client-api/app/miniprogram/txiotcallsession.md +180 -0
- package/resource/knowledge/iot/client-api/app/miniprogram/txiotcloudstorage.md +76 -0
- package/resource/knowledge/iot/client-api/app/miniprogram/txiotdevicemanager.md +281 -0
- package/resource/knowledge/iot/client-api/app/miniprogram/txiotengine.md +183 -0
- package/resource/knowledge/iot/client-api/app/miniprogram/txiotenginedef.md +152 -0
- package/resource/knowledge/iot/client-api/app/miniprogram/txiotfamilymanager.md +179 -0
- package/resource/knowledge/iot/client-api/app/miniprogram/txiotmonitorsession.md +226 -0
- package/resource/knowledge/iot/client-api/device/android-smart-device.md +813 -0
- package/resource/knowledge/iot/client-api/device/linux-rtos-device.md +2027 -0
- package/resource/knowledge/iot/device/activate-service.md +167 -0
- package/resource/knowledge/iot/device/ai-voice-chat/advanced-features/custom-agent.md +171 -0
- package/resource/knowledge/iot/device/ai-voice-chat/advanced-features/smart-device-control.md +721 -0
- package/resource/knowledge/iot/device/ai-voice-chat/integration-guide/android-smart-device.md +247 -0
- package/resource/knowledge/iot/device/ai-voice-chat/integration-guide/linux-rtos-device.md +368 -0
- package/resource/knowledge/iot/device/ai-voice-chat/overview.md +84 -0
- package/resource/knowledge/iot/device/cloud-storage.md +696 -0
- package/resource/knowledge/iot/device/data-model.md +972 -0
- package/resource/knowledge/iot/device/demo/android-smart-device.md +97 -0
- package/resource/knowledge/iot/device/demo/linux-rtos-device.md +106 -0
- package/resource/knowledge/iot/device/device-ota-upgrade.md +237 -0
- package/resource/knowledge/iot/device/dynamic-registration/android-smart-device.md +275 -0
- package/resource/knowledge/iot/device/dynamic-registration/linux-rtos-device.md +297 -0
- package/resource/knowledge/iot/device/login-and-register/android-smart-device.md +131 -0
- package/resource/knowledge/iot/device/login-and-register/linux-rtos-device.md +291 -0
- package/resource/knowledge/iot/device/monitor-pushing/android-smart-device.md +237 -0
- package/resource/knowledge/iot/device/monitor-pushing/linux-rtos-device.md +493 -0
- package/resource/knowledge/iot/device/video-call/android-smart-device.md +299 -0
- package/resource/knowledge/iot/device/video-call/linux-rtos-device.md +465 -0
- package/resource/knowledge/iot/device/wechat-call/android-smart-device.md +534 -0
- package/resource/knowledge/iot/device/wechat-call/linux-rtos-device.md +681 -0
- package/resource/knowledge/iot/kids-watch/overview.md +28 -0
- package/resource/knowledge/iot/security-camera/activate-service.md +74 -0
- package/resource/knowledge/iot/security-camera/monitor-playback/app-integration.md +302 -0
- package/resource/knowledge/iot/security-camera/monitor-playback/device-integration/android.md +237 -0
- package/resource/knowledge/iot/security-camera/monitor-playback/device-integration/linux-rtos.md +493 -0
- package/resource/knowledge/iot/security-camera/overview.md +31 -0
- package/resource/knowledge/iot/security-camera/ptz-control.md +153 -0
- package/resource/knowledge/iot/security-camera/recording-and-snapshot.md +182 -0
- package/resource/knowledge/iot/security-camera/voice-intercom.md +174 -0
- package/resource/knowledge/iot/smart-vision/serviceoverview.md +114 -0
- package/resource/knowledge/iot/voice-recorder/app-demo.md +99 -0
- package/resource/knowledge/iot/voice-recorder/device-demo.md +189 -0
- package/resource/knowledge/iot/voice-recorder/overview.md +64 -0
- package/resource/knowledge/livekit/core-sdk/features/android/base-beauty.md +0 -2
- package/resource/knowledge/livekit/core-sdk/features/android/gift.md +0 -4
- package/resource/knowledge/livekit/core-sdk/features/android/live-list.md +0 -2
- package/resource/knowledge/livekit/core-sdk/features/flutter/audio-effect.md +0 -2
- package/resource/knowledge/livekit/core-sdk/features/flutter/base-beauty.md +0 -2
- package/resource/knowledge/livekit/core-sdk/features/flutter/gift.md +0 -4
- package/resource/knowledge/livekit/core-sdk/features/ios/base-beauty.md +0 -2
- package/resource/knowledge/livekit/core-sdk/features/ios/gift.md +0 -4
- package/resource/knowledge/livekit/core-sdk/features/ios/live-list.md +0 -2
- package/resource/knowledge/livekit/core-sdk/features/uni-app/base-beauty.md +0 -2
- package/resource/knowledge/livekit/core-sdk/features/uni-app/gift.md +0 -4
- package/resource/knowledge/livekit/core-sdk/live/android/co-guest-interaction.md +0 -4
- package/resource/knowledge/livekit/core-sdk/live/android/host-interaction.md +0 -10
- package/resource/knowledge/livekit/core-sdk/live/android/integration.md +0 -2
- package/resource/knowledge/livekit/core-sdk/live/flutter/co-guest-interaction.md +0 -2
- package/resource/knowledge/livekit/core-sdk/live/flutter/host-interaction.md +0 -10
- package/resource/knowledge/livekit/core-sdk/live/flutter/integration.md +0 -2
- package/resource/knowledge/livekit/core-sdk/live/ios/co-guest-interaction.md +0 -4
- package/resource/knowledge/livekit/core-sdk/live/ios/host-interaction.md +0 -10
- package/resource/knowledge/livekit/core-sdk/live/ios/integration.md +0 -2
- package/resource/knowledge/livekit/core-sdk/live/uni-app/co-guest-interaction.md +0 -4
- package/resource/knowledge/livekit/core-sdk/live/uni-app/host-interaction.md +0 -4
- package/resource/knowledge/livekit/core-sdk/live/uni-app/integration.md +0 -2
- package/resource/knowledge/livekit/core-sdk/voice/android/co-guest-interaction.md +0 -2
- package/resource/knowledge/livekit/core-sdk/voice/android/host-interaction.md +0 -4
- package/resource/knowledge/livekit/core-sdk/voice/android/integration.md +0 -4
- package/resource/knowledge/livekit/core-sdk/voice/flutter/integration.md +0 -2
- package/resource/knowledge/livekit/core-sdk/voice/ios/co-guest-interaction.md +0 -2
- package/resource/knowledge/livekit/core-sdk/voice/ios/host-interaction.md +0 -4
- package/resource/knowledge/livekit/core-sdk/voice/ios/integration.md +0 -4
- package/resource/knowledge/livekit/core-sdk/voice/uni-app/co-guest-interaction.md +0 -2
- package/resource/knowledge/livekit/core-sdk/voice/uni-app/integration.md +0 -2
- package/resource/knowledge/livekit/faq/error-code.md +0 -2
- package/resource/knowledge/push/config/android/honor.md +16 -1
- package/resource/knowledge/push/config/android/huawei.md +20 -4
- package/resource/knowledge/push/config/android/meizu.md +19 -5
- package/resource/knowledge/push/config/android/vivo.md +20 -1
- package/resource/knowledge/push/config/donut.md +0 -2
- package/resource/knowledge/push/config/harmonyos.md +21 -5
- package/resource/knowledge/push/integration/android.md +0 -5
- package/resource/knowledge/push/integration/donut.md +0 -3
- package/resource/knowledge/push/integration/flutter.md +1 -4
- package/resource/knowledge/push/integration/harmonyos.md +0 -3
- package/resource/knowledge/push/integration/ios.md +0 -3
- package/resource/knowledge/push/integration/react-native.md +0 -5
- package/resource/knowledge/push/integration/uni-app.md +0 -3
- package/resource/knowledge/push/integration/unity.md +0 -3
- package/resource/knowledge/push/integration/unreal-engine.md +0 -3
- package/resource/knowledge/roomkit/core-sdk/android/call-user-to-room.md +0 -2
- package/resource/knowledge/roomkit/core-sdk/android/room-participant-state.md +0 -2
- package/resource/knowledge/roomkit/core-sdk/android/room-state.md +0 -2
- package/resource/knowledge/roomkit/core-sdk/android/schedule-room.md +0 -2
- package/resource/knowledge/roomkit/core-sdk/flutter/call-user-to-room.md +0 -2
- package/resource/knowledge/roomkit/core-sdk/flutter/room-participant-state.md +0 -2
- package/resource/knowledge/roomkit/core-sdk/flutter/room-state.md +0 -2
- package/resource/knowledge/roomkit/core-sdk/flutter/schedule-room.md +0 -2
- package/resource/knowledge/roomkit/core-sdk/ios/call-user-to-room.md +0 -2
- package/resource/knowledge/roomkit/core-sdk/ios/room-participant-state.md +0 -2
- package/resource/knowledge/roomkit/core-sdk/ios/room-state.md +0 -2
- package/resource/knowledge/roomkit/core-sdk/ios/schedule-room.md +0 -2
- package/resource/knowledge/roomkit/core-sdk/vue/room-view.md +0 -3
- package/resource/knowledge/roomkit/preset/uniapp-app/integration.md +18 -14
- package/resource/knowledge/rtcengine/web/how_to_run_web_sdk_demo.md +0 -2
- package/resource/knowledge/rtcengine/web/plugin/23-advanced-support-detection.md +30 -0
- package/resource/knowledge/rtcengine/web/plugin/24-advanced-network-quality.md +0 -2
- package/resource/knowledge/rtcengine/web/plugin/31-advanced-plugins-overview.md +1 -1
- package/resource/knowledge/rtcengine/web/plugin/35-advanced-ai-denoiser.md +1 -1
- package/resource/knowledge/rtcengine/web/plugin/36-advanced-virtual-background.md +4 -0
- package/resource/knowledge/trtc/android/TRTCCloud.md +94 -85
- package/resource/knowledge/trtc/android/TRTCCloudDef.md +48 -46
- package/resource/knowledge/trtc/android/TRTCCloudListener.md +48 -48
- package/resource/knowledge/trtc/android/TXAudioEffectManager.md +18 -18
- package/resource/knowledge/trtc/android/TXDeviceManager.md +4 -4
- package/resource/knowledge/trtc/android/TXLiteAVCode.md +1 -0
- package/resource/knowledge/trtc/c++/ITRTCCloud.md +90 -90
- package/resource/knowledge/trtc/c++/ITXAudioEffectManager.md +18 -18
- package/resource/knowledge/trtc/c++/ITXDeviceManager.md +9 -9
- package/resource/knowledge/trtc/c++/TRTCCloudCallback.md +47 -47
- package/resource/knowledge/trtc/c++/TRTCTypeDef.md +47 -45
- package/resource/knowledge/trtc/c++/TXLiteAVCode.md +1 -0
- package/resource/knowledge/trtc/ios/TRTCCloud.md +93 -93
- package/resource/knowledge/trtc/ios/TRTCCloudDelegate.md +50 -50
- package/resource/knowledge/trtc/ios/TXAudioEffectManager.md +8 -8
- package/resource/knowledge/trtc/ios/TXDeviceManager.md +9 -9
- package/resource/knowledge/trtc/ios/TXLiteAVCode.md +1 -0
- package/resource/knowledge/trtc/ios/TXLiveSDKTypeDef.md +48 -46
- package/server-config.js +8 -9
- package/server.js +1 -1
- package/tools/common/finalize_answer.js +1 -1
- package/tools/common/present_framework_choice.js +1 -1
- package/tools/common/search_trtc_knowledge.js +22 -3
- package/tools/definitions/search_trtc_knowledge_def.js +3 -2
- package/utils/preflight-route.js +19 -2
- package/utils/report-cls-client.js +1 -1
- package/utils/report-es-client.js +1 -1
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
---
|
|
2
|
+
product: iot
|
|
3
|
+
framework:
|
|
4
|
+
- linux
|
|
5
|
+
types:
|
|
6
|
+
- feature
|
|
7
|
+
retrievable_scope: always
|
|
8
|
+
feature_domain: device
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
本文将介绍 App 呼叫设备,实现 App 和设备之间的**双向通话**,包括响应来电(接听/拒绝)和挂断通话。
|
|
12
|
+
|
|
13
|
+
## 前提条件
|
|
14
|
+
|
|
15
|
+
在接入通话功能前,请您先完成 登录与注册 文档中跑通 `tc_iot_login` 登录功能。如果您已经完成,可以跳过该操作。
|
|
16
|
+
|
|
17
|
+
## 接入步骤
|
|
18
|
+
|
|
19
|
+
### 步骤 1:注册通话事件回调
|
|
20
|
+
|
|
21
|
+
登录成功后,调用 `tc_iot_av_init` 注册 `tc_iot_av_observer_s`,通话相关的回调如下:
|
|
22
|
+
|
|
23
|
+
|回调|说明|
|
|
24
|
+
|---------|---------|
|
|
25
|
+
|`on_call_requested`|收到对端来电时触发,携带 `contact`(对端信息)与 `option`(通话媒体类型等)。|
|
|
26
|
+
|`on_call_timeout`|来电无人应答超时时触发。|
|
|
27
|
+
|`on_call_hangup`|对端挂断通话时触发。|
|
|
28
|
+
|
|
29
|
+
``` c
|
|
30
|
+
#include "tc_iot_av.h"
|
|
31
|
+
|
|
32
|
+
static void on_call_requested(const tc_iot_contact_s *contact, tc_iot_call_option_t option);
|
|
33
|
+
static void on_call_timeout(const tc_iot_contact_s *contact);
|
|
34
|
+
static void on_call_hangup(const tc_iot_contact_s *contact);
|
|
35
|
+
|
|
36
|
+
tc_iot_av_observer_s observer;
|
|
37
|
+
memset(&observer, 0, sizeof(observer));
|
|
38
|
+
observer.on_call_requested = on_call_requested;
|
|
39
|
+
observer.on_call_timeout = on_call_timeout;
|
|
40
|
+
observer.on_call_hangup = on_call_hangup;
|
|
41
|
+
|
|
42
|
+
tc_iot_error_e av_rc = tc_iot_av_init(&observer);
|
|
43
|
+
if (av_rc != TC_IOT_ERR_SUCCESS) {
|
|
44
|
+
printf("tc_iot_av_init failed: %d\n", av_rc);
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 步骤 2:响应来电,接听或拒绝
|
|
49
|
+
|
|
50
|
+
收到 `on_call_requested` 后,根据业务逻辑调用 `tc_iot_av_accept` 接听,或调用 `tc_iot_av_reject` 拒绝:
|
|
51
|
+
``` c
|
|
52
|
+
static void on_call_requested(const tc_iot_contact_s *contact, tc_iot_call_option_t option) {
|
|
53
|
+
printf("[demo] on_call_requested user_id=%s media=%d\n", contact->user_id, option.media_content);
|
|
54
|
+
|
|
55
|
+
// 示例:直接接听,实际业务可结合按键、APP 联动等方式决定接听或拒绝
|
|
56
|
+
tc_iot_error_e rc = tc_iot_av_accept(contact, NULL);
|
|
57
|
+
if (rc != TC_IOT_ERR_SUCCESS) {
|
|
58
|
+
printf("[demo] tc_iot_av_accept failed: %d\n", rc);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// 拒绝来电:tc_iot_av_reject(contact, NULL);
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### 步骤 3:创建发送通道
|
|
66
|
+
|
|
67
|
+
己方接听来电成功后,通话即建立,此时根据通话的 `media_content` 创建对应的发送通道:
|
|
68
|
+
|
|
69
|
+
|接口|说明|
|
|
70
|
+
|---------|---------|
|
|
71
|
+
|`tc_iot_create_video_channel(channel_id, quality)`|创建视频发送通道,通话场景固定使用通道 `0`,`quality` 为视频清晰度。|
|
|
72
|
+
|`tc_iot_create_audio_channel()`|创建音频发送通道,无需传入 `channel_id`。|
|
|
73
|
+
|
|
74
|
+
> **注意:**
|
|
75
|
+
> 设备通常只有一路麦克风采集源,`tc_iot_create_audio_channel` 建议全局只创建一次。
|
|
76
|
+
>
|
|
77
|
+
|
|
78
|
+
``` c
|
|
79
|
+
static tc_iot_av_channel_t *g_video_channel = NULL;
|
|
80
|
+
static tc_iot_av_channel_t *g_audio_channel = NULL;
|
|
81
|
+
|
|
82
|
+
// 通话建立后,根据媒体类型创建对应的发送通道
|
|
83
|
+
static void create_call_channels(tc_iot_media_content_e media_content,
|
|
84
|
+
tc_iot_video_quality_e quality) {
|
|
85
|
+
if (media_content == TC_IOT_MEDIA_CONTENT_VIDEO ||
|
|
86
|
+
media_content == TC_IOT_MEDIA_CONTENT_AUDIO_VIDEO) {
|
|
87
|
+
g_video_channel = tc_iot_create_video_channel(0, quality);
|
|
88
|
+
if (!g_video_channel) {
|
|
89
|
+
printf("[demo] create video channel failed\n");
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if ((media_content == TC_IOT_MEDIA_CONTENT_AUDIO ||
|
|
94
|
+
media_content == TC_IOT_MEDIA_CONTENT_AUDIO_VIDEO) &&
|
|
95
|
+
!g_audio_channel) {
|
|
96
|
+
g_audio_channel = tc_iot_create_audio_channel();
|
|
97
|
+
if (!g_audio_channel) {
|
|
98
|
+
printf("[demo] create audio channel failed\n");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// 启动本地采集(示意,详见步骤 4/5 推流示例)
|
|
103
|
+
// start_capture_and_push(...)
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### 步骤 4:推送视频帧
|
|
108
|
+
|
|
109
|
+
采集到一帧编码后的视频数据后,填充 `tc_iot_video_frame` 并调用 `tc_iot_push_video_frame` 推送到视频发送通道:
|
|
110
|
+
|
|
111
|
+
|字段|说明|
|
|
112
|
+
|---------|---------|
|
|
113
|
+
|`codec`|视频编码格式,`TC_IOT_VIDEO_CODEC_H264` 或 `TC_IOT_VIDEO_CODEC_H265`。|
|
|
114
|
+
|`type`|帧类型,关键帧 `TC_IOT_VIDEO_FRAME_TYPE_IDR` 或非关键帧 `TC_IOT_VIDEO_FRAME_TYPE_P`。|
|
|
115
|
+
|`rotation`|画面旋转角度,如 `TC_IOT_VIDEO_ROTATION_0`。|
|
|
116
|
+
|`width` / `height`|画面宽高(像素)。|
|
|
117
|
+
|`data` / `data_size`|编码后的视频裸流数据指针与长度。|
|
|
118
|
+
|`pts_ms`|帧时间戳(毫秒)。|
|
|
119
|
+
|
|
120
|
+
> **说明:**
|
|
121
|
+
> 建议推送第一个 **IDR 关键帧**之后才开始持续推流,以保证对端能正常解码;在 IDR 帧之前推送 P 帧,对端可能无法解码画面。
|
|
122
|
+
>
|
|
123
|
+
|
|
124
|
+
``` c
|
|
125
|
+
void push_video_frame_sample(tc_iot_av_channel_t *video_channel,
|
|
126
|
+
const uint8_t *encoded_data, size_t encoded_size,
|
|
127
|
+
bool is_key_frame) {
|
|
128
|
+
if (!video_channel) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
tc_iot_video_frame frame;
|
|
133
|
+
memset(&frame, 0, sizeof(frame));
|
|
134
|
+
frame.codec = TC_IOT_VIDEO_CODEC_H264;
|
|
135
|
+
frame.type = is_key_frame ? TC_IOT_VIDEO_FRAME_TYPE_IDR : TC_IOT_VIDEO_FRAME_TYPE_P;
|
|
136
|
+
frame.rotation = TC_IOT_VIDEO_ROTATION_0;
|
|
137
|
+
frame.width = 480;
|
|
138
|
+
frame.height = 320;
|
|
139
|
+
frame.data = (uint8_t *)encoded_data;
|
|
140
|
+
frame.data_size = encoded_size;
|
|
141
|
+
frame.pts_ms = current_time_ms(); // 由业务自行实现,返回当前毫秒时间戳
|
|
142
|
+
|
|
143
|
+
tc_iot_error_e err = tc_iot_push_video_frame(video_channel, &frame);
|
|
144
|
+
if (err != TC_IOT_ERR_SUCCESS) {
|
|
145
|
+
printf("[demo] push video frame failed: %d\n", err);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### 步骤 5:推送音频帧
|
|
151
|
+
|
|
152
|
+
采集到一帧编码后的音频数据后,填充 `tc_iot_audio_frame` 并调用 `tc_iot_push_audio_frame` 推送到音频发送通道:
|
|
153
|
+
|
|
154
|
+
|字段|说明|
|
|
155
|
+
|---------|---------|
|
|
156
|
+
|`codec`|音频编码格式,支持 `TC_IOT_AUDIO_CODEC_PCM` / `AAC` / `OPUS` / `G722`。|
|
|
157
|
+
|`sample_rate`|采样率,如 `TC_IOT_AUDIO_SAMPLE_RATE_16000`。|
|
|
158
|
+
|`channels`|声道数,`TC_IOT_AUDIO_CHANNEL_MONO`(单声道)或 `TC_IOT_AUDIO_CHANNEL_STEREO`(双声道)。|
|
|
159
|
+
|`frame_duration_ms`|单帧时长(毫秒),如 20ms 一帧。|
|
|
160
|
+
|`data` / `data_size`|编码后的音频裸流数据指针与长度。|
|
|
161
|
+
|`pts_ms`|帧时间戳(毫秒)。|
|
|
162
|
+
|
|
163
|
+
``` c
|
|
164
|
+
void push_audio_frame_sample(tc_iot_av_channel_t *audio_channel,
|
|
165
|
+
const uint8_t *pcm_data, size_t pcm_size) {
|
|
166
|
+
if (!audio_channel) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
tc_iot_audio_frame frame;
|
|
171
|
+
memset(&frame, 0, sizeof(frame));
|
|
172
|
+
frame.codec = TC_IOT_AUDIO_CODEC_PCM;
|
|
173
|
+
frame.sample_rate = TC_IOT_AUDIO_SAMPLE_RATE_16000;
|
|
174
|
+
frame.channels = TC_IOT_AUDIO_CHANNEL_MONO;
|
|
175
|
+
frame.frame_duration_ms = 20;
|
|
176
|
+
frame.data = (uint8_t *)pcm_data;
|
|
177
|
+
frame.data_size = pcm_size;
|
|
178
|
+
frame.pts_ms = current_time_ms(); // 由业务自行实现,返回当前毫秒时间戳
|
|
179
|
+
|
|
180
|
+
tc_iot_error_e err = tc_iot_push_audio_frame(audio_channel, &frame);
|
|
181
|
+
if (err != TC_IOT_ERR_SUCCESS) {
|
|
182
|
+
printf("[demo] push audio frame failed: %d\n", err);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### 步骤 6:挂断通话
|
|
188
|
+
|
|
189
|
+
通话中主动挂断,调用 `tc_iot_av_hangup`;对端挂断时会触发 `on_call_hangup`,此时应停止本地推流并销毁发送通道:
|
|
190
|
+
``` c
|
|
191
|
+
void hangup_call(const char *user_id) {
|
|
192
|
+
tc_iot_contact_s contact = {0};
|
|
193
|
+
contact.user_id = user_id;
|
|
194
|
+
|
|
195
|
+
tc_iot_error_e rc = tc_iot_av_hangup(&contact, NULL);
|
|
196
|
+
if (rc != TC_IOT_ERR_SUCCESS) {
|
|
197
|
+
printf("[demo] tc_iot_av_hangup failed: %d\n", rc);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
static void on_call_hangup(const tc_iot_contact_s *contact) {
|
|
202
|
+
printf("[demo] on_call_hangup user_id=%s\n", contact->user_id);
|
|
203
|
+
// 停止推流并销毁发送通道(同实时监控场景的 on_monitor_end 处理)
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
> **说明:**
|
|
208
|
+
> 己方来电未及时处理时会触发 `on_call_timeout`,处理方式与 `on_call_hangup` 一致:停止推流并释放资源。
|
|
209
|
+
>
|
|
210
|
+
|
|
211
|
+
## 完整示例代码
|
|
212
|
+
|
|
213
|
+
以下示例整合登录、通话事件响应、发起语音/视频呼叫、以及使用**模拟数据**推送音视频帧的完整流程,用于验证通话链路是否正常。实际接入时,请将模拟数据替换为真实的摄像头/麦克风采集数据。
|
|
214
|
+
``` c
|
|
215
|
+
#include <stdio.h>
|
|
216
|
+
#include <stdlib.h>
|
|
217
|
+
#include <string.h>
|
|
218
|
+
#include <stdbool.h>
|
|
219
|
+
#include <unistd.h>
|
|
220
|
+
#include <pthread.h>
|
|
221
|
+
#include <sys/time.h>
|
|
222
|
+
#include "tc_iot.h"
|
|
223
|
+
#include "tc_iot_av.h"
|
|
224
|
+
|
|
225
|
+
static volatile int s_login_done = 0;
|
|
226
|
+
static tc_iot_error_e s_login_rc = TC_IOT_ERR_SUCCESS;
|
|
227
|
+
|
|
228
|
+
static tc_iot_av_channel_t *g_video_channel = NULL;
|
|
229
|
+
static tc_iot_av_channel_t *g_audio_channel = NULL;
|
|
230
|
+
static volatile bool g_pushing = false;
|
|
231
|
+
static pthread_t g_video_thread;
|
|
232
|
+
static pthread_t g_audio_thread;
|
|
233
|
+
|
|
234
|
+
static uint64_t current_time_ms(void) {
|
|
235
|
+
struct timeval tv;
|
|
236
|
+
gettimeofday(&tv, NULL);
|
|
237
|
+
return (uint64_t)tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// 登录回调:与快速接入一致
|
|
241
|
+
static void on_login(tc_iot_error_e error_code, const char *error_message) {
|
|
242
|
+
s_login_rc = error_code;
|
|
243
|
+
s_login_done = 1;
|
|
244
|
+
if (error_code != TC_IOT_ERR_SUCCESS) {
|
|
245
|
+
printf("[demo] login failed: %d, msg=%s\n", error_code,
|
|
246
|
+
error_message ? error_message : "");
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// 模拟视频采集:独立线程定时生成占位视频帧(首帧标记为 IDR)并推送。
|
|
251
|
+
// 实际接入时替换为真实摄像头采集与 H264/H265 编码逻辑。
|
|
252
|
+
static void *video_push_thread_func(void *arg) {
|
|
253
|
+
static uint8_t dummy_video[64] = {0};
|
|
254
|
+
bool first_frame = true;
|
|
255
|
+
|
|
256
|
+
while (g_pushing) {
|
|
257
|
+
if (g_video_channel) {
|
|
258
|
+
tc_iot_video_frame vframe;
|
|
259
|
+
memset(&vframe, 0, sizeof(vframe));
|
|
260
|
+
vframe.codec = TC_IOT_VIDEO_CODEC_H264;
|
|
261
|
+
vframe.type = first_frame ? TC_IOT_VIDEO_FRAME_TYPE_IDR
|
|
262
|
+
: TC_IOT_VIDEO_FRAME_TYPE_P;
|
|
263
|
+
vframe.rotation = TC_IOT_VIDEO_ROTATION_0;
|
|
264
|
+
vframe.width = 480;
|
|
265
|
+
vframe.height = 320;
|
|
266
|
+
vframe.data = dummy_video;
|
|
267
|
+
vframe.data_size = sizeof(dummy_video);
|
|
268
|
+
vframe.pts_ms = current_time_ms();
|
|
269
|
+
tc_iot_push_video_frame(g_video_channel, &vframe);
|
|
270
|
+
first_frame = false;
|
|
271
|
+
}
|
|
272
|
+
usleep(40 * 1000); // 模拟 25fps
|
|
273
|
+
}
|
|
274
|
+
return NULL;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// 模拟音频采集:独立线程定时生成占位音频帧并推送。
|
|
278
|
+
// 实际接入时替换为真实麦克风采集与 PCM/AAC 编码逻辑。
|
|
279
|
+
static void *audio_push_thread_func(void *arg) {
|
|
280
|
+
static uint8_t dummy_audio[320] = {0}; // 16kHz/mono/20ms 对应的 PCM 采样点数
|
|
281
|
+
|
|
282
|
+
while (g_pushing) {
|
|
283
|
+
if (g_audio_channel) {
|
|
284
|
+
tc_iot_audio_frame aframe;
|
|
285
|
+
memset(&aframe, 0, sizeof(aframe));
|
|
286
|
+
aframe.codec = TC_IOT_AUDIO_CODEC_PCM;
|
|
287
|
+
aframe.sample_rate = TC_IOT_AUDIO_SAMPLE_RATE_16000;
|
|
288
|
+
aframe.channels = TC_IOT_AUDIO_CHANNEL_MONO;
|
|
289
|
+
aframe.frame_duration_ms = 20;
|
|
290
|
+
aframe.data = dummy_audio;
|
|
291
|
+
aframe.data_size = sizeof(dummy_audio);
|
|
292
|
+
aframe.pts_ms = current_time_ms();
|
|
293
|
+
tc_iot_push_audio_frame(g_audio_channel, &aframe);
|
|
294
|
+
}
|
|
295
|
+
usleep(20 * 1000); // 20ms 一帧
|
|
296
|
+
}
|
|
297
|
+
return NULL;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// 根据通话媒体类型创建发送通道并启动推流线程
|
|
301
|
+
static void start_call_streams(tc_iot_media_content_e media_content) {
|
|
302
|
+
if (media_content == TC_IOT_MEDIA_CONTENT_VIDEO ||
|
|
303
|
+
media_content == TC_IOT_MEDIA_CONTENT_AUDIO_VIDEO) {
|
|
304
|
+
g_video_channel = tc_iot_create_video_channel(0, TC_IOT_VIDEO_QUALITY_SD);
|
|
305
|
+
}
|
|
306
|
+
if (media_content == TC_IOT_MEDIA_CONTENT_AUDIO ||
|
|
307
|
+
media_content == TC_IOT_MEDIA_CONTENT_AUDIO_VIDEO) {
|
|
308
|
+
g_audio_channel = tc_iot_create_audio_channel();
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (!g_pushing) {
|
|
312
|
+
g_pushing = true;
|
|
313
|
+
pthread_create(&g_video_thread, NULL, video_push_thread_func, NULL);
|
|
314
|
+
pthread_create(&g_audio_thread, NULL, audio_push_thread_func, NULL);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// 停止推流并销毁发送通道
|
|
319
|
+
static void stop_call_streams(void) {
|
|
320
|
+
if (g_pushing) {
|
|
321
|
+
g_pushing = false;
|
|
322
|
+
pthread_join(g_video_thread, NULL);
|
|
323
|
+
pthread_join(g_audio_thread, NULL);
|
|
324
|
+
}
|
|
325
|
+
if (g_video_channel) {
|
|
326
|
+
tc_iot_destroy_video_channel(g_video_channel);
|
|
327
|
+
g_video_channel = NULL;
|
|
328
|
+
}
|
|
329
|
+
if (g_audio_channel) {
|
|
330
|
+
tc_iot_destroy_audio_channel(g_audio_channel);
|
|
331
|
+
g_audio_channel = NULL;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
static void on_call_requested(const tc_iot_contact_s *contact, tc_iot_call_option_t option) {
|
|
336
|
+
printf("[demo] on_call_requested user_id=%s media=%d\n", contact->user_id, option.media_content);
|
|
337
|
+
|
|
338
|
+
tc_iot_error_e rc = tc_iot_av_accept(contact, NULL);
|
|
339
|
+
if (rc != TC_IOT_ERR_SUCCESS) {
|
|
340
|
+
printf("[demo] tc_iot_av_accept failed: %d\n", rc);
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
start_call_streams(option.media_content);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
static void on_call_timeout(const tc_iot_contact_s *contact) {
|
|
347
|
+
printf("[demo] on_call_timeout user_id=%s\n", contact->user_id);
|
|
348
|
+
stop_call_streams();
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
static void on_call_hangup(const tc_iot_contact_s *contact) {
|
|
352
|
+
printf("[demo] on_call_hangup user_id=%s\n", contact->user_id);
|
|
353
|
+
stop_call_streams();
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
int main(int argc, char **argv) {
|
|
357
|
+
if (argc < 7) {
|
|
358
|
+
printf("Usage: %s -p <product_id> -d <device_id> -s <device_secret>\n", argv[0]);
|
|
359
|
+
return 0;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const char *product_id = NULL;
|
|
363
|
+
const char *device_id = NULL;
|
|
364
|
+
const char *device_secret = NULL;
|
|
365
|
+
for (int i = 1; i < argc; i++) {
|
|
366
|
+
if (strcmp(argv[i], "-p") == 0 && i + 1 < argc) {
|
|
367
|
+
product_id = argv[++i];
|
|
368
|
+
} else if (strcmp(argv[i], "-d") == 0 && i + 1 < argc) {
|
|
369
|
+
device_id = argv[++i];
|
|
370
|
+
} else if (strcmp(argv[i], "-s") == 0 && i + 1 < argc) {
|
|
371
|
+
device_secret = argv[++i];
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
if (!product_id || !device_id || !device_secret) {
|
|
375
|
+
printf("device info error\n");
|
|
376
|
+
return 1;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// 初始化与登录:与快速接入一致
|
|
380
|
+
tc_iot_config_s config;
|
|
381
|
+
memset(&config, 0, sizeof(config));
|
|
382
|
+
config.storage_path = "./";
|
|
383
|
+
config.log_level = TC_IOT_LOG_LEVEL_INFO;
|
|
384
|
+
|
|
385
|
+
tc_iot_error_e rc = tc_iot_init(&config);
|
|
386
|
+
if (rc != TC_IOT_ERR_SUCCESS) {
|
|
387
|
+
printf("tc_iot_init failed: %d\n", rc);
|
|
388
|
+
return 1;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
tc_iot_device_info_s device_info;
|
|
392
|
+
device_info.product_id = product_id;
|
|
393
|
+
device_info.device_id = device_id;
|
|
394
|
+
device_info.device_secret = device_secret;
|
|
395
|
+
|
|
396
|
+
rc = tc_iot_login(&device_info, on_login);
|
|
397
|
+
if (rc != TC_IOT_ERR_SUCCESS) {
|
|
398
|
+
printf("tc_iot_login call failed: %d\n", rc);
|
|
399
|
+
tc_iot_deinit();
|
|
400
|
+
return 1;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
int waited_ms = 0;
|
|
404
|
+
while (!s_login_done && waited_ms < 5000) {
|
|
405
|
+
usleep(100 * 1000);
|
|
406
|
+
waited_ms += 100;
|
|
407
|
+
}
|
|
408
|
+
if (!s_login_done || s_login_rc != TC_IOT_ERR_SUCCESS) {
|
|
409
|
+
printf("login timeout or failed\n");
|
|
410
|
+
tc_iot_deinit();
|
|
411
|
+
return 1;
|
|
412
|
+
}
|
|
413
|
+
printf("[demo] login success\n");
|
|
414
|
+
|
|
415
|
+
// 注册通话事件回调(本文核心内容)
|
|
416
|
+
tc_iot_av_observer_s observer;
|
|
417
|
+
memset(&observer, 0, sizeof(observer));
|
|
418
|
+
observer.on_call_requested = on_call_requested;
|
|
419
|
+
observer.on_call_timeout = on_call_timeout;
|
|
420
|
+
observer.on_call_hangup = on_call_hangup;
|
|
421
|
+
|
|
422
|
+
rc = tc_iot_av_init(&observer);
|
|
423
|
+
if (rc != TC_IOT_ERR_SUCCESS) {
|
|
424
|
+
printf("tc_iot_av_init failed: %d\n", rc);
|
|
425
|
+
tc_iot_deinit();
|
|
426
|
+
return 1;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
printf("[demo] ready, waiting for incoming call from app (60s)...\n");
|
|
430
|
+
sleep(60);
|
|
431
|
+
|
|
432
|
+
// 释放资源
|
|
433
|
+
stop_call_streams();
|
|
434
|
+
tc_iot_av_deinit();
|
|
435
|
+
tc_iot_logout();
|
|
436
|
+
tc_iot_deinit();
|
|
437
|
+
printf("[demo] main exit\n");
|
|
438
|
+
return 0;
|
|
439
|
+
}
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
## 编译并运行
|
|
443
|
+
|
|
444
|
+
将上述代码覆盖到快速接入中已创建的项目 `main.c`,`CMakeLists.txt` 无需改动,重新编译并运行即可。
|
|
445
|
+
1. 重新编译。
|
|
446
|
+
|
|
447
|
+
``` bash
|
|
448
|
+
cmake --build build -j
|
|
449
|
+
```
|
|
450
|
+
2. 运行可执行文件,传入设备三元组。
|
|
451
|
+
|
|
452
|
+
``` bash
|
|
453
|
+
./build/iot_quickstart_demo -p YOUR_PRODUCT_ID -d YOUR_DEVICE_NAME -s 'YOUR_DEVICE_SECRET'
|
|
454
|
+
```
|
|
455
|
+
3. 通过 APP 对该设备发起语音或视频呼叫,观察设备端日志输出 `on_call_requested` 及后续推流日志;挂断后观察 `on_call_hangup` 日志,即代表通话链路验证成功。
|
|
456
|
+
|
|
457
|
+
## 常见问题
|
|
458
|
+
|
|
459
|
+
|现象|排查建议|
|
|
460
|
+
|---------|---------|
|
|
461
|
+
|APP 发起呼叫后,设备端未收到 `on_call_requested`。|确认设备已成功登录且 `tc_iot_av_init` 调用成功;确认 `on_call_requested` 已正确赋值(未被 `memset` 清零覆盖)。|
|
|
462
|
+
|`tc_iot_av_accept` 返回失败。|确认设备已成功登录;确认 `contact.user_id` 有效;确认当前没有其他通话正在进行。|
|
|
463
|
+
|通话已接通,但对端看不到画面或听不到声音。|确认接通后已根据 `media_content` 创建对应的发送通道并开始推流;确认视频首帧为 IDR 关键帧。|
|
|
464
|
+
|多次通话后设备资源占用持续增长。|检查 `on_call_hangup` / `on_call_timeout` 是否都正确停止了推流并销毁了发送通道,避免通道未释放导致的资源泄漏。|
|
|
465
|
+
|