瀏覽代碼

可以双向视频通话啦

liuzhenxing1118 5 月之前
父節點
當前提交
8251a67001
共有 100 個文件被更改,包括 2869 次插入9 次删除
  1. 二進制
      app/libs/agora-rtc-sdk-javadoc.jar
  2. 二進制
      app/libs/agora-rtc-sdk.jar
  3. 二進制
      app/libs/arm64-v8a/libagora-fdkaac.so
  4. 二進制
      app/libs/arm64-v8a/libagora-ffmpeg.so
  5. 二進制
      app/libs/arm64-v8a/libagora-rtc-sdk.so
  6. 二進制
      app/libs/arm64-v8a/libagora-soundtouch.so
  7. 二進制
      app/libs/arm64-v8a/libagora_ai_echo_cancellation_extension.so
  8. 二進制
      app/libs/arm64-v8a/libagora_ai_echo_cancellation_ll_extension.so
  9. 二進制
      app/libs/arm64-v8a/libagora_ai_noise_suppression_extension.so
  10. 二進制
      app/libs/arm64-v8a/libagora_ai_noise_suppression_ll_extension.so
  11. 二進制
      app/libs/arm64-v8a/libagora_audio_beauty_extension.so
  12. 二進制
      app/libs/arm64-v8a/libagora_clear_vision_extension.so
  13. 二進制
      app/libs/arm64-v8a/libagora_content_inspect_extension.so
  14. 二進制
      app/libs/arm64-v8a/libagora_face_capture_extension.so
  15. 二進制
      app/libs/arm64-v8a/libagora_face_detection_extension.so
  16. 二進制
      app/libs/arm64-v8a/libagora_lip_sync_extension.so
  17. 二進制
      app/libs/arm64-v8a/libagora_screen_capture_extension.so
  18. 二進制
      app/libs/arm64-v8a/libagora_segmentation_extension.so
  19. 二進制
      app/libs/arm64-v8a/libagora_spatial_audio_extension.so
  20. 二進制
      app/libs/arm64-v8a/libagora_video_av1_decoder_extension.so
  21. 二進制
      app/libs/arm64-v8a/libagora_video_av1_encoder_extension.so
  22. 二進制
      app/libs/arm64-v8a/libagora_video_decoder_extension.so
  23. 二進制
      app/libs/arm64-v8a/libagora_video_encoder_extension.so
  24. 二進制
      app/libs/arm64-v8a/libagora_video_quality_analyzer_extension.so
  25. 二進制
      app/libs/arm64-v8a/libaosl.so
  26. 二進制
      app/libs/arm64-v8a/libvideo_enc.so
  27. 二進制
      app/libs/armeabi-v7a/libagora-fdkaac.so
  28. 二進制
      app/libs/armeabi-v7a/libagora-ffmpeg.so
  29. 二進制
      app/libs/armeabi-v7a/libagora-rtc-sdk.so
  30. 二進制
      app/libs/armeabi-v7a/libagora-soundtouch.so
  31. 二進制
      app/libs/armeabi-v7a/libagora_ai_echo_cancellation_extension.so
  32. 二進制
      app/libs/armeabi-v7a/libagora_ai_echo_cancellation_ll_extension.so
  33. 二進制
      app/libs/armeabi-v7a/libagora_ai_noise_suppression_extension.so
  34. 二進制
      app/libs/armeabi-v7a/libagora_ai_noise_suppression_ll_extension.so
  35. 二進制
      app/libs/armeabi-v7a/libagora_audio_beauty_extension.so
  36. 二進制
      app/libs/armeabi-v7a/libagora_clear_vision_extension.so
  37. 二進制
      app/libs/armeabi-v7a/libagora_content_inspect_extension.so
  38. 二進制
      app/libs/armeabi-v7a/libagora_face_capture_extension.so
  39. 二進制
      app/libs/armeabi-v7a/libagora_face_detection_extension.so
  40. 二進制
      app/libs/armeabi-v7a/libagora_lip_sync_extension.so
  41. 二進制
      app/libs/armeabi-v7a/libagora_screen_capture_extension.so
  42. 二進制
      app/libs/armeabi-v7a/libagora_segmentation_extension.so
  43. 二進制
      app/libs/armeabi-v7a/libagora_spatial_audio_extension.so
  44. 二進制
      app/libs/armeabi-v7a/libagora_video_av1_decoder_extension.so
  45. 二進制
      app/libs/armeabi-v7a/libagora_video_av1_encoder_extension.so
  46. 二進制
      app/libs/armeabi-v7a/libagora_video_decoder_extension.so
  47. 二進制
      app/libs/armeabi-v7a/libagora_video_encoder_extension.so
  48. 二進制
      app/libs/armeabi-v7a/libagora_video_quality_analyzer_extension.so
  49. 二進制
      app/libs/armeabi-v7a/libaosl.so
  50. 二進制
      app/libs/armeabi-v7a/libvideo_enc.so
  51. 2 1
      app/libs/include/AgoraBase.h
  52. 7 0
      app/libs/include/AgoraMediaBase.h
  53. 4 0
      app/libs/include/AgoraMediaPlayerTypes.h
  54. 0 0
      app/libs/include/AgoraOptional.h
  55. 0 0
      app/libs/include/AgoraRefPtr.h
  56. 0 0
      app/libs/include/IAgoraH265Transcoder.h
  57. 0 0
      app/libs/include/IAgoraLog.h
  58. 0 0
      app/libs/include/IAgoraMediaComponentFactory.h
  59. 0 0
      app/libs/include/IAgoraMediaEngine.h
  60. 0 0
      app/libs/include/IAgoraMediaPlayer.h
  61. 0 0
      app/libs/include/IAgoraMediaPlayerSource.h
  62. 0 0
      app/libs/include/IAgoraMediaRecorder.h
  63. 0 0
      app/libs/include/IAgoraMediaStreamingSource.h
  64. 0 0
      app/libs/include/IAgoraMusicContentCenter.h
  65. 0 0
      app/libs/include/IAgoraParameter.h
  66. 0 0
      app/libs/include/IAgoraRhythmPlayer.h
  67. 10 8
      app/libs/include/IAgoraRtcEngine.h
  68. 0 0
      app/libs/include/IAgoraRtcEngineEx.h
  69. 0 0
      app/libs/include/IAgoraSpatialAudio.h
  70. 0 0
      app/libs/include/IAudioDeviceManager.h
  71. 25 0
      app/libs/include/rte_base/c/bridge.h
  72. 48 0
      app/libs/include/rte_base/c/c_error.h
  73. 671 0
      app/libs/include/rte_base/c/c_player.h
  74. 142 0
      app/libs/include/rte_base/c/c_rte.h
  75. 383 0
      app/libs/include/rte_base/c/channel.h
  76. 59 0
      app/libs/include/rte_base/c/common.h
  77. 40 0
      app/libs/include/rte_base/c/device/audio.h
  78. 97 0
      app/libs/include/rte_base/c/device/audio_device_manager.h
  79. 27 0
      app/libs/include/rte_base/c/device/device.h
  80. 37 0
      app/libs/include/rte_base/c/device/video.h
  81. 67 0
      app/libs/include/rte_base/c/device/video_device_manager.h
  82. 155 0
      app/libs/include/rte_base/c/handle.h
  83. 27 0
      app/libs/include/rte_base/c/info.h
  84. 48 0
      app/libs/include/rte_base/c/log.h
  85. 92 0
      app/libs/include/rte_base/c/metadata.h
  86. 20 0
      app/libs/include/rte_base/c/observer.h
  87. 112 0
      app/libs/include/rte_base/c/old.h
  88. 22 0
      app/libs/include/rte_base/c/options.h
  89. 36 0
      app/libs/include/rte_base/c/stream/cdn_stream.h
  90. 59 0
      app/libs/include/rte_base/c/stream/local_cdn_stream.h
  91. 33 0
      app/libs/include/rte_base/c/stream/local_realtime_stream.h
  92. 38 0
      app/libs/include/rte_base/c/stream/local_stream.h
  93. 37 0
      app/libs/include/rte_base/c/stream/realtime_stream.h
  94. 54 0
      app/libs/include/rte_base/c/stream/remote_cdn_stream.h
  95. 32 0
      app/libs/include/rte_base/c/stream/remote_realtime_stream.h
  96. 49 0
      app/libs/include/rte_base/c/stream/remote_stream.h
  97. 289 0
      app/libs/include/rte_base/c/stream/stream.h
  98. 34 0
      app/libs/include/rte_base/c/track/camera_video_track.h
  99. 94 0
      app/libs/include/rte_base/c/track/canvas.h
  100. 19 0
      app/libs/include/rte_base/c/track/layout.h

二進制
app/libs/agora-rtc-sdk-javadoc.jar


二進制
app/libs/agora-rtc-sdk.jar


二進制
app/libs/arm64-v8a/libagora-fdkaac.so


二進制
app/libs/arm64-v8a/libagora-ffmpeg.so


二進制
app/libs/arm64-v8a/libagora-rtc-sdk.so


二進制
app/libs/arm64-v8a/libagora-soundtouch.so


二進制
app/libs/arm64-v8a/libagora_ai_echo_cancellation_extension.so


二進制
app/libs/arm64-v8a/libagora_ai_echo_cancellation_ll_extension.so


二進制
app/libs/arm64-v8a/libagora_ai_noise_suppression_extension.so


二進制
app/libs/arm64-v8a/libagora_ai_noise_suppression_ll_extension.so


二進制
app/libs/arm64-v8a/libagora_audio_beauty_extension.so


二進制
app/libs/arm64-v8a/libagora_clear_vision_extension.so


二進制
app/libs/arm64-v8a/libagora_content_inspect_extension.so


二進制
app/libs/arm64-v8a/libagora_face_capture_extension.so


二進制
app/libs/arm64-v8a/libagora_face_detection_extension.so


二進制
app/libs/arm64-v8a/libagora_lip_sync_extension.so


二進制
app/libs/arm64-v8a/libagora_screen_capture_extension.so


二進制
app/libs/arm64-v8a/libagora_segmentation_extension.so


二進制
app/libs/arm64-v8a/libagora_spatial_audio_extension.so


二進制
app/libs/arm64-v8a/libagora_video_av1_decoder_extension.so


二進制
app/libs/arm64-v8a/libagora_video_av1_encoder_extension.so


二進制
app/libs/arm64-v8a/libagora_video_decoder_extension.so


二進制
app/libs/arm64-v8a/libagora_video_encoder_extension.so


二進制
app/libs/arm64-v8a/libagora_video_quality_analyzer_extension.so


二進制
app/libs/arm64-v8a/libaosl.so


二進制
app/libs/arm64-v8a/libvideo_enc.so


二進制
app/libs/armeabi-v7a/libagora-fdkaac.so


二進制
app/libs/armeabi-v7a/libagora-ffmpeg.so


二進制
app/libs/armeabi-v7a/libagora-rtc-sdk.so


二進制
app/libs/armeabi-v7a/libagora-soundtouch.so


二進制
app/libs/armeabi-v7a/libagora_ai_echo_cancellation_extension.so


二進制
app/libs/armeabi-v7a/libagora_ai_echo_cancellation_ll_extension.so


二進制
app/libs/armeabi-v7a/libagora_ai_noise_suppression_extension.so


二進制
app/libs/armeabi-v7a/libagora_ai_noise_suppression_ll_extension.so


二進制
app/libs/armeabi-v7a/libagora_audio_beauty_extension.so


二進制
app/libs/armeabi-v7a/libagora_clear_vision_extension.so


二進制
app/libs/armeabi-v7a/libagora_content_inspect_extension.so


二進制
app/libs/armeabi-v7a/libagora_face_capture_extension.so


二進制
app/libs/armeabi-v7a/libagora_face_detection_extension.so


二進制
app/libs/armeabi-v7a/libagora_lip_sync_extension.so


二進制
app/libs/armeabi-v7a/libagora_screen_capture_extension.so


二進制
app/libs/armeabi-v7a/libagora_segmentation_extension.so


二進制
app/libs/armeabi-v7a/libagora_spatial_audio_extension.so


二進制
app/libs/armeabi-v7a/libagora_video_av1_decoder_extension.so


二進制
app/libs/armeabi-v7a/libagora_video_av1_encoder_extension.so


二進制
app/libs/armeabi-v7a/libagora_video_decoder_extension.so


二進制
app/libs/armeabi-v7a/libagora_video_encoder_extension.so


二進制
app/libs/armeabi-v7a/libagora_video_quality_analyzer_extension.so


二進制
app/libs/armeabi-v7a/libaosl.so


二進制
app/libs/armeabi-v7a/libvideo_enc.so


+ 2 - 1
app/libs/high_level_api/include/AgoraBase.h → app/libs/include/AgoraBase.h

@@ -2706,6 +2706,7 @@ enum AUDIO_SCENARIO_TYPE {
   AUDIO_SCENARIO_MEETING = 8,
   /**
    * 9: AI Server.
+   * @technical preview 
    */
   AUDIO_SCENARIO_AI_SERVER = 9,
   /**
@@ -6537,7 +6538,7 @@ enum THREAD_PRIORITY_TYPE {
   CRITICAL = 5,
 };
 
-#if defined(__ANDROID__) || (defined(__APPLE__) && TARGET_OS_IOS)
+#if defined(__ANDROID__) || (defined(__APPLE__) && (TARGET_OS_IOS || (defined(TARGET_OS_VISION) && TARGET_OS_VISION)))
 
 /**
  * The video configuration for the shared screen stream.

+ 7 - 0
app/libs/high_level_api/include/AgoraMediaBase.h → app/libs/include/AgoraMediaBase.h

@@ -445,6 +445,10 @@ struct AudioPcmFrame {
   /** The channel number.
    */
   size_t num_channels_;
+  /**  @technical preview
+   * The audio track number. if mpk enableMultiAudioTrack, audio frame will have audio track number, eg 0 or 1.
+   */
+  int audio_track_number_;
   /** The number of bytes per sample.
    */
   rtc::BYTES_PER_SAMPLE bytes_per_sample;
@@ -468,6 +472,7 @@ struct AudioPcmFrame {
     bytes_per_sample = src.bytes_per_sample;
     num_channels_ = src.num_channels_;
     is_stereo_ = src.is_stereo_;
+    this->audio_track_number_ = src.audio_track_number_;
 
     size_t length = src.samples_per_channel_ * src.num_channels_;
     if (length > kMaxDataSizeSamples) {
@@ -484,6 +489,7 @@ struct AudioPcmFrame {
         samples_per_channel_(0),
         sample_rate_hz_(0),
         num_channels_(0),
+        audio_track_number_(0),
         bytes_per_sample(rtc::TWO_BYTES_PER_SAMPLE),
         is_stereo_(false) {
     memset(data_, 0, sizeof(data_));
@@ -494,6 +500,7 @@ struct AudioPcmFrame {
         samples_per_channel_(src.samples_per_channel_),
         sample_rate_hz_(src.sample_rate_hz_),
         num_channels_(src.num_channels_),
+        audio_track_number_(src.audio_track_number_),
         bytes_per_sample(src.bytes_per_sample),
         is_stereo_(src.is_stereo_) {
     size_t length = src.samples_per_channel_ * src.num_channels_;

+ 4 - 0
app/libs/high_level_api/include/AgoraMediaPlayerTypes.h → app/libs/include/AgoraMediaPlayerTypes.h

@@ -237,6 +237,10 @@ enum MEDIA_PLAYER_EVENT {
   /** Triggered when retrying to open media fails
    */
   PLAYER_EVENT_TRY_OPEN_FAILED = 18,
+  /** Triggered when an http redirect occurs
+   * @technical preview 
+   */
+  PLAYER_EVENT_HTTP_REDIRECT = 19,
 };
 
 /**

+ 0 - 0
app/libs/high_level_api/include/AgoraOptional.h → app/libs/include/AgoraOptional.h


+ 0 - 0
app/libs/high_level_api/include/AgoraRefPtr.h → app/libs/include/AgoraRefPtr.h


+ 0 - 0
app/libs/high_level_api/include/IAgoraH265Transcoder.h → app/libs/include/IAgoraH265Transcoder.h


+ 0 - 0
app/libs/high_level_api/include/IAgoraLog.h → app/libs/include/IAgoraLog.h


+ 0 - 0
app/libs/high_level_api/include/IAgoraMediaComponentFactory.h → app/libs/include/IAgoraMediaComponentFactory.h


+ 0 - 0
app/libs/high_level_api/include/IAgoraMediaEngine.h → app/libs/include/IAgoraMediaEngine.h


+ 0 - 0
app/libs/high_level_api/include/IAgoraMediaPlayer.h → app/libs/include/IAgoraMediaPlayer.h


+ 0 - 0
app/libs/high_level_api/include/IAgoraMediaPlayerSource.h → app/libs/include/IAgoraMediaPlayerSource.h


+ 0 - 0
app/libs/high_level_api/include/IAgoraMediaRecorder.h → app/libs/include/IAgoraMediaRecorder.h


+ 0 - 0
app/libs/high_level_api/include/IAgoraMediaStreamingSource.h → app/libs/include/IAgoraMediaStreamingSource.h


+ 0 - 0
app/libs/high_level_api/include/IAgoraMusicContentCenter.h → app/libs/include/IAgoraMusicContentCenter.h


+ 0 - 0
app/libs/high_level_api/include/IAgoraParameter.h → app/libs/include/IAgoraParameter.h


+ 0 - 0
app/libs/high_level_api/include/IAgoraRhythmPlayer.h → app/libs/include/IAgoraRhythmPlayer.h


+ 10 - 8
app/libs/high_level_api/include/IAgoraRtcEngine.h → app/libs/include/IAgoraRtcEngine.h

@@ -812,7 +812,7 @@ enum CLOUD_PROXY_TYPE {
 /** Camera capturer configuration.*/
 struct CameraCapturerConfiguration {
   /** Camera direction settings (for Android/iOS only). See: #CAMERA_DIRECTION. */
-#if defined(__ANDROID__) || (defined(__APPLE__) && TARGET_OS_IOS)
+#if defined(__ANDROID__) || (defined(__APPLE__) && (TARGET_OS_IOS || (defined(TARGET_OS_VISION) && TARGET_OS_VISION)))
   /**
    * The camera direction.
    */
@@ -2122,7 +2122,7 @@ class IRtcEngineEventHandler {
     (void)width;
     (void)height;
   }
-#if defined(__ANDROID__) || (defined(__APPLE__) && TARGET_OS_IOS)
+#if defined(__ANDROID__) || (defined(__APPLE__) && (TARGET_OS_IOS || (defined(TARGET_OS_VISION) && TARGET_OS_VISION)))
   /**
    * Reports the face detection result of the local user.
    *
@@ -4008,7 +4008,7 @@ class IRtcEngine : public agora::base::IEngineBase {
   */
   virtual int stopEchoTest() = 0;
 
-#if defined(__APPLE__) && TARGET_OS_IOS
+#if defined(__APPLE__) && (TARGET_OS_IOS || (defined(TARGET_OS_VISION) && TARGET_OS_VISION))
   /** Enables the SDK use AVCaptureMultiCamSession or AVCaptureSession. Applies to iOS 13.0+ only.
    * @param enabled Whether to enable multi-camera when capturing video:
    * - true: Enable multi-camera, and the SDK uses AVCaptureMultiCamSession.
@@ -6706,7 +6706,9 @@ class IRtcEngine : public agora::base::IEngineBase {
    */
   virtual int destroyCustomEncodedVideoTrack(video_track_id_t video_track_id) = 0;
 
-#if defined(__ANDROID__) || (defined(__APPLE__) && TARGET_OS_IOS)
+
+#if defined(__ANDROID__) || (defined(__APPLE__) && (TARGET_OS_IOS || (defined(TARGET_OS_VISION) && TARGET_OS_VISION)))
+
   /**
    * Switches between front and rear cameras.
    *
@@ -6982,7 +6984,7 @@ class IRtcEngine : public agora::base::IEngineBase {
    */
   virtual int setRouteInCommunicationMode(int route) = 0;
 
-#endif  // __ANDROID__ || (__APPLE__ && TARGET_OS_IOS)
+#endif  // __ANDROID__ || (__APPLE__ && (TARGET_OS_IOS || (defined(TARGET_OS_VISION) && TARGET_OS_VISION)))
 
 #if defined(__APPLE__)
   /**
@@ -7018,7 +7020,7 @@ class IRtcEngine : public agora::base::IEngineBase {
     */
   virtual IScreenCaptureSourceList* getScreenCaptureSources(const SIZE& thumbSize, const SIZE& iconSize, const bool includeScreen) = 0;
 #endif // _WIN32 || (__APPLE__ && !TARGET_OS_IPHONE && TARGET_OS_MAC)
-#if (defined(__APPLE__) && TARGET_OS_IOS)
+#if (defined(__APPLE__) && (TARGET_OS_IOS || (defined(TARGET_OS_VISION) && TARGET_OS_VISION)))
   /** Sets the operational permission of the SDK on the audio session.
    *
    * The SDK and the app can both configure the audio session by default. If
@@ -7044,7 +7046,7 @@ class IRtcEngine : public agora::base::IEngineBase {
    * - < 0: Failure.
    */
   virtual int setAudioSessionOperationRestriction(AUDIO_SESSION_OPERATION_RESTRICTION restriction) = 0;
-#endif // __APPLE__ && TARGET_OS_IOS
+#endif // __APPLE__ && (TARGET_OS_IOS || (defined(TARGET_OS_VISION) && TARGET_OS_VISION))
 
 #if defined(_WIN32) || (defined(__APPLE__) && !TARGET_OS_IPHONE && TARGET_OS_MAC)
 
@@ -7185,7 +7187,7 @@ class IRtcEngine : public agora::base::IEngineBase {
   virtual int updateScreenCaptureParameters(const ScreenCaptureParameters& captureParams) = 0;
 #endif // _WIN32 || (__APPLE__ && !TARGET_OS_IPHONE && TARGET_OS_MAC)
 
-#if defined(__ANDROID__) || (defined(__APPLE__) && TARGET_OS_IOS)
+#if defined(__ANDROID__) || (defined(__APPLE__) && (TARGET_OS_IOS || (defined(TARGET_OS_VISION) && TARGET_OS_VISION)))
   /**
    * Starts screen sharing.
    *

+ 0 - 0
app/libs/high_level_api/include/IAgoraRtcEngineEx.h → app/libs/include/IAgoraRtcEngineEx.h


+ 0 - 0
app/libs/high_level_api/include/IAgoraSpatialAudio.h → app/libs/include/IAgoraSpatialAudio.h


+ 0 - 0
app/libs/high_level_api/include/IAudioDeviceManager.h → app/libs/include/IAudioDeviceManager.h


+ 25 - 0
app/libs/include/rte_base/c/bridge.h

@@ -0,0 +1,25 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include "handle.h"
+#include "common.h"
+#include "./stream/stream.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+AGORA_RTE_API_C Rte RteGetFromBridge(RteError *err);
+
+AGORA_RTE_API_C void RteChannelAndStreamGetFromBridge(
+    Rte *rte, const char *channel_name, int uid, RteChannel *channel,
+    RteStream *stream, RteError *error);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 48 - 0
app/libs/include/rte_base/c/c_error.h

@@ -0,0 +1,48 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include <stdbool.h>
+
+#include "common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct RteString RteString;
+
+typedef enum RteErrorCode {
+  kRteOk,
+  kRteErrorDefault,
+  kRteErrorInvalidArgument,
+  kRteErrorInvalidOperation,
+  kRteErrorNetworkError,
+  kRteErrorAuthenticationFailed,
+  kRteErrorStreamNotFound,
+} RteErrorCode;
+
+typedef struct RteError {
+  RteErrorCode code;
+  RteString *message;
+} RteError;
+
+AGORA_RTE_API_C RteError *RteErrorCreate();
+AGORA_RTE_API_C bool RteErrorDestroy(RteError *err);
+
+AGORA_RTE_API_C bool RteErrorInit(RteError *err);
+AGORA_RTE_API_C bool RteErrorDeinit(RteError *err);
+
+AGORA_RTE_API_C bool RteErrorCopy(RteError *dest, RteError *src);
+
+AGORA_RTE_API_C bool RteErrorSet(RteError *err, RteErrorCode code,
+                                const char *fmt, ...);
+AGORA_RTE_API_C bool RteErrorOccurred(RteError *err);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 671 - 0
app/libs/include/rte_base/c/c_player.h

@@ -0,0 +1,671 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include <stddef.h>
+
+#include "handle.h"
+#include "observer.h"
+#include "utils/string.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct Rte Rte;
+typedef struct RteStream RteStream;
+typedef struct RtePlayerInternal RtePlayerInternal;
+
+/**
+ * Player states.
+ * When the player state changes, the state will be notified through the PlayerObserver::onStateChanged callback interface.
+ * @since v4.4.0
+ */
+typedef enum RtePlayerState {
+  /**
+   * 0: Idle state.
+   */
+  kRtePlayerStateIdle,
+  /**
+   * 1: Opening state. This state is notified after calling rte::Player::OpenWithUrl().
+   */
+  kRtePlayerStateOpening,
+  /**
+   * 2: Open completed state. This state is notified after successfully calling rte::Player::OpenWithUrl().
+   */
+  kRtePlayerStateOpenCompleted,
+  /**
+   * 3: Playing state. This state is notified when the url source is playing.
+   */
+  kRtePlayerStatePlaying,
+  /**
+   * 4: Paused state. This state is notified when playback is paused.
+   */
+  kRtePlayerStatePaused,
+  /**
+   * 5: Playback completed state. This state is notified when the url source playback completed.
+   */
+  kRtePlayerStatePlaybackCompleted,
+  /**
+   * 6: Stopped state. This state is entered after the user calls Player::stop.
+   */
+  kRtePlayerStateStopped,
+  /**
+   * 7: Failed state. This state is entered when an internal error occurs.
+   */
+  kRtePlayerStateFailed
+} RtePlayerState;
+
+/**
+ * Player events.
+ * When an event occurs, it will be notified through the PlayerObserver::onEvent callback interface.
+ * @since v4.4.0
+ */
+typedef enum RtePlayerEvent {
+  /**
+   * 0: Start seeking to a specified position for playback.
+   */
+  kRtePlayerEventSeekBegin = 0,
+  /**
+   * 1: Seeking completes.
+   */
+  kRtePlayerEventSeekComplete = 1,
+  /**
+   * 2: An error occurs when seeking to a new playback position.
+   */
+  kRtePlayerEventSeekError = 2,
+  /**
+   * 3: The currently buffered data is not enough to support playback.
+   */
+  kRtePlayerEventBufferLow = 3,
+  /**
+   * 4: The currently buffered data is just enough to support playback.
+   */
+  kRtePlayerEventBufferRecover = 4,
+  /**
+   * 5: Audio or video playback starts freezing.
+   */
+  kRtePlayerEventFreezeStart = 5,
+  /**
+   * 6: The audio or video playback resumes without freezing.
+   */
+  kRtePlayerEventFreezeStop = 6,
+  /**
+   * 7: One loop playback completed.
+   */
+  kRtePlayerEventOneLoopPlaybackCompleted = 7,
+  /**
+   * 8: URL authentication will expire.
+   */
+  kRtePlayerEventAuthenticationWillExpire = 8,
+  /**
+   * 9: When the fallback option is enabled, ABR revert to the audio-only layer due to poor network.
+   */
+  kRtePlayerEventAbrFallbackToAudioOnlyLayer = 9,
+  /**
+   * 10: ABR recovers from audio-only layer to video layer when fallback option is enabled.
+   */
+  kRtePlayerEventAbrRecoverFromAudioOnlyLayer = 10,
+  /**
+   * 11: Start switching to a new URL.
+   */
+  kRtePlayerEventSwitchBegin = 11,
+  /**
+   * 12: Switching to a new URL completes.
+   */
+  kRtePlayerEventSwitchComplete = 12,
+  /**
+   * 13: An error occurs when switching to a new URL.
+   */
+  kRtePlayerEventSwitchError = 13,
+  /**
+   * 14: The first frame of the video is displayed.
+   */
+  kRtePlayerEventFirstDisplayed = 14,
+  /**
+   * 15: The number of cached files reaches the maximum.
+   */
+  kRtePlayerEventReachCacheFileMaxCount = 15,
+  /**
+   * 16: The size of the cached file reaches the maximum.
+   */
+  kRtePlayerEventReachCacheFileMaxSize = 16,
+  /**
+   * 17: Start trying to open a new URL.
+   */
+  kRtePlayerEventTryOpenStart = 17,
+  /**
+   * 18: Trying to open a new URL succeeds.
+   */
+  kRtePlayerEventTryOpenSucceed = 18, 
+  /**
+   * 19: Trying to open a new URL fails.
+   */
+  kRtePlayerEventTryOpenFailed = 19,
+  /**
+   * 20: Audio track changed.
+   */
+  kRtePlayerEventAudioTrackChanged = 20,
+} RtePlayerEvent;
+
+/**
+ * ABR subscription layer.
+ * This enumeration can be used to set the value of the abr_subscription_layer query parameter in the rte URL. 
+ * It can also be used in the PlayerConfig::SetAbrSubscriptionLayer setting interface.
+ * @since v4.4.0
+ */
+typedef enum RteAbrSubscriptionLayer {
+  /**
+   * 0: High-quality video stream, this layer has the highest resolution and bitrate.
+   */
+  kRteAbrSubscriptionHigh = 0,
+  /**
+   * 1: Low-quality video stream, this layer has the lowest resolution and bitrate.
+   */
+  kRteAbrSubscriptionLow = 1,
+  /**
+   * 2: Layer1 video stream, this layer has lower resolution and bitrate than that of the high-quality video stream.
+   */
+  kRteAbrSubscriptionLayer1 = 2,
+  /**
+   * 3: Layer2 video stream, this layer has lower resolution and bitrate than layer1.
+   */
+  kRteAbrSubscriptionLayer2 = 3,
+  /**
+   * 4: Layer3 video stream, this layer has lower resolution and bitrate than layer2.
+   */
+  kRteAbrSubscriptionLayer3 = 4,
+  /**
+   * 5: Layer4 video stream, this layer has lower resolution and bitrate than layer3.
+   */
+  kRteAbrSubscriptionLayer4 = 5,
+  /**
+   * 6: Layer5 video stream, this layer has lower resolution and bitrate than layer4.
+   */
+  kRteAbrSubscriptionLayer5 = 6,
+  /**
+   * 7: Layer6 video stream, this layer has lower resolution and bitrate than layer5.
+   */
+  kRteAbrSubscriptionLayer6 = 7,
+} RteAbrSubscriptionLayer;
+
+
+/**
+ * ABR fallback layer.
+ * This enumeration can be used to set the value of the abr_fallback_layer query parameter in the rte URL. 
+ * It can also be used in the PlayerConfig::SetAbrFallbackLayer setting interface.
+ * @since v4.4.0
+ */
+typedef enum RteAbrFallbackLayer {
+  /**
+   * 0: When the network quality is poor, it will not revert to a lower resolution stream. 
+   * It may still revert to scalable video coding but will maintain the high-quality video resolution.
+   */
+  kRteAbrFallbackDisabled = 0,
+  /**
+   * 1: (Default) In a poor network environment, the receiver's SDK will receive the kRteAbrSubscriptionLow layer video stream.
+   */
+  kRteAbrFallbackLow = 1,
+  /**
+   * 2: In a poor network environment, the SDK may first receive the kRteAbrSubscriptionLow layer, 
+   * and if the relevant layer exists, it will revert to kRteAbrSubscriptionLayer1 to kRteAbrSubscriptionLayer6. 
+   * If the network environment is too poor to play video, the SDK will only receive audio.
+   */
+  kRteAbrFallbackAudioOnly = 2,
+  /**
+   * 3~8: If the receiving end sets the fallback option, the SDK will receive one of the layers from kRteAbrSubscriptionLayer1 to kRteAbrSubscriptionLayer6. 
+   * The lower boundary of the fallback video stream is determined by the configured fallback option.
+   */
+  kRteAbrFallbackLayer1 = 3,
+  kRteAbrFallbackLayer2 = 4,
+  kRteAbrFallbackLayer3 = 5,
+  kRteAbrFallbackLayer4 = 6,
+  kRteAbrFallbackLayer5 = 7,
+  kRteAbrFallbackLayer6 = 8,
+} RteAbrFallbackLayer;
+
+/**
+ * Player information.
+ * When playerInfo changes, it will be notified through the PlayerObserver::onPlayerInfoUpdated callback interface. 
+ * It can also be actively obtained through the Player::GetInfo interface.
+ * @since v4.4.0
+ */
+typedef struct RtePlayerInfo {
+  /** 
+   * Current player state
+   */
+  RtePlayerState state;
+  /** 
+   * Duration time of the current media source. This is valid when playing local media files or on-demand streams
+   */
+  size_t duration;
+  /** 
+   * Stream count. This field is only valid when opening a non-RTE URL.
+   */
+  size_t stream_count;
+  /** 
+   * Whether there is an audio stream. Indicates whether the url source contains the audio stream.
+   * - true: The url source contains the audio stream.
+   * - false: The url source does not contain the audio stream.
+   */
+  bool has_audio;
+  /** 
+   * Whether there is a video stream. Indicates whether the url source contains the video stream.
+   * - true: The url source contains the video stream.
+   * - false: The url source does not contain the video stream.
+   */
+  bool has_video;
+  /** 
+   * Whether the audio is muted. Indicates whether the receiver end stops receiving the audio stream.
+   * - true: Stop receiving the audio stream.
+   * - false: Continue receiving the audio stream.
+   */
+  bool is_audio_muted;
+  /** 
+   * Whether the video is muted. Indicates whether the receiver end stops receiving the video stream. This field is only valid when you open an RTE URL.
+   * - true: Stop receiving the video stream.
+   * - false: Continue receiving the video stream.
+   */
+  bool is_video_muted;
+  /** 
+   * Video resolution height
+   */
+  int video_height;
+  /** 
+   * Video resolution width
+   */
+  int video_width;
+  /** 
+   * The currently subscribed video layer. This field is only valid when you open an RTE URL.
+   */
+  RteAbrSubscriptionLayer abr_subscription_layer;
+  /** 
+   * Audio sample rate
+   */
+  int audio_sample_rate;
+  /** 
+   * Number of audio channels.
+   */
+  int audio_channels;
+  /** 
+   * Audio bits per sample. This field is only valid when opening a non-RTE URL.
+   */
+  int audio_bits_per_sample;
+  /**
+   * The URL being played.
+   */
+  RteString *current_url;
+
+} RtePlayerInfo;
+
+/**
+ * Player statistics.
+ * Can be actively obtained through the Player::GetStats interface.
+ * @since v4.4.0
+ */
+typedef struct RtePlayerStats {
+  /**
+   * Decoding frame rate
+   */
+  int video_decode_frame_rate;
+  /**
+   * Rendering frame rate
+   */
+  int video_render_frame_rate;
+  /**
+   * Video bitrate
+   */
+  int video_bitrate;
+
+  /**
+   * Audio bitrate
+   */
+  int audio_bitrate;
+} RtePlayerStats;
+
+typedef struct RteMediaTrackInfo {
+  void *placeholder;
+} RteMediaTrackInfo;
+
+typedef enum RtePlayerMetadataType {
+  kRtePlayerMetadataTypeSei
+} RtePlayerMetadataType;
+
+typedef enum RteAudioDualMonoMode {
+  RteAudioDualMonoStereo,
+  RteAudioDualMonoLeft,
+  RteAudioDualMonoRight,
+  RteAudioDualMonoMix,
+} RteAudioDualMonoMode;
+
+typedef struct RtePlayerInitialConfig {
+  bool enable_cache;
+  bool _enable_cache_is_set;
+
+  bool enable_multiple_audio_track;
+  bool _enable_multiple_audio_track_is_set;
+
+  bool is_agora_source;
+  bool _is_agora_source_is_set;
+
+  bool is_live_source;
+  bool _is_live_source_is_set;
+} RtePlayerInitialConfig;
+
+typedef struct RtePlayerConfig {
+  bool auto_play;
+  bool _auto_play_is_set;
+
+  int32_t speed;
+  bool _speed_is_set;
+
+  int32_t playout_audio_track_idx;
+  bool _playout_audio_track_idx_is_set;
+
+  int32_t publish_audio_track_idx;
+  bool _publish_audio_track_idx_is_set;
+
+  int32_t subtitle_track_idx;
+  bool _subtitle_track_idx_is_set;
+
+  int32_t external_subtitle_track_idx;
+  bool _external_subtitle_track_idx_is_set;
+
+  int32_t audio_pitch;
+  bool _audio_pitch_is_set;
+
+  int32_t playout_volume;
+  bool _playout_volume_is_set;
+
+  int32_t audio_playback_delay;
+  bool _audio_playback_delay_is_set;
+
+  RteAudioDualMonoMode audio_dual_mono_mode;
+  bool _audio_dual_mono_mode_is_set;
+
+  int32_t publish_volume;
+  bool _publish_volume_is_set;
+
+  int32_t loop_count;
+  bool _loop_count_is_set;
+
+  RteString *json_parameter;
+  bool _json_parameter_is_set;
+
+  // live player options
+  RteAbrSubscriptionLayer abr_subscription_layer;
+  bool _abr_subscription_layer_is_set;
+
+  RteAbrFallbackLayer abr_fallback_layer;
+  bool _abr_fallback_layer_is_set;
+
+} RtePlayerConfig;
+
+typedef struct RtePlayerCustomSourceProvider RtePlayerCustomSourceProvider;
+struct RtePlayerCustomSourceProvider {
+  void (*on_read_data)(RtePlayerCustomSourceProvider *self);
+  void (*on_seek)(RtePlayerCustomSourceProvider *self);
+};
+
+typedef struct RtePlayerObserver RtePlayerObserver;
+struct RtePlayerObserver {
+  RteBaseObserver base_observer;
+
+  void (*on_state_changed)(RtePlayerObserver *observer,
+                           RtePlayerState old_state, RtePlayerState new_state,
+                           RteError *err);
+  void (*on_position_changed)(RtePlayerObserver *observer, uint64_t curr_time,
+                              uint64_t utc_time);
+
+  void (*on_resolution_changed)(RtePlayerObserver *observer, int width, int height);
+
+  void (*on_event)(RtePlayerObserver *observer, RtePlayerEvent event);
+  void (*on_metadata)(RtePlayerObserver *observer, RtePlayerMetadataType type,
+                      const uint8_t *data, size_t length);
+
+  void (*on_player_info_updated)(RtePlayerObserver *observer,
+                                    const RtePlayerInfo *info);
+
+  void (*on_audio_volume_indication)(RtePlayerObserver *observer,
+                                         int32_t volume);
+};
+
+AGORA_RTE_API_C void RtePlayerInfoInit(RtePlayerInfo *info, RteError *err);
+AGORA_RTE_API_C void RtePlayerInfoCopy(RtePlayerInfo *dest, const RtePlayerInfo *src, RteError *err);
+AGORA_RTE_API_C void RtePlayerInfoDeinit(RtePlayerInfo *info, RteError *err);
+
+AGORA_RTE_API_C void RtePlayerStatsInit(RtePlayerStats *stats, RteError *err);
+AGORA_RTE_API_C void RtePlayerStatsDeinit(RtePlayerStats *stats, RteError *err);
+
+AGORA_RTE_API_C void RteMediaTrackInfoInit(RteMediaTrackInfo *info,
+                                          RteError *err);
+AGORA_RTE_API_C void RteMediaTrackInfoDeinit(RteMediaTrackInfo *info,
+                                            RteError *err);
+
+AGORA_RTE_API_C void RtePlayerInitialConfigInit(RtePlayerInitialConfig *config,
+                                               RteError *err);
+
+AGORA_RTE_API_C void RtePlayerInitialConfigDeinit(RtePlayerInitialConfig *config,
+                                                 RteError *err);
+
+AGORA_RTE_API_C void RtePlayerInitialConfigSetEnableCache(
+    RtePlayerInitialConfig *config, bool enable_cache, RteError *err);
+
+AGORA_RTE_API_C void RtePlayerInitialConfigGetEnableCache(
+    RtePlayerInitialConfig *config, bool *enable_cache, RteError *err);
+
+AGORA_RTE_API_C void RtePlayerInitialConfigSetEnableMultipleAudioTrack(
+    RtePlayerInitialConfig *config, bool enable_multiple_audio_track,
+    RteError *err);
+
+AGORA_RTE_API_C void RtePlayerInitialConfigGetEnableMultipleAudioTrack(
+    RtePlayerInitialConfig *config, bool *enable_multiple_audio_track,
+    RteError *err);
+
+AGORA_RTE_API_C void RtePlayerInitialConfigSetIsAgoraSource(
+    RtePlayerInitialConfig *config, bool is_agora_source, RteError *err);
+
+AGORA_RTE_API_C void RtePlayerInitialConfigGetIsAgoraSource(
+    RtePlayerInitialConfig *config, bool *is_agora_source, RteError *err);
+
+AGORA_RTE_API_C void RtePlayerInitialConfigSetIsLiveSource(
+    RtePlayerInitialConfig *config, bool is_agora_source, RteError *err);
+
+AGORA_RTE_API_C void RtePlayerInitialConfigGetIsLiveSource(
+    RtePlayerInitialConfig *config, bool *is_agora_source, RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigInit(RtePlayerConfig *config, RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigDeinit(RtePlayerConfig *config,
+                                          RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigCopy(RtePlayerConfig *dst,
+                                        const RtePlayerConfig *src,
+                                        RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigSetAutoPlay(RtePlayerConfig *config,
+                                               bool auto_play, RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigGetAutoPlay(RtePlayerConfig *config,
+                                               bool *auto_play, RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigSetPlaybackSpeed(RtePlayerConfig *config,
+                                                    int32_t speed,
+                                                    RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigGetPlaybackSpeed(RtePlayerConfig *config,
+                                                    int32_t *speed,
+                                                    RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigSetPlayoutAudioTrackIdx(
+    RtePlayerConfig *config, int32_t idx, RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigGetPlayoutAudioTrackIdx(
+    RtePlayerConfig *config, int32_t *idx, RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigSetPublishAudioTrackIdx(
+    RtePlayerConfig *config, int32_t idx, RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigGetPublishAudioTrackIdx(
+    RtePlayerConfig *config, int32_t *idx, RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigSetAudioTrackIdx(RtePlayerConfig *config,
+                                                    int32_t idx, RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigGetAudioTrackIdx(RtePlayerConfig *config,
+                                                    int32_t *idx,
+                                                    RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigSetSubtitleTrackIdx(RtePlayerConfig *config,
+                                                       int32_t idx,
+                                                       RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigGetSubtitleTrackIdx(RtePlayerConfig *config,
+                                                       int32_t *idx,
+                                                       RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigSetExternalSubtitleTrackIdx(
+    RtePlayerConfig *config, int32_t idx, RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigGetExternalSubtitleTrackIdx(
+    RtePlayerConfig *config, int32_t *idx, RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigSetAudioPitch(RtePlayerConfig *config,
+                                                 int32_t audio_pitch,
+                                                 RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigGetAudioPitch(RtePlayerConfig *config,
+                                                 int32_t *audio_pitch,
+                                                 RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigSetPlayoutVolume(RtePlayerConfig *config,
+                                                    int32_t volume,
+                                                    RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigGetPlayoutVolume(RtePlayerConfig *config,
+                                                    int32_t *volume,
+                                                    RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigSetAudioPlaybackDelay(
+    RtePlayerConfig *config, int32_t delay, RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigGetAudioPlaybackDelay(
+    RtePlayerConfig *config, int32_t *delay, RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigSetAudioDualMonoMode(
+    RtePlayerConfig *config, RteAudioDualMonoMode mode, RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigGetAudioDualMonoMode(
+    RtePlayerConfig *config, RteAudioDualMonoMode *mode, RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigSetPublishVolume(RtePlayerConfig *config,
+                                                    int32_t volume,
+                                                    RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigGetPublishVolume(RtePlayerConfig *config,
+                                                    int32_t *volume,
+                                                    RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigSetLoopCount(RtePlayerConfig *config,
+                                                int32_t loop_count,
+                                                RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigGetLoopCount(RtePlayerConfig *config,
+                                                int32_t *loop_count,
+                                                RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigSetJsonParameter(RtePlayerConfig *config,
+                                                    RteString *json_parameter,
+                                                    RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigGetJsonParameter(RtePlayerConfig *config,
+                                                    RteString *json_parameter,
+                                                    RteError *err);
+
+AGORA_RTE_API_C void RtePlayerConfigSetAbrSubscriptionLayer(RtePlayerConfig *config,
+                                                            RteAbrSubscriptionLayer abr_subscription_layer,
+                                                            RteError *err);     
+
+AGORA_RTE_API_C void RtePlayerConfigGetAbrSubscriptionLayer(RtePlayerConfig *config,
+                                                            RteAbrSubscriptionLayer *abr_subscription_layer,
+                                                            RteError *err); 
+
+AGORA_RTE_API_C void RtePlayerConfigSetAbrFallbackLayer(RtePlayerConfig *config,
+                                                        RteAbrFallbackLayer abr_fallback_layer,
+                                                        RteError *err); 
+
+AGORA_RTE_API_C void RtePlayerConfigGetAbrFallbackLayer(RtePlayerConfig *config,                                            
+                                                        RteAbrFallbackLayer *abr_fallback_layer,
+                                                        RteError *err);
+
+AGORA_RTE_API_C RtePlayer RtePlayerCreate(Rte *self, RtePlayerInitialConfig *config,
+                                         RteError *err);
+AGORA_RTE_API_C void RtePlayerDestroy(RtePlayer *self, RteError *err);
+
+AGORA_RTE_API_C bool RtePlayerPreloadWithUrl(RtePlayer *self, const char *url,
+                                            RteError *err);
+
+AGORA_RTE_API_C void RtePlayerOpenWithUrl(
+    RtePlayer *self, const char *url, uint64_t start_time,
+    void (*cb)(RtePlayer *self, void *cb_data, RteError *err), void *cb_data);
+
+AGORA_RTE_API_C void RtePlayerOpenWithCustomSourceProvider(
+    RtePlayer *self, RtePlayerCustomSourceProvider *provider,
+    uint64_t start_time,
+    void (*cb)(RtePlayer *self, void *cb_data, RteError *err), void *cb_data);
+
+AGORA_RTE_API_C void RtePlayerOpenWithStream(RtePlayer *self, RteStream *stream,
+                             void (*cb)(RtePlayer *self, void *cb_data,
+                                        RteError *err),
+                             void *cb_data);
+
+
+AGORA_RTE_API_C void RtePlayerGetStats(RtePlayer *self, void (*cb)(RtePlayer *player, RtePlayerStats *stats, void *cb_data, RteError *err), void *cb_data);
+
+AGORA_RTE_API_C bool RtePlayerSetCanvas(RtePlayer *self, RteCanvas *canvas, RteError *err);
+
+AGORA_RTE_API_C bool RtePlayerPlay(RtePlayer *self, RteError *err);
+AGORA_RTE_API_C bool RtePlayerStop(RtePlayer *self, RteError *err);
+AGORA_RTE_API_C bool RtePlayerPause(RtePlayer *self, RteError *err);
+AGORA_RTE_API_C bool RtePlayerSeek(RtePlayer *self, uint64_t new_time,
+                                  RteError *err);
+
+AGORA_RTE_API_C void RtePlayerSwitchWithUrl(RtePlayer *self, const char* url, bool sync_pts, void (*cb)(RtePlayer *self, void *cb_data, RteError *err), void *cb_data);
+                                  
+AGORA_RTE_API_C bool RtePlayerMuteAudio(RtePlayer *self, bool mute, RteError *err);
+AGORA_RTE_API_C bool RtePlayerMuteVideo(RtePlayer *self, bool mute, RteError *err);
+
+AGORA_RTE_API_C uint64_t RtePlayerGetPosition(RtePlayer *self, RteError *err);
+                                  
+AGORA_RTE_API_C bool RtePlayerGetInfo(RtePlayer *self, RtePlayerInfo *info, RteError *err);
+
+AGORA_RTE_API_C bool RtePlayerGetConfigs(RtePlayer *self,
+                                        RtePlayerConfig *config, RteError *err);
+AGORA_RTE_API_C bool RtePlayerSetConfigs(RtePlayer *self, RtePlayerConfig *config, RteError *err);
+
+
+AGORA_RTE_API_C bool RtePlayerRegisterObserver(
+    RtePlayer *self, RtePlayerObserver *observer, RteError *err);
+AGORA_RTE_API_C bool RtePlayerUnregisterObserver(RtePlayer *self,
+                                                RtePlayerObserver *observer,
+                                                RteError *err);
+
+AGORA_RTE_API_C RtePlayerObserver *RtePlayerObserverCreate(RteError *err);
+AGORA_RTE_API_C void RtePlayerObserverDestroy(RtePlayerObserver *observer,
+                                             RteError *err);
+AGORA_RTE_API_C RtePlayer
+RtePlayerObserverGetEventSrc(RtePlayerObserver *observer, RteError *err);
+
+AGORA_RTE_API_C RtePlayerCustomSourceProvider
+RtePlayerCustomSourceProviderCreate(Rte *self, RteError *err);
+
+AGORA_RTE_API_C void RtePlayerCustomSourceProviderDestroy(
+    RtePlayerCustomSourceProvider *self, RteError *err);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 142 - 0
app/libs/include/rte_base/c/c_rte.h

@@ -0,0 +1,142 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include <stdint.h>
+
+#include "common.h"
+#include "handle.h"
+#include "observer.h"
+#include "utils/string.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct RteRemoteStream RteRemoteStream;
+typedef struct RteLocalStream RteLocalStream;
+
+typedef struct RteInitialConfig {
+  void *placeholder;
+} RteInitialConfig;
+
+typedef struct RteConfig {
+  RteString *app_id;
+  bool has_app_id;
+
+  RteString *log_folder;
+  bool has_log_folder;
+
+  size_t log_file_size;
+  bool has_log_file_size;
+
+  int32_t area_code;
+  bool has_area_code;
+
+  RteString *cloud_proxy;
+  bool has_cloud_proxy;
+
+  RteString *json_parameter;
+  bool has_json_parameter;
+} RteConfig;
+
+typedef struct RteObserver {
+  RteBaseObserver base_observer;
+} RteObserver;
+
+AGORA_RTE_API_C void RteInitialConfigInit(RteInitialConfig *config, RteError *err);
+AGORA_RTE_API_C void RteInitialConfigDeinit(RteInitialConfig *config, RteError *err);
+
+AGORA_RTE_API_C void RteConfigInit(RteConfig *config, RteError *err);
+AGORA_RTE_API_C void RteConfigDeinit(RteConfig *config, RteError *err);
+AGORA_RTE_API_C void RteConfigCopy(RteConfig *dst, const RteConfig *src,
+                                  RteError *err);
+
+AGORA_RTE_API_C void RteConfigSetAppId(RteConfig *config, RteString *app_id,
+                                      RteError *err);
+AGORA_RTE_API_C void RteConfigGetAppId(RteConfig *config, RteString *app_id,
+                                      RteError *err);
+
+AGORA_RTE_API_C void RteConfigSetLogFolder(RteConfig *config,
+                                          RteString *log_folder, RteError *err);
+AGORA_RTE_API_C void RteConfigGetLogFolder(RteConfig *config,
+                                          RteString *log_folder, RteError *err);
+
+AGORA_RTE_API_C void RteConfigSetLogFileSize(RteConfig *config,
+                                            size_t log_file_size,
+                                            RteError *err);
+AGORA_RTE_API_C void RteConfigGetLogFileSize(RteConfig *config,
+                                            size_t *log_file_size,
+                                            RteError *err);
+
+AGORA_RTE_API_C void RteConfigSetAreaCode(RteConfig *config, int32_t area_code,
+                                         RteError *err);
+AGORA_RTE_API_C void RteConfigGetAreaCode(RteConfig *config, int32_t *area_code,
+                                         RteError *err);
+
+AGORA_RTE_API_C void RteConfigSetCloudProxy(RteConfig *config,
+                                           RteString *cloud_proxy,
+                                           RteError *err);
+AGORA_RTE_API_C void RteConfigGetCloudProxy(RteConfig *config,
+                                           RteString *cloud_proxy,
+                                           RteError *err);
+
+AGORA_RTE_API_C void RteConfigSetJsonParameter(RteConfig *config,
+                                              RteString *json_parameter,
+                                              RteError *err);
+AGORA_RTE_API_C void RteConfigGetJsonParameter(RteConfig *config,
+                                              RteString *json_parameter,
+                                              RteError *err);
+
+AGORA_RTE_API_C Rte RteCreate(RteInitialConfig *config, RteError *err);
+AGORA_RTE_API_C bool RteDestroy(Rte *self, RteError *err);
+
+AGORA_RTE_API_C bool RteInitMediaEngine(Rte *self,
+                                       void (*cb)(Rte *self, void *cb_data,
+                                                  RteError *err),
+                                       void *cb_data, RteError *err);
+
+AGORA_RTE_API_C bool RteGetConfigs(Rte *self, RteConfig *config, RteError *err);
+AGORA_RTE_API_C bool RteSetConfigs(Rte *self, RteConfig *config, RteError *err);
+
+AGORA_RTE_API_C void RteRelayStream(RteChannel *src_channel,
+                                   RteRemoteStream *src_stream,
+                                   RteChannel *dest_channel,
+                                   RteLocalStream *dest_stream,
+                                   void (*cb)(void *cb_data, RteError *err),
+                                   void *cb_data);
+
+AGORA_RTE_API_C void RteRegisterExtension(
+    Rte *self, RteString *provider_name, RteString *extension_name,
+    void (*cb)(Rte *self, RteString *provider_name, RteString *extension_name,
+               void *cb_data, RteError *err),
+    void *cb_data);
+
+AGORA_RTE_API_C void RteReportMessage(Rte *self, RteError *err, const char *fmt,
+                                     ...);
+
+AGORA_RTE_API_C bool RteRegisterObserver(Rte *self, RteObserver *observer, RteError *err);
+AGORA_RTE_API_C bool RteUnregisterObserver(Rte *self, RteObserver *observer,
+                                          RteError *err);
+
+AGORA_RTE_API_C void RteStartLastMileProbeTest(Rte *self,
+                                              void (*cb)(RteError *err));
+
+AGORA_RTE_API_C RteObserver *RteObserverCreate(RteError *err);
+
+AGORA_RTE_API_C void RteObserverDestroy(RteObserver *observer, RteError *err);
+
+AGORA_RTE_API_C Rte RteObserverGetEventSrc(RteObserver *observer, RteError *err);
+
+// @{
+// Internal use only.
+AGORA_RTE_API_C bool RteGlobalListIsEmpty();
+// @}
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 383 - 0
app/libs/include/rte_base/c/channel.h

@@ -0,0 +1,383 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include "handle.h"
+#include "common.h"
+#include "metadata.h"
+#include "observer.h"
+#include "utils/string.h"
+#include "track/track.h"
+#include "utils/buf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct RteTrack RteTrack;
+typedef struct RteUser RteUser;
+typedef struct RteStream RteStream;
+typedef struct Rte Rte;
+typedef struct RteLocalStream RteLocalStream;
+typedef struct RteLocalStreamInfo RteLocalStreamInfo;
+typedef struct RteRemoteStream RteRemoteStream;
+typedef struct RteRemoteStreamInfo RteRemoteStreamInfo;
+
+typedef enum RteChannelType {
+  kRteChannelTypeDefault,
+} RteChannelType;
+
+typedef enum RteLocalUserRtcRole {
+  kRteLocalUserRtcRoleBroadcaster,
+  kRteLocalUserRtcRoleAudience,
+} RteLocalUserRtcRole;
+
+typedef enum RteChannelConnectionState {
+  kRteChannelConnectionStateDisconnected,
+  kRteChannelConnectionStateDisconnecting,
+  kRteChannelConnectionStateConnecting,
+  kRteChannelConnectionStateConnected,
+  kRteChannelConnectionStateReconnecting,
+  kRteChannelConnectionStateFailed
+} RteChannelConnectionState;
+
+typedef enum RteChannelConnectionStateChangedReason {
+  kRteChannelConnectionStateChangedReasonConnecting,
+  kRteChannelConnectionStateChangedReasonSuccess,
+  kRteChannelConnectionStateChangedReasonInterrupted,
+  kRteChannelConnectionStateChangedReasonBannedByServer,
+  kRteChannelConnectionStateChangedReasonJoinFailed,
+  kRteChannelConnectionStateChangedReasonLeaveChannel,
+  kRteChannelConnectionStateChangedReasonInvalidAppId,
+  kRteChannelConnectionStateChangedReasonInvalidChannelName,
+  kRteChannelConnectionStateChangedReasonInvalidToken,
+  kRteChannelConnectionStateChangedReasonTokenExpired,
+  kRteChannelConnectionStateChangedReasonRejectedByServer,
+  kRteChannelConnectionStateChangedReasonSettingProxyServer,
+  kRteChannelConnectionStateChangedReasonRenewToken,
+  kRteChannelConnectionStateChangedReasonClientIpChanged,
+  kRteChannelConnectionStateChangedReasonKeepAliveTimeout,
+  kRteChannelConnectionStateChangedReasonRejoinSuccess,
+  kRteChannelConnectionStateChangedReasonLost,
+  kRteChannelConnectionStateChangedReasonEchoTest,
+  kRteChannelConnectionStateChangedReasonClientIpChangedByUser,
+  kRteChannelConnectionStateChangedReasonSameUidLogin,
+  kRteChannelConnectionStateChangedReasonTooManyBroadcasters,
+  kRteChannelConnectionStateChangedReasonLicenseValidationFailure,
+  kRteChannelConnectionStateChangedReasonCertificationVerifyFailure,
+  kRteChannelConnectionStateChangedReasonStreamChannelNotAvailable,
+  kRteChannelConnectionStateChangedReasonInconsistentAppId
+} RteChannelConnectionStateChangedReason;
+
+typedef enum RteTrackSubState {
+  kRteTrackSubStateSubscribing,
+  kRteTrackSubStateSubscribed,
+  kRteTrackSubStateNotSubscribed
+} RteTrackSubState;
+
+typedef enum RteTrackSubStateChangedReason {
+  kRteTrackSubStateChangedReasonRemotePublished,
+  kRteTrackSubStateChangedReasonRemoteUnpublished,
+  kRteTrackSubStateChangedReasonLocalSubscribed,
+  kRteTrackSubStateChangedReasonLocalUnsubscribed
+} RteTrackSubStateChangedReason;
+
+typedef enum RteTrackPubState {
+  kRteTrackPubStatePublishing,
+  kRteTrackPubStatePublished,
+  kRteTrackPubStateNotPublished
+} RteTrackPubState;
+
+typedef enum RteTrackPubStateChangedReason {
+  kRteTrackPubStateChangedReasonLocalPublished,
+  kRteTrackPubStateChangedReasonLocalUnpublished
+} RteTrackPubStateChangedReason;
+
+typedef struct RteStateItem {
+  RteString *key;
+  RteString *value;
+} RteStateItem;
+
+typedef struct RteState {
+  RteString *name;
+  RteStateItem *items;
+  size_t items_cnt;
+} RteState;
+
+typedef struct RteLock {
+  RteString *lock_name;
+  RteString *owner;
+  uint32_t ttl;
+} RteLock;
+
+typedef enum RteLockChangedEvent {
+  kRteLockChangedEventSet,
+  kRteLockChangedEventRemoved,
+  kRteLockChangedEventAcquired,
+  kRteLockChangedEventReleased,
+  kRteLockChangedEventExpired
+} RteLockChangedEvent;
+
+typedef struct RteChannelConfig {
+  RteString *channel_id;
+  bool has_channel_id;
+
+  RteChannelType type;
+  bool has_type;
+
+  bool is_user_id_integer_only;
+  bool has_is_user_id_integer_only;
+
+  bool is_user_id_same_as_stream_id;
+  bool has_is_useR_id_same_as_stream_id;
+
+  RteLocalUserRtcRole local_user_rtc_role;
+  bool has_local_user_rtc_role;
+
+  bool auto_subscribe_audio;
+  bool has_auto_subscribe_audio;
+
+  bool auto_subscribe_video;
+  bool has_auto_subscribe_video;
+
+  RteString *json_parameter;
+  bool has_json_parameter;
+} RteChannelConfig;
+
+typedef struct RteChannelObserver RteChannelObserver;
+struct RteChannelObserver {
+  RteBaseObserver base_observer;
+
+  void (*on_remote_stream_added)(RteChannelObserver *self,
+                                 RteRemoteStream *stream, RteRemoteUser *user);
+  void (*on_local_stream_info)(RteChannelObserver *self, RteLocalStream *stream,
+                               RteLocalStreamInfo *info);
+  void (*on_remote_stream_info)(RteChannelObserver *self,
+                                RteRemoteStream *stream,
+                                RteRemoteStreamInfo *info);
+  void (*on_channel_message_received)(RteChannelObserver *self,
+                                      RteString publisher, RteBuf *message);
+};
+
+typedef struct RteSubscribeOptions {
+  RteTrackMediaType track_media_type;
+  RteString *data_track_topic;
+} RteSubscribeOptions;
+
+AGORA_RTE_API_C void RteStateItemInit(RteStateItem *self, RteError *err);
+AGORA_RTE_API_C void RteStateItemDeinit(RteStateItem *self, RteError *err);
+// @}
+
+// @{
+// Config
+AGORA_RTE_API_C void RteChannelConfigInit(RteChannelConfig *config,
+                                         RteError *err);
+AGORA_RTE_API_C void RteChannelConfigDeinit(RteChannelConfig *config,
+                                           RteError *err);
+
+AGORA_RTE_API_C void RteChannelConfigSetChannelId(RteChannelConfig *self,
+                                                 const char *channel_id,
+                                                 RteError *err);
+AGORA_RTE_API_C void RteChannelConfigGetChannelId(RteChannelConfig *self,
+                                                 RteString *channel_id,
+                                                 RteError *err);
+
+AGORA_RTE_API_C void RteChannelConfigSetChannelType(RteChannelConfig *self,
+                                                   RteChannelType type,
+                                                   RteError *err);
+AGORA_RTE_API_C void RteChannelConfigGetChannelType(RteChannelConfig *self,
+                                                   RteChannelType *type,
+                                                   RteError *err);
+
+AGORA_RTE_API_C void RteChannelConfigSetIsUserIdIntegerOnly(
+    RteChannelConfig *self, bool is_user_id_integer_only, RteError *err);
+
+AGORA_RTE_API_C void RteChannelConfigGetIsUserIdIntegerOnly(
+    RteChannelConfig *self, bool *is_user_id_integer_only, RteError *err);
+
+AGORA_RTE_API_C void RteChannelConfigSetIsUserIdSameAsStreamId(
+    RteChannelConfig *self, bool is_user_id_same_as_stream_id, RteError *err);
+AGORA_RTE_API_C void RteChannelConfigGetIsUserIdSameAsStreamId(
+    RteChannelConfig *self, bool *is_user_id_same_as_stream_id, RteError *err);
+
+AGORA_RTE_API_C void RteChannelConfigSetLocalUserRtcRole(
+    RteChannelConfig *self, RteLocalUserRtcRole local_user_rtc_role,
+    RteError *err);
+AGORA_RTE_API_C void RteChannelConfigGetLocalUserRtcRole(
+    RteChannelConfig *self, RteLocalUserRtcRole *local_user_rtc_role,
+    RteError *err);
+
+AGORA_RTE_API_C void RteChannelConfigSetAutoSubscribeAudio(
+    RteChannelConfig *self, bool auto_subscribe_audio, RteError *err);
+AGORA_RTE_API_C void RteChannelConfigGetAutoSubscribeAudio(
+    RteChannelConfig *self, bool *auto_subscribe_audio, RteError *err);
+
+AGORA_RTE_API_C void RteChannelConfigSetAutoSubscribeVideo(
+    RteChannelConfig *self, bool auto_subscribe_video, RteError *err);
+AGORA_RTE_API_C void RteChannelConfigGetAutoSubscribeVideo(
+    RteChannelConfig *self, bool *auto_subscribe_video, RteError *err);
+
+AGORA_RTE_API_C void RteChannelConfigSetJsonParameter(RteChannelConfig *self,
+                                                     RteString *json_parameter,
+                                                     RteError *err);
+AGORA_RTE_API_C void RteChannelConfigGetJsonParameter(RteChannelConfig *self,
+                                                     RteString *json_parameter,
+                                                     RteError *err);
+// @}
+
+// @{
+// Observer
+AGORA_RTE_API_C RteChannelObserver *RteChannelObserverCreate(RteError *err);
+AGORA_RTE_API_C void RteChannelObserverDestroy(RteChannelObserver *self,
+                                              RteError *err);
+AGORA_RTE_API_C RteChannel
+RteChannelObserverGetEventSrc(RteChannelObserver *self, RteError *err);
+// @}
+
+AGORA_RTE_API_C RteChannel RteChannelCreate(Rte *self, RteChannelConfig *config,
+                                           RteError *err);
+AGORA_RTE_API_C void RteChannelDestroy(RteChannel *channel, RteError *err);
+
+AGORA_RTE_API_C void RteChannelGetConfigs(RteChannel *self,
+                                         RteChannelConfig *config,
+                                         RteError *err);
+AGORA_RTE_API_C void RteChannelSetConfigs(
+    RteChannel *self, RteChannelConfig *config,
+    void (*cb)(RteChannel *self, void *cb_data, RteError *err), void *cb_data);
+
+AGORA_RTE_API_C void RteChannelPublishStream(
+    RteChannel *self, RteLocalUser *user, RteLocalStream *stream,
+    void (*cb)(RteChannel *self, RteLocalStream *stream, void *cb_data,
+               RteError *err),
+    void *cb_data);
+AGORA_RTE_API_C void RteChannelUnpublishStream(
+    RteChannel *self, RteLocalStream *stream,
+    void (*cb)(RteChannel *self, RteLocalStream *stream, void *cb_data,
+               RteError *err),
+    void *cb_data);
+
+AGORA_RTE_API_C void RteChannelSubscribeTrack(
+    RteChannel *self, RteRemoteStream *stream, RteSubscribeOptions *options,
+    void (*cb)(RteChannel *self, RteTrack *track, void *cb_data, RteError *err),
+    void *cb_data);
+
+AGORA_RTE_API_C bool RteChannelRegisterObserver(
+    RteChannel *self, RteChannelObserver *observer, RteError *err);
+
+AGORA_RTE_API_C RteUser RteChannelGetLocalUser(RteChannel *self, RteError *err);
+AGORA_RTE_API_C size_t RteChannelGetRemoteUsersCount(RteChannel *self,
+                                                    RteError *err);
+AGORA_RTE_API_C void RteChannelGetRemoteUsers(RteChannel *self,
+                                             RteRemoteUser *remote_users,
+                                             size_t start_idx,
+                                             size_t remote_users_cnt,
+                                             RteError *err);
+
+AGORA_RTE_API_C void RteChannelJoin(RteChannel *self, RteLocalUser *user,
+                                   RteString *channel_token,
+                                   void (*cb)(RteChannel *self,
+                                              RteLocalUser *user, void *cb_data,
+                                              RteError *err),
+                                   void *cb_data);
+AGORA_RTE_API_C void RteChannelLeave(RteChannel *self, RteLocalUser *user,
+                                    void (*cb)(RteChannel *self,
+                                               RteLocalUser *user,
+                                               void *cb_data, RteError *err),
+                                    void *cb_data);
+
+AGORA_RTE_API_C void RteChannelRenewToken(
+    RteChannel *self, RteString *channel_token,
+    void (*cb)(RteChannel *self, void *cb_data, RteError *err), void *cb_data);
+
+AGORA_RTE_API_C void RteChannelPublishMessage(
+    RteChannel *self, RteBuf *message,
+    void (*cb)(RteChannel *self, void *cb_data, RteError *err), void *cb_data);
+AGORA_RTE_API_C void RteChannelSubscribeMessage(
+    RteChannel *self,
+    void (*cb)(RteChannel *self, void *cb_data, RteError *err), void *cb_data);
+AGORA_RTE_API_C void RteChannelUnsubscribeMessage(
+    RteChannel *self,
+    void (*cb)(RteChannel *self, void *cb_data, RteError *err), void *cb_data);
+
+AGORA_RTE_API_C void RteChannelGetMetadata(RteChannel *self,
+                                          void (*cb)(RteChannel *self,
+                                                     RteMetadata *items,
+                                                     void *cb_data,
+                                                     RteError *err),
+                                          void *cb_data);
+AGORA_RTE_API_C void RteChannelSubscribeMetadata(
+    RteChannel *self,
+    void (*cb)(RteChannel *self, RteMetadata *items, size_t items_cnt,
+               void *cb_data, RteError *err),
+    void *cb_data);
+AGORA_RTE_API_C void RteChannelUnsubscribeMetadata(
+    RteChannel *self,
+    void (*cb)(RteChannel *self, void *cb_data, RteError *err), void *cb_data);
+AGORA_RTE_API_C void RteChannelRemoveMetadata(
+    RteChannel *self, RteMetadata *items,
+    void (*cb)(RteChannel *self, void *cb_data, RteError *err), void *cb_data);
+
+AGORA_RTE_API_C void RteChannelGetUserState(
+    RteChannel *self, RteString *user_name,
+    void (*cb)(RteChannel *self, RteState *state, void *cb_data, RteError *err),
+    void *cb_data);
+AGORA_RTE_API_C void RteChannelSetUserState(
+    RteChannel *self, RteState *state,
+    void (*cb)(RteChannel *self, void *cb_data, RteError *err), void *cb_data);
+AGORA_RTE_API_C void RteChannelRemoveUserState(
+    RteChannel *self, RteString *key,
+    void (*cb)(RteChannel *self, void *cb_data, RteError *err), void *cb_data);
+AGORA_RTE_API_C void RteChannelSubscribeUserState(
+    RteChannel *self,
+    void (*cb)(RteChannel *self, void *cb_data, RteError *err), void *cb_data);
+AGORA_RTE_API_C void RteChannelUnsubscribeUserState(
+    RteChannel *self,
+    void (*cb)(RteChannel *self, void *cb_data, RteError *err), void *cb_data);
+
+AGORA_RTE_API_C void RteChannelSetLock(
+    RteChannel *self, RteString *lock_name, uint32_t ttl,
+    void (*cb)(RteChannel *self, void *cb_data, RteError *err), void *cb_data);
+AGORA_RTE_API_C void RteChannelRemoveLock(
+    RteChannel *self, RteString *lock_name,
+    void (*cb)(RteChannel *self, void *cb_data, RteError *err), void *cb_data);
+AGORA_RTE_API_C void RteChannelGetLocks(RteChannel *self,
+                                       void (*cb)(RteChannel *self,
+                                                  RteLock *locks,
+                                                  size_t locks_cnt,
+                                                  void *cb_data, RteError *err),
+                                       void *cb_data);
+AGORA_RTE_API_C void RteChannelSubscribeLocks(
+    RteChannel *self,
+    void (*cb)(RteChannel *self, void *cb_data, RteError *err), void *cb_data);
+AGORA_RTE_API_C void RteChannelUnsubscribeLocks(
+    RteChannel *self,
+    void (*cb)(RteChannel *self, void *cb_data, RteError *err), void *cb_data);
+AGORA_RTE_API_C void RteChannelAcquireLock(
+    RteChannel *self, RteString *lock_name, bool retry,
+    void (*cb)(RteChannel *self, RteString owner, void *cb_data, RteError *err),
+    void *cb_data);
+AGORA_RTE_API_C void RteChannelReleaseLock(
+    RteChannel *self, RteString *lock_name,
+    void (*cb)(RteChannel *self, void *cb_data, RteError *err), void *cb_data);
+
+AGORA_RTE_API_C size_t RteChannelGetLocalStreamsCount(RteChannel *self,
+                                                     RteError *err);
+AGORA_RTE_API_C void RteChannelGetLocalStreams(RteChannel *self,
+                                              RteLocalStream *streams,
+                                              size_t start_idx,
+                                              size_t streams_cnt,
+                                              RteError *err);
+
+AGORA_RTE_API_C size_t RteChannelGetRemoteStreamsCount(RteChannel *self,
+                                                      RteError *err);
+AGORA_RTE_API_C void RteChannelGetRemoteStreams(
+    RteChannel *self, RteRemoteUser *user, RteRemoteStream *streams,
+    size_t start_idx, size_t streams_cnt, RteError *err);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 59 - 0
app/libs/include/rte_base/c/common.h

@@ -0,0 +1,59 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#if defined(_WIN32)
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif  // !WIN32_LEAN_AND_MEAN
+#if defined(__aarch64__)
+#include <arm64intr.h>
+#endif
+#include <Windows.h>
+
+#ifdef AGORARTC_EXPORT
+#define AGORA_RTE_API_C __declspec(dllexport)
+#else
+#define AGORA_RTE_API_C __declspec(dllimport)
+#endif  // AGORARTC_EXPORT
+
+#define AGORA_CALL_C __cdecl
+
+#elif defined(__APPLE__)
+
+#include <TargetConditionals.h>
+
+#define AGORA_RTE_API_C __attribute__((visibility("default")))
+
+#elif defined(__ANDROID__) || defined(__linux__)
+
+#define AGORA_RTE_API_C __attribute__((visibility("default")))
+
+#else  // !_WIN32 && !__APPLE__ && !(__ANDROID__ || __linux__)
+
+#define AGORA_RTE_API_C
+
+#endif  // _WIN32
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef enum RteAreaCode {
+  kRteAreaCodeCn = 0x00000001,
+  kRteAreaCodeNa = 0x00000002,
+  kRteAreaCodeEu = 0x00000004,
+  kRteAreaCodeAs = 0x00000008,
+  kRteAreaCodeJp = 0x00000010,
+  kRteAreaCodeIn = 0x00000020,
+  kRteAreaCodeGlob = 0xFFFFFFFF
+} RteAreaCode;
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 40 - 0
app/libs/include/rte_base/c/device/audio.h

@@ -0,0 +1,40 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include "rte_base/c/device/device.h"
+#include "rte_base/c/handle.h"
+#include "rte_base/c/common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct RteAudioDevice RteAudioDevice;
+
+typedef enum RteAudioDeviceType {
+  kRteAudioDeviceTypePlayout,
+  kRteAudioDeviceTypeRecording,
+} RteAudioDeviceType;
+
+typedef struct RteAudioDeviceInfo {
+  RteDeviceInfo info;
+
+  RteAudioDeviceType type;
+} RteAudioDeviceInfo;
+
+AGORA_RTE_API_C void RteAudioDeviceInfoInit(RteAudioDeviceInfo *info,
+                                           RteError *err);
+AGORA_RTE_API_C void RteAudioDeviceInfoDeinit(RteAudioDeviceInfo *info,
+                                             RteError *err);
+
+AGORA_RTE_API_C void RteAudioDeviceGetInfo(RteAudioDevice *self,
+                                          RteAudioDeviceInfo *info,
+                                          RteError *err);
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 97 - 0
app/libs/include/rte_base/c/device/audio_device_manager.h

@@ -0,0 +1,97 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include <stddef.h>
+
+#include "rte_base/c/common.h"  
+#include "rte_base/c/c_error.h"
+#include "rte_base/c/device/audio.h"
+#include "rte_base/c/handle.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct RteAudioDeviceManagerConfig {
+    char placeholder;
+} RteAudioDeviceManagerConfig;
+
+typedef struct RteAudioDeviceManager {
+    char placeholder;
+} RteAudioDeviceManager;
+
+AGORA_RTE_API_C void RteAudioDeviceManagerConfigInit(
+    RteAudioDeviceManagerConfig *config, RteError *err);
+
+AGORA_RTE_API_C void RteAudioDeviceManagerConfigDeInit(
+    RteAudioDeviceManagerConfig *config, RteError *err);
+
+AGORA_RTE_API_C void RteAudioDeviceManagerConfigSetJsonParameter(
+    RteAudioDeviceManagerConfig *self, RteString *json_parameter,
+    RteError *err);
+
+AGORA_RTE_API_C void RteAudioDeviceManagerConfigGetJsonParameter(
+    RteAudioDeviceManagerConfig *config, RteString *json_parameter,
+    RteError *err);
+
+typedef void (*RteAudioDeviceManagerSetConfigsCallback)(
+    RteAudioDeviceManager *device_manager, RteAudioDeviceManagerConfig *config,
+    void *cb_data, RteError *err);
+
+AGORA_RTE_API_C RteAudioDeviceManager RteAudioDeviceManagerCreate(
+    Rte *rte, RteAudioDeviceManagerConfig *config, RteError *err);
+AGORA_RTE_API_C void RteAudioDeviceManagerDestroy(RteAudioDeviceManager *self,
+                                                 RteError *err);
+
+AGORA_RTE_API_C void RteAudioDeviceManagerGetConfigs(
+    RteAudioDeviceManager *self, RteAudioDeviceManagerConfig *config,
+    RteError *err);
+
+AGORA_RTE_API_C void RteAudioDeviceManagerSetConfigs(
+    RteAudioDeviceManager *self, RteAudioDeviceManagerConfig *config,
+    RteAudioDeviceManagerSetConfigsCallback cb, void *cb_data);
+
+typedef void (*RteAudioDeviceManagerEnumerateDevicesCallback)(
+    RteAudioDeviceManager *mgr, RteAudioDevice *devices, size_t devices_cnt,
+    void *cb_data, RteError *err);
+AGORA_RTE_API_C void RteAudioDeviceManagerEnumerateDevices(
+    RteAudioDeviceManager *self, RteAudioDeviceType type,
+    RteAudioDeviceManagerEnumerateDevicesCallback cb, void *cb_data);
+
+AGORA_RTE_API_C void RteAudioDeviceManagerSetVolume(RteAudioDeviceManager *self,
+                                                   RteAudioDeviceType type,
+                                                   uint32_t volume,
+                                                   RteError *err);
+
+AGORA_RTE_API_C void RteAudioDeviceManagerGetVolume(RteAudioDeviceManager *self,
+                                                   RteAudioDeviceType type,
+                                                   uint32_t *volume,
+                                                   RteError *err);
+
+typedef void (*RteAudioDeviceManagerSetCurrentDeviceCallback)(
+    RteAudioDeviceManager *self, RteAudioDeviceType type,
+    RteAudioDevice *device, void *cb_data, RteError *err);
+AGORA_RTE_API_C void RteAudioDeviceManagerSetCurrentDevice(
+    RteAudioDeviceManager *self, RteAudioDeviceType type,
+    RteAudioDevice *device, RteAudioDeviceManagerSetCurrentDeviceCallback cb,
+    void *cb_data);
+
+AGORA_RTE_API_C RteAudioDevice RteAudioDeviceManagerGetCurrentDevice(
+    RteAudioDeviceManager *self, RteAudioDeviceType type, RteError *err);
+
+#if defined(__ANDROID__) || defined(TARGET_OS_IOS) || defined(UNIT_TEST_MOCK)
+AGORA_RTE_API_C void RteAudioDeviceManagerUseSpeakerphoneByDefault(
+    RteAudioDeviceManager *self, bool enable, RteError *err);
+
+AGORA_RTE_API_C void RteAudioDeviceManagerUseSpeakerphone(
+    RteAudioDeviceManager *self, bool enable, RteError *err);
+#endif
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 27 - 0
app/libs/include/rte_base/c/device/device.h

@@ -0,0 +1,27 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include "rte_base/c/common.h"
+#include "rte_base/c/utils/string.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct RteDeviceInfo {
+  RteString *device_name;
+  RteString *device_id;
+} RteDeviceInfo;
+
+AGORA_RTE_API_C void RteDeviceInfoInit(RteDeviceInfo *info, RteError *err);
+
+AGORA_RTE_API_C void RteDeviceInfoDeinit(RteDeviceInfo *info, RteError *err);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 37 - 0
app/libs/include/rte_base/c/device/video.h

@@ -0,0 +1,37 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include "rte_base/c/device/device.h"
+#include "rte_base/c/common.h"
+#include "rte_base/c/handle.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef enum RteVideoDeviceType {
+  kRteVideoDeviceTypeCapturing
+} RteVideoDeviceType;
+
+typedef struct RteVideoDeviceInfo {
+  RteDeviceInfo base;
+
+  RteVideoDeviceType type;
+} RteVideoDeviceInfo;
+
+AGORA_RTE_API_C void RteVideoDeviceInfoInit(RteVideoDeviceInfo *info,
+                                           RteError *err);
+AGORA_RTE_API_C void RteVideoDeviceInfoDeinit(RteVideoDeviceInfo *info,
+                                             RteError *err);
+
+AGORA_RTE_API_C void RteVideoDeviceGetInfo(RteVideoDevice *self,
+                                          RteVideoDeviceInfo *info,
+                                          RteError *err);
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 67 - 0
app/libs/include/rte_base/c/device/video_device_manager.h

@@ -0,0 +1,67 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include <stddef.h>
+
+#include "rte_base/c/c_error.h"
+#include "rte_base/c/device/video.h"
+#include "rte_base/c/handle.h"
+#include "rte_base/c/common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct RteVideoDeviceManagerConfig {
+    char placeholder;
+} RteVideoDeviceManagerConfig;
+
+typedef struct RteVideoDeviceManager {
+    char placeholder;
+} RteVideoDeviceManager;
+
+AGORA_RTE_API_C void RteVideoDeviceManagerConfigInit(
+    RteVideoDeviceManagerConfig *config, RteError *err);
+AGORA_RTE_API_C void RteVideoDeviceManagerConfigDeinit(
+    RteVideoDeviceManagerConfig *config, RteError *err);
+AGORA_RTE_API_C void RteVideoDeviceManagerConfigSetJsonParameter(
+    RteVideoDeviceManagerConfig *config, RteString *json_parameter,
+    RteError *err);
+AGORA_RTE_API_C void RteVideoDeviceManagerConfigGetJsonParameter(
+    RteVideoDeviceManagerConfig *config, RteString *json_parameter,
+    RteError *err);
+
+typedef void (*RteVideoDeviceManagerSetConfigsCallback)(
+    RteVideoDeviceManager *device_manager, RteVideoDeviceManagerConfig *config,
+    void *cb_data, RteError *err);
+
+typedef void (*RteVideoDeviceManagerEnumerateDevicesCallback)(
+    RteVideoDeviceManager *device_manager, RteVideoDevice *devices,
+    size_t devices_cnt, void *cb_data, RteError *err);
+
+AGORA_RTE_API_C RteVideoDeviceManager RteVideoDeviceManagerCreate(
+    Rte *rte, RteVideoDeviceManagerConfig *config, RteError *err);
+AGORA_RTE_API_C void RteVideoDeviceManagerDestroy(RteVideoDeviceManager *self,
+                                                 RteError *err);
+AGORA_RTE_API_C void RteVideoDeviceManagerGetConfigs(
+    RteVideoDeviceManager *self, RteVideoDeviceManagerConfig *config,
+    RteError *err);
+AGORA_RTE_API_C void RteVideoDeviceManagerSetConfigs(
+    RteVideoDeviceManager *self, RteVideoDeviceManagerConfig *config,
+    RteVideoDeviceManagerSetConfigsCallback callback, void *cb_data);
+AGORA_RTE_API_C void RteVideoDeviceManagerEnumerateDevices(
+    RteVideoDeviceManager *self, RteVideoDeviceType type,
+    RteVideoDeviceManagerEnumerateDevicesCallback cb, void *cb_data);
+AGORA_RTE_API_C void RteVideoDeviceManagerSetCurrentDevice(
+    RteVideoDeviceManager *self, RteVideoDevice *device, RteError *err);
+AGORA_RTE_API_C RteVideoDevice RteVideoDeviceManagerGetCurrentDevice(
+    RteVideoDeviceManager *self, RteVideoDeviceType type, RteError *err);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 155 - 0
app/libs/include/rte_base/c/handle.h

@@ -0,0 +1,155 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include <stdbool.h>
+
+#include "utils/uuid.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct RteHandle {
+  RteUuid uuid;
+} RteHandle;
+
+typedef struct Rte {
+  RteHandle handle;
+} Rte;
+
+typedef struct RtePlayer {
+  RteHandle handle;
+} RtePlayer;
+
+typedef struct RteChannel {
+  RteHandle handle;
+} RteChannel;
+
+typedef struct RteUser {
+  RteHandle handle;
+} RteUser;
+
+typedef struct RteLocalUser {
+  RteHandle handle;
+} RteLocalUser;
+
+typedef struct RteRemoteUser {
+  RteHandle handle;
+} RteRemoteUser;
+
+typedef struct RteTrack {
+  RteHandle handle;
+} RteTrack;
+
+typedef struct RteLocalTrack {
+  RteHandle handle;
+} RteLocalTrack;
+
+typedef struct RteRemoteTrack {
+  RteHandle handle;
+} RteRemoteTrack;
+
+typedef struct RteVideoTrack {
+  RteHandle handle;
+} RteVideoTrack;
+
+typedef struct RteAudioTrack {
+  RteHandle handle;
+} RteAudioTrack;
+
+typedef struct RteDataTrack {
+  RteHandle handle;
+} RteDataTrack;
+
+typedef struct RteLocalVideoTrack {
+  RteHandle handle;
+} RteLocalVideoTrack;
+
+typedef struct RteRemoteVideoTrack {
+  RteHandle handle;
+} RteRemoteVideoTrack;
+
+typedef struct RteCameraVideoTrack {
+  RteHandle handle;
+} RteCameraVideoTrack;
+
+typedef struct RteMixedVideoTrack {
+  RteHandle handle;
+} RteMixedVideoTrack;
+
+typedef struct RteScreenVideoTrack {
+  RteHandle handle;
+} RteScreenVideoTrack;
+
+typedef struct RteLocalAudioTrack {
+  RteHandle handle;
+} RteLocalAudioTrack;
+
+typedef struct RteRemoteAudioTrack {
+  RteHandle handle;
+} RteRemoteAudioTrack;
+
+typedef struct RteMicAudioTrack {
+  RteHandle handle;
+} RteMicAudioTrack;
+
+typedef struct RteLocalDataTrack {
+  RteHandle handle;
+} RteLocalDataTrack;
+
+typedef struct RteRemoteDataTrack {
+  RteHandle handle;
+} RteRemoteDataTrack;
+
+typedef struct RteCanvas {
+  RteHandle handle;
+} RteCanvas;
+
+typedef struct RteAudioDevice {
+  RteHandle handle;
+} RteAudioDevice;
+
+typedef struct RteVideoDevice {
+  RteHandle handle;
+} RteVideoDevice;
+
+typedef struct RteRealTimeStream {
+  RteHandle handle;
+} RteRealTimeStream;
+
+typedef struct RteCdnStream {
+  RteHandle handle;
+} RteCdnStream;
+
+typedef struct RteLocalStream {
+  RteHandle handle;
+} RteLocalStream;
+
+typedef struct RteRemoteStream {
+  RteHandle handle;
+} RteRemoteStream;
+
+typedef struct RteLocalCdnStream {
+  RteHandle handle;
+} RteLocalCdnStream;
+
+typedef struct RteLocalRealTimeStream {
+  RteHandle handle;
+} RteLocalRealTimeStream;
+
+typedef struct RteRemoteCdnStream {
+  RteHandle handle;
+} RteRemoteCdnStream;
+
+typedef struct RteRemoteRealTimeStream {
+  RteHandle handle;
+} RteRemoteRealTimeStream;
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 27 - 0
app/libs/include/rte_base/c/info.h

@@ -0,0 +1,27 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include "c_error.h"
+#include "common.h"
+#include "handle.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct RteBaseInfo {
+  Rte rte;
+} RteBaseInfo;
+
+AGORA_RTE_API_C void RteBaseInfoInit(RteBaseInfo *info, RteError *err);
+
+AGORA_RTE_API_C void RteBaseInfoDeinit(RteBaseInfo *info, RteError *err);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 48 - 0
app/libs/include/rte_base/c/log.h

@@ -0,0 +1,48 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include <stddef.h>
+
+#include "common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct Rte Rte;
+typedef struct RteError RteError;
+
+typedef enum RteLogLevel {
+  kRteLogInfo,
+  kRteLogWarn,
+  kRteLogError,
+  kRteLogFatal,
+} RteLogLevel;
+
+AGORA_RTE_API_C void RteLog(Rte *self, RteLogLevel level, const char *func,
+                           const char *file, size_t line, RteError *err,
+                           const char *fmt, ...);
+
+#define RTE_LOG(level, ...) \
+  RteLog(NULL, level, __func__, __FILE__, __LINE__, NULL, __VA_ARGS__)
+
+#define RTE_LOGI(...) \
+  RteLog(NULL, kRteLogInfo, __func__, __FILE__, __LINE__, NULL, __VA_ARGS__)
+
+#define RTE_LOGW(...) \
+  RteLog(NULL, kRteLogWarn, __func__, __FILE__, __LINE__, NULL, __VA_ARGS__)
+
+#define RTE_LOGE(...) \
+  RteLog(NULL, kRteLogError, __func__, __FILE__, __LINE__, NULL, __VA_ARGS__)
+
+#define RTE_LOGF(...) \
+  RteLog(NULL, kRteLogFatal, __func__, __FILE__, __LINE__, NULL, __VA_ARGS__)
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 92 - 0
app/libs/include/rte_base/c/metadata.h

@@ -0,0 +1,92 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "c_error.h"
+#include "common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct RteMetadataConfig {
+  bool record_ts;
+  bool has_record_ts;
+
+  bool record_owner;
+  bool has_record_owner;
+
+  RteString *lock_name;
+  bool has_lock_name;
+
+  RteString *json_parameter;
+  bool has_json_parameter;
+} RteMetadataConfig;
+
+typedef struct RteMetadataItem {
+  RteString *key;
+  RteString *value;
+  RteString *author;
+  int64_t revision;
+  int64_t update_timestamp;
+} RteMetadataItem;
+
+typedef struct RteMetadata {
+  char placeholder;
+} RteMetadata;
+
+AGORA_RTE_API_C void RteMetadataConfigInit(RteMetadataConfig *config,
+                                          RteError *err);
+AGORA_RTE_API_C void RteMetadataConfigDeinit(RteMetadataConfig *config,
+                                            RteError *err);
+
+AGORA_RTE_API_C void RteMetadataConfigSetRecordTs(RteMetadataConfig *self,
+                                                 bool record_ts, RteError *err);
+AGORA_RTE_API_C void RteMetadataConfigGetRecordTs(RteMetadataConfig *self,
+                                                 bool *record_ts,
+                                                 RteError *err);
+
+AGORA_RTE_API_C void RteMetadataConfigSetRecordOwner(RteMetadataConfig *self,
+                                                    bool record_owner,
+                                                    RteError *err);
+AGORA_RTE_API_C void RteMetadataConfigGetRecordOwner(RteMetadataConfig *self,
+                                                    bool *record_owner,
+                                                    RteError *err);
+
+AGORA_RTE_API_C void RteMetadataConfigSetJsonParameter(RteMetadataConfig *self,
+                                                      RteString *json_parameter,
+                                                      RteError *err);
+AGORA_RTE_API_C void RteMetadataConfigGetJsonParameter(RteMetadataConfig *self,
+                                                      RteString *json_parameter,
+                                                      RteError *err);
+
+AGORA_RTE_API_C void RteMetadataItemInit(RteMetadataItem *self, RteError *err);
+AGORA_RTE_API_C void RteMetadataItemDeinit(RteMetadataItem *self, RteError *err);
+
+AGORA_RTE_API_C void RteMetadataInit(RteMetadata *self, RteError *err);
+AGORA_RTE_API_C void RteMetadataDeinit(RteMetadata *self, RteError *err);
+
+AGORA_RTE_API_C void RteMetadataSetRevision(RteMetadata *self, int64_t revision,
+                                           RteError *err);
+AGORA_RTE_API_C void RteMetadataGetRevision(RteMetadata *self, int64_t *revision,
+                                           RteError *err);
+
+AGORA_RTE_API_C void RteMetadataClear(RteMetadata *self, RteError *err);
+
+AGORA_RTE_API_C void RteMetadataAddItem(RteMetadata *self, RteMetadataItem *item,
+                                       RteError *err);
+AGORA_RTE_API_C size_t RteMetadataGetItems(RteMetadata *self,
+                                          RteMetadataItem *items,
+                                          size_t items_cnt, RteError *err);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 20 - 0
app/libs/include/rte_base/c/observer.h

@@ -0,0 +1,20 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct RteBaseObserver {
+  void *event_src;
+  void *me_in_target_lang;
+} RteBaseObserver;
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 112 - 0
app/libs/include/rte_base/c/old.h

@@ -0,0 +1,112 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include <string>
+
+#include "common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+struct RtcStats {};
+
+enum USER_OFFLINE_REASON_TYPE {};
+
+struct IRtcEngineEventHandler {
+  // When a local user successfully joins the channel, this callback is
+  // triggered.
+  virtual void onJoinChannelSuccess(const char *channel, uid_t uid,
+                                    int elapsed);
+
+  // When the local host successfully leaves the channel, this callback is
+  // triggered.
+  virtual void onLeaveChannel(const RtcStats &stat);
+
+  // When a remote host successfully joins the channel, this callback is
+  // triggered. Upon receiving this callback, you need to immediately call
+  // setupRemoteVideo to set up the remote host's view.
+  virtual void onUserJoined(uid_t uid, int elapsed);
+
+  // When a remote host leaves the channel or disconnects, this callback is
+  // triggered.
+  virtual void onUserOffline(uid_t uid, USER_OFFLINE_REASON_TYPE reason);
+};
+
+// 繼承 IRtcEngineEventHandler 類中的回呼與事件
+struct SampleEngineEventHandler : public IRtcEngineEventHandler {
+  SampleEngineEventHandler() = default;
+  virtual ~SampleEngineEventHandler() = default;
+
+  SampleEngineEventHandler(const SampleEngineEventHandler &) = delete;
+  SampleEngineEventHandler &operator=(const SampleEngineEventHandler &) =
+      delete;
+
+  SampleEngineEventHandler(SampleEngineEventHandler &&) = delete;
+  SampleEngineEventHandler &operator=(SampleEngineEventHandler &&) = delete;
+};
+
+struct RtcEngineContext {
+  IRtcEngineEventHandler *eventHandler;
+  std::string appId;
+};
+
+enum RENDER_MODE_TYPE {
+  RENDER_MODE_HIDDEN,
+  RENDER_MODE_FIT,
+};
+
+struct VideoCanvas {
+  uid_t uid;
+  void *view;
+  RENDER_MODE_TYPE renderMode;
+};
+
+enum VIDEO_CODEC_TYPE { VIDEO_CODEC_SOME };
+
+struct VideoEncoderConfiguration {
+  VIDEO_CODEC_TYPE codecType;
+};
+
+enum CHANNEL_PROFILE { CHANNEL_PROFILE_LIVE_BROADCASTING };
+
+enum CLIENT_ROLE_TYPE { CLIENT_ROLE_TYPE_BROADCASTER };
+
+struct ChannelMediaOptions {
+  CHANNEL_PROFILE channelProfile;
+  CLIENT_ROLE_TYPE clientRoleType;
+
+  bool autoSubscribeAudio;
+  bool autoSubscribeVideo;
+};
+
+struct IRtcEngine {
+  void initialize(RtcEngineContext &ctx);
+  void release(bool some_param);
+
+  void enableVideo();
+  void disableVideo();
+
+  void startPreview();
+  void stopPreview();
+
+  void setupLocalVideo(VideoCanvas &canvas);
+  void setupRemoteVideo(VideoCanvas &canvas);
+
+  void setVideoEncoderConfiguration(VideoEncoderConfiguration &config);
+
+  int joinChannel(const char *app_id, const char *channel_name, int uid,
+                  ChannelMediaOptions &options);
+  int leaveChannel();
+};
+
+AGORA_RTE_API_C IRtcEngine *createAgoraRtcEngine();
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 22 - 0
app/libs/include/rte_base/c/options.h

@@ -0,0 +1,22 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+/**
+ * @note This document lists functions that are for internal use and not part of
+ * the public API.
+ */
+
+namespace rte_api_internal {}  // namespace rte_api_internal
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 36 - 0
app/libs/include/rte_base/c/stream/cdn_stream.h

@@ -0,0 +1,36 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include "rte_base/c/c_error.h"
+#include "rte_base/c/common.h"
+#include "rte_base/c/stream/stream.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct RteCdnStreamConfig {
+  RteStreamConfig stream_config;
+} RteCdnStreamConfig;
+
+typedef struct RteCdnStreamStats {
+  RteStreamStats stream_stats;
+} RteCdnStreamStats;
+
+typedef struct RteCdnStreamInfo {
+  RteStreamInfo stream_info;
+} RteCdnStreamInfo;
+
+AGORA_RTE_API_C void RteCdnStreamStatsInit(RteCdnStreamStats *stats,
+                                          RteError *err);
+AGORA_RTE_API_C void RteCdnStreamStatsDeinit(RteCdnStreamStats *stats,
+                                            RteError *err);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 59 - 0
app/libs/include/rte_base/c/stream/local_cdn_stream.h

@@ -0,0 +1,59 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include "rte_base/c/common.h"
+#include "rte_base/c/stream/cdn_stream.h"
+#include "rte_base/c/stream/local_stream.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct RteUser RteUser;
+typedef struct RteTrack RteTrack;
+typedef struct Rte Rte;
+typedef struct RteChannel RteChannel;
+
+typedef struct RteLocalCdnStreamConfig {
+  RteCdnStreamConfig cdn_stream_config;
+  RteLocalStreamConfig local_stream_config;
+} RteLocalCdnStreamConfig;
+
+AGORA_RTE_API_C void RteLocalCdnStreamConfigInit(RteLocalCdnStreamConfig *config,
+                                                RteError *err);
+AGORA_RTE_API_C void RteLocalCdnStreamConfigDeinit(
+    RteLocalCdnStreamConfig *config, RteError *err);
+
+AGORA_RTE_API_C void RteLocalCdnStreamConfigSetUrl(RteLocalCdnStreamConfig *self,
+                                                  RteString *url,
+                                                  RteError *err);
+AGORA_RTE_API_C void RteLocalCdnStreamConfigGetUrl(RteLocalCdnStreamConfig *self,
+                                                  RteString *url,
+                                                  RteError *err);
+
+AGORA_RTE_API_C void RteLocalCdnStreamConfigSetJsonParameter(
+    RteLocalCdnStreamConfig *self, RteString *json_parameter, RteError *err);
+AGORA_RTE_API_C void RteLocalCdnStreamConfigGetJsonParameter(
+    RteLocalCdnStreamConfig *self, RteString *json_parameter, RteError *err);
+
+AGORA_RTE_API_C RteLocalCdnStream RteLocalCdnStreamCreate(
+    Rte *rte, RteLocalCdnStreamConfig *config, RteError *err);
+AGORA_RTE_API_C void RteLocalCdnStreamDestroy(RteLocalCdnStream *self,
+                                             RteError *err);
+
+AGORA_RTE_API_C void RteLocalCdnStreamGetConfigs(RteLocalCdnStream *self,
+                                                RteLocalCdnStreamConfig *config,
+                                                RteError *err);
+AGORA_RTE_API_C void RteLocalCdnStreamSetConfigs(
+    RteLocalCdnStream *self, RteLocalCdnStreamConfig *config,
+    void (*cb)(RteLocalCdnStream *stream, void *cb_data, RteError *err),
+    void *cb_data);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 33 - 0
app/libs/include/rte_base/c/stream/local_realtime_stream.h

@@ -0,0 +1,33 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include "rte_base/c/common.h"
+#include "rte_base/c/stream/local_stream.h"
+#include "rte_base/c/stream/realtime_stream.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct Rte Rte;
+typedef struct RteChannel RteChannel;
+
+typedef struct RteLocalRealTimeStreamConfig {
+  RteRealTimeStreamConfig realtime_stream_config;
+  RteLocalStreamConfig local_stream_config;
+} RteLocalRealTimeStreamConfig;
+
+AGORA_RTE_API_C RteLocalRealTimeStream RteLocalRealTimeStreamCreate(
+    Rte *rte, RteLocalRealTimeStreamConfig *config, RteError *err);
+
+AGORA_RTE_API_C void RteLocalRealTimeStreamDestroy(RteLocalRealTimeStream *self,
+                                                  RteError *err);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 38 - 0
app/libs/include/rte_base/c/stream/local_stream.h

@@ -0,0 +1,38 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include "rte_base/c/c_error.h"
+#include "rte_base/c/common.h"
+#include "rte_base/c/stream/stream.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct RteLocalStreamConfig {
+  RteStreamConfig stream_config;
+} RteLocalStreamConfig;
+
+typedef struct RteLocalStreamStats {
+  RteStreamStats stream_stats;
+} RteLocalStreamStats;
+
+typedef struct RteLocalStreamInfo {
+  RteStreamInfo stream_info;
+  bool has_subscribed;
+} RteLocalStreamInfo;
+
+AGORA_RTE_API_C void RteLocalStreamStatsInit(RteLocalStreamStats *stats,
+                                            RteError *err);
+
+AGORA_RTE_API_C void RteLocalStreamStatsDeinit(RteLocalStreamStats *stats,
+                                              RteError *err);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 37 - 0
app/libs/include/rte_base/c/stream/realtime_stream.h

@@ -0,0 +1,37 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include "rte_base/c/c_error.h"
+#include "rte_base/c/common.h"
+#include "rte_base/c/stream/stream.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct RteRealTimeStreamConfig {
+  RteStreamConfig stream_config;
+} RteRealTimeStreamConfig;
+
+typedef struct RteRealTimeStreamStats {
+  RteStreamStats stream_stats;
+} RteRealTimeStreamStats;
+
+typedef struct RteRealTimeStreamInfo {
+  RteStreamInfo stream_info;
+} RteRealTimeStreamInfo;
+
+AGORA_RTE_API_C void RteRealTimeStreamStatsInit(RteRealTimeStreamStats *stats,
+                                               RteError *err);
+
+AGORA_RTE_API_C void RteRealTimeStreamStatsDeinit(RteRealTimeStreamStats *stats,
+                                                 RteError *err);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 54 - 0
app/libs/include/rte_base/c/stream/remote_cdn_stream.h

@@ -0,0 +1,54 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include "rte_base/c/common.h"
+#include "rte_base/c/stream/cdn_stream.h"
+#include "rte_base/c/stream/remote_stream.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct RteUser RteUser;
+typedef struct RteTrack RteTrack;
+
+typedef struct RteRemoteCdnStreamConfig {
+  RteRemoteStreamConfig remote_stream_config;
+  RteCdnStreamConfig cdn_stream_config;
+} RteRemoteCdnStreamConfig;
+
+AGORA_RTE_API_C void RteRemoteCdnStreamConfigInit(
+    RteRemoteCdnStreamConfig *config, RteError *err);
+AGORA_RTE_API_C void RteRemoteCdnStreamConfigDeinit(
+    RteRemoteCdnStreamConfig *config, RteError *err);
+
+AGORA_RTE_API_C void RteRemoteCdnStreamConfigSetUrl(
+    RteRemoteCdnStreamConfig *self, RteString *url, RteError *err);
+AGORA_RTE_API_C void RteRemoteCdnStreamConfigGetUrl(
+    RteRemoteCdnStreamConfig *self, RteString *url, RteError *err);
+
+AGORA_RTE_API_C void RteRemoteCdnStreamConfigSetJsonParameter(
+    RteRemoteCdnStreamConfig *self, RteString *json_parameter, RteError *err);
+AGORA_RTE_API_C void RteRemoteCdnStreamConfigGetJsonParameter(
+    RteRemoteCdnStreamConfig *self, RteString *json_parameter, RteError *err);
+
+AGORA_RTE_API_C RteRemoteCdnStream RteRemoteCdnStreamCreate(Rte *self,
+                                                           RteError *err);
+AGORA_RTE_API_C void RteRemoteCdnStreamDestroy(RteRemoteCdnStream *self,
+                                              RteError *err);
+
+AGORA_RTE_API_C void RteRemoteCdnStreamGetConfigs(
+    RteRemoteCdnStream *self, RteRemoteCdnStreamConfig *config, RteError *err);
+AGORA_RTE_API_C void RteRemoteCdnStreamSetConfigs(
+    RteRemoteCdnStream *self, RteRemoteCdnStreamConfig *config,
+    void (*cb)(RteRemoteCdnStream *stream, void *cb_data, RteError *err),
+    void *cb_data);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 32 - 0
app/libs/include/rte_base/c/stream/remote_realtime_stream.h

@@ -0,0 +1,32 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include "rte_base/c/common.h"
+#include "rte_base/c/stream/realtime_stream.h"
+#include "rte_base/c/stream/remote_stream.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct Rte Rte;
+typedef struct RteChannel RteChannel;
+
+typedef struct RteRemoteRealTimeStreamConfig {
+  RteRemoteStreamConfig remote_stream_config;
+  RteRealTimeStreamConfig realtime_stream_config;
+} RteRemoteRealTimeStreamConfig;
+
+AGORA_RTE_API_C RteRemoteRealTimeStream RteRemoteRealTimeStreamCreate(
+    Rte *rte, RteRemoteRealTimeStreamConfig *config, RteError *err);
+AGORA_RTE_API_C void RteRemoteRealTimeStreamDestroy(
+    RteRemoteRealTimeStream *self, RteError *err);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 49 - 0
app/libs/include/rte_base/c/stream/remote_stream.h

@@ -0,0 +1,49 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include <stddef.h>
+
+#include "rte_base/c/c_error.h"
+#include "rte_base/c/common.h"
+#include "rte_base/c/stream/stream.h"
+#include "rte_base/c/track/track.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct RteRemoteStreamConfig {
+  RteStreamConfig stream_config;
+} RteRemoteStreamConfig;
+
+typedef struct RteRemoteStreamStats {
+  RteStreamStats stream_stats;
+} RteRemoteStreamStats;
+
+typedef struct RteRemoteStreamInfo {
+  RteStreamInfo stream_info;
+
+  bool has_audio;
+  bool has_video;
+  bool has_data;
+  RteTrackSrc audio_track_src;
+  RteTrackSrc video_track_src;
+  RteTrackSrc audio_track_src_original;
+  RteTrackSrc video_track_src_original;
+  RteString *data_track_topics;
+  size_t data_track_topic_cnt;
+} RteRemoteStreamInfo;
+
+AGORA_RTE_API_C void RteRemoteStreamStatsInit(RteRemoteStreamStats *stats,
+                                             RteError *err);
+AGORA_RTE_API_C void RteRemoteStreamStatsDeinit(RteRemoteStreamStats *stats,
+                                               RteError *err);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 289 - 0
app/libs/include/rte_base/c/stream/stream.h

@@ -0,0 +1,289 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include <stdbool.h>
+
+#include "rte_base/c/c_error.h"
+#include "rte_base/c/handle.h"
+#include "rte_base/c/observer.h"
+#include "rte_base/c/common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct RteChannel RteChannel;
+typedef struct Rte Rte;
+typedef struct RteStream RteStream;
+
+typedef struct RteStreamObserver RteStreamObserver;
+struct RteStreamObserver {
+  RteBaseObserver base_observer;
+};
+
+typedef enum RteStreamType {
+  kRteStreamTypeRealTime,
+  kRteStreamTypeCdn,
+} RteStreamType;
+
+typedef enum RteEncryptionMode {
+  kRteEncryptionModeAes128Xts,
+  kRteEncryptionModeAes128Ecb,
+  kRteEncryptionModeAes128Gcm,
+  kRteEncryptionModeAes128Gcm2,
+  kRteEncryptionModeAes256Xts,
+  kRteEncryptionModeAes256Gcm,
+  kRteEncryptionModeAes256Gcm2,
+  kRteEncryptionModeSm4128Ecb,
+} RteEncryptionMode;
+
+typedef enum RteAudioEncoderProfile {
+  kRteAudioEncoderProfileDefault,
+  kRteAudioEncoderProfileStdSpeech,
+  kRteAudioEncoderProfileStdMusic,
+  kRteAudioEncoderProfileStdStereoMusic,
+  kRteAudioEncoderProfileHighQualityMusic,
+  kRteAudioEncoderProfileHighQualityStereoMusic,
+  kRteAudioEncoderProfileIot,
+} RteAudioEncoderProfile;
+
+typedef enum RteOrientationMode {
+  kRteOrientationModeAdaptive,
+  kRteOrientationModeFixedLandscape,
+  kRteOrientationModeFixedPortrait,
+} RteOrientationMode;
+
+typedef enum RteVideoDegradationPreference {
+  kRteVideoDegradationPreferenceMaintainFramerate,
+  kRteVideoDegradationPreferenceMaintainBalanced,
+  kRteVideoDegradationPreferenceMaintainResolution,
+  kRteVideoDegradationPreferenceDisabled,
+} RteVideoDegradationPreference;
+
+typedef enum RteVideoMirrorMode {
+  kRteVideoMirrorModeAuto,
+  kRteVideoMirrorModeEnabled,
+  kRteVideoMirrorModeDisabled,
+} RteVideoMirrorMode;
+
+typedef struct RteStreamConfig {
+  RteStreamType type;
+  bool has_type;
+
+  RteString *stream_id;
+  bool has_stream_id;
+
+  RteEncryptionMode encryption_mode;
+  bool has_encryption_mode;
+
+  RteString *encryption_key;
+  bool has_encryption_key;
+
+  uint8_t encryption_kdf_salt[32];
+  bool has_encryption_kdf_salt;
+
+  RteAudioEncoderProfile audio_encoder_profile;
+  bool has_audio_encoder_profile;
+
+  uint32_t width;
+  bool has_width;
+
+  uint32_t height;
+  bool has_height;
+
+  uint32_t frame_rate;
+  bool has_frame_rate;
+
+  uint32_t min_bitrate;
+  bool has_min_bitrate;
+
+  RteOrientationMode orientation_mode;
+  bool has_orientation_mode;
+
+  RteVideoDegradationPreference degradation_preference;
+  bool has_degradation_preference;
+
+  RteVideoMirrorMode mirror_mode;
+  bool has_mirror_mode;
+
+  bool che_hw_decoding;
+  bool has_che_hw_decoding;
+
+  RteString *json_parameter;
+  bool has_json_parameter;
+} RteStreamConfig;
+
+typedef struct RteStreamStats {
+  int placeholder;
+} RteStreamStats;
+
+typedef struct RteStreamInfo {
+  RteChannel channel;
+  Rte rte;
+} RteStreamInfo;
+
+typedef struct RteStream {
+  RteHandle handle;
+} RteStream;
+
+// @{
+// Observer
+AGORA_RTE_API_C RteStreamObserver *RteStreamObserverCreate(RteError *err);
+AGORA_RTE_API_C void RteStreamObserverDestroy(RteStreamObserver *observer,
+                                             RteError *err);
+// @}
+
+// @{
+// Config
+AGORA_RTE_API_C void RteStreamConfigInit(RteStreamConfig *config, RteError *err);
+AGORA_RTE_API_C void RteStreamConfigDeinit(RteStreamConfig *config,
+                                          RteError *err);
+
+AGORA_RTE_API_C void RteStreamConfigSetChannel(RteStreamConfig *self,
+                                              RteChannel *channel,
+                                              RteError *err);
+
+AGORA_RTE_API_C void RteStreamConfigSetStreamType(RteStreamConfig *self,
+                                                 RteStreamType type,
+                                                 RteError *err);
+AGORA_RTE_API_C void RteStreamConfigGetStreamType(RteStreamConfig *self,
+                                                 RteStreamType *type,
+                                                 RteError *err);
+
+AGORA_RTE_API_C void RteStreamConfigSetStreamId(RteStreamConfig *self,
+                                               RteString *stream_id,
+                                               RteError *err);
+AGORA_RTE_API_C void RteStreamConfigGetStreamId(RteStreamConfig *self,
+                                               RteString *stream_id,
+                                               RteError *err);
+
+AGORA_RTE_API_C void RteStreamConfigSetEncryptionMode(RteStreamConfig *self,
+                                                     RteEncryptionMode mode,
+                                                     RteError *err);
+AGORA_RTE_API_C void RteStreamConfigGetEncryptionMode(RteStreamConfig *self,
+                                                     RteEncryptionMode *mode,
+                                                     RteError *err);
+
+AGORA_RTE_API_C void RteStreamConfigSetEncryptionKey(RteStreamConfig *self,
+                                                    RteString *encryption_key,
+                                                    RteError *err);
+AGORA_RTE_API_C void RteStreamConfigGetEncryptionKey(RteStreamConfig *self,
+                                                    RteString *encryption_key,
+                                                    RteError *err);
+
+AGORA_RTE_API_C void RteStreamConfigSetEncryptionKdfSalt(
+    RteStreamConfig *self, uint8_t *encryption_kdf_salt, RteError *err);
+AGORA_RTE_API_C void RteStreamConfigGetEncryptionKdfSalt(
+    RteStreamConfig *self, uint8_t *encryption_kdf_salt, RteError *err);
+
+AGORA_RTE_API_C void RteStreamConfigSetAudioEncoderProfile(
+    RteStreamConfig *self, RteAudioEncoderProfile profile, RteError *err);
+AGORA_RTE_API_C void RteStreamConfigGetAudioEncoderProfile(
+    RteStreamConfig *self, RteAudioEncoderProfile *profile, RteError *err);
+
+AGORA_RTE_API_C void RteStreamConfigSetWidth(RteStreamConfig *self,
+                                            uint32_t width, RteError *err);
+AGORA_RTE_API_C void RteStreamConfigGetWidth(RteStreamConfig *self,
+                                            uint32_t *width, RteError *err);
+AGORA_RTE_API_C void RteStreamConfigSetHeight(RteStreamConfig *self,
+                                             uint32_t height, RteError *err);
+AGORA_RTE_API_C void RteStreamConfigGetHeight(RteStreamConfig *self,
+                                             uint32_t *height, RteError *err);
+
+AGORA_RTE_API_C void RteStreamConfigSetFrameRate(RteStreamConfig *self,
+                                                uint32_t frame_rate,
+                                                RteError *err);
+AGORA_RTE_API_C void RteStreamConfigGetFrameRate(RteStreamConfig *self,
+                                                uint32_t *frame_rate,
+                                                RteError *err);
+
+AGORA_RTE_API_C void RteStreamConfigSetMinBitRate(RteStreamConfig *self,
+                                                 uint32_t min_bitrate,
+                                                 RteError *err);
+AGORA_RTE_API_C void RteStreamConfigGetMinBitRate(RteStreamConfig *self,
+                                                 uint32_t *min_bitrate,
+                                                 RteError *err);
+
+AGORA_RTE_API_C void RteStreamConfigSetOrientationMode(
+    RteStreamConfig *self, RteOrientationMode orientation_mode, RteError *err);
+AGORA_RTE_API_C void RteStreamConfigGetOrientationMode(
+    RteStreamConfig *self, RteOrientationMode *orientation_mode, RteError *err);
+
+AGORA_RTE_API_C void RteStreamConfigSetVideoDegradationPreference(
+    RteStreamConfig *self, RteVideoDegradationPreference degradation_preference,
+    RteError *err);
+AGORA_RTE_API_C void RteStreamConfigGetVideoDegradationPreference(
+    RteStreamConfig *self,
+    RteVideoDegradationPreference *degradation_preference, RteError *err);
+
+AGORA_RTE_API_C void RteStreamConfigSetVideoMirrorMode(
+    RteStreamConfig *self, RteVideoMirrorMode mirror_mode, RteError *err);
+AGORA_RTE_API_C void RteStreamConfigGetVideoMirrorMode(
+    RteStreamConfig *self, RteVideoMirrorMode *mirror_mode, RteError *err);
+
+AGORA_RTE_API_C void RteStreamConfigSetCheHwDecoding(RteStreamConfig *self,
+                                                    bool che_hw_decoding,
+                                                    RteError *err);
+AGORA_RTE_API_C void RteStreamConfigGetCheHwDecoding(RteStreamConfig *self,
+                                                    bool *che_hw_decoding,
+                                                    RteError *err);
+
+AGORA_RTE_API_C void RteStreamConfigSetJsonParameter(RteStreamConfig *self,
+                                                    RteString *json_parameter,
+                                                    RteError *err);
+AGORA_RTE_API_C void RteStreamConfigGetJsonParameter(RteStreamConfig *self,
+                                                    RteString *json_parameter,
+                                                    RteError *err);
+// @}
+
+// @{
+// Info
+AGORA_RTE_API_C void RteStreamInfoInit(RteStreamInfo *info, RteError *err);
+AGORA_RTE_API_C void RteStreamInfoDeinit(RteStreamInfo *info, RteError *err);
+// @}
+
+AGORA_RTE_API_C void RteStreamGetInfo(RteStream *self, RteStreamInfo *info,
+                                     RteError *err);
+
+AGORA_RTE_API_C void RteStreamSetConfigs(
+    RteStream *self, RteStreamConfig *config,
+    void (*cb)(RteStream *stream, void *cb_data, RteError *err), void *cb_data);
+
+AGORA_RTE_API_C bool RteStreamRegisterObserver(
+    RteStream *self, RteStreamObserver *observer, RteError *err);
+
+AGORA_RTE_API_C RteAudioTrack RteStreamGetAudioTrack(RteStream *self,
+                                                    RteError *err);
+AGORA_RTE_API_C void RteStreamAddAudioTrack(RteStream *self,
+                                           RteAudioTrack *audio_track,
+                                           RteError *err);
+AGORA_RTE_API_C void RteStreamDelAudioTrack(RteStream *self,
+                                           RteAudioTrack *audio_track,
+                                           RteError *err);
+
+AGORA_RTE_API_C RteVideoTrack RteStreamGetVideoTrack(RteStream *self,
+                                                    RteError *err);
+AGORA_RTE_API_C void RteStreamAddVideoTrack(RteStream *self,
+                                           RteVideoTrack *video_track,
+                                           RteError *err);
+AGORA_RTE_API_C void RteStreamDelVideoTrack(RteStream *self,
+                                           RteVideoTrack *video_track,
+                                           RteError *err);
+
+AGORA_RTE_API_C RteDataTrack RteStreamGetDataTrack(RteStream *self,
+                                                  RteError *err);
+AGORA_RTE_API_C void RteStreamAddDataTrack(RteStream *self,
+                                          RteDataTrack *data_track,
+                                          RteError *err);
+AGORA_RTE_API_C void RteStreamDelDataTrack(RteStream *self,
+                                          RteDataTrack *data_track,
+                                          RteError *err);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 34 - 0
app/libs/include/rte_base/c/track/camera_video_track.h

@@ -0,0 +1,34 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include "rte_base/c/handle.h"
+#include "rte_base/c/common.h"
+#include "rte_base/c/track/local_video_track.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct Rte Rte;
+
+typedef struct RteCameraVideoTrackInitialConfig {
+  RteLocalVideoTrackInitialConfig local_video_track_initial_config;
+} RteCameraVideoTrackInitialConfig;
+
+typedef struct RteCameraVideoTrackConfig {
+  RteLocalVideoTrackConfig local_video_track_config;
+} RteCameraVideoTrackConfig;
+
+AGORA_RTE_API_C RteCameraVideoTrack RteCameraVideoTrackCreate(
+    Rte *rte, RteCameraVideoTrackConfig *config, RteError *err);
+AGORA_RTE_API_C void RteCameraVideoTrackDestroy(RteCameraVideoTrack *self,
+                                       RteError *err);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 94 - 0
app/libs/include/rte_base/c/track/canvas.h

@@ -0,0 +1,94 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#include "rte_base/c/handle.h"
+#include "rte_base/c/common.h"
+#include "rte_base/c/track/view.h"
+#include "rte_base/c/stream/stream.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct RteViewConfig RteViewConfig;
+
+
+typedef enum RteVideoRenderMode {
+    /**
+     * 0: The hidden mode will fill the entire view. Parts of the image that exceed the view will be
+     * cropped.
+     */
+    kRteVideoRenderModeHidden = 0,
+    /**
+     * 1: The fit mode will render the entire image within the view.
+     */
+    kRteVideoRenderModeFit = 1
+} RteVideoRenderMode;
+
+typedef struct RteCanvasInitialConfig {
+    char placeholder;
+} RteCanvasInitialConfig;
+
+
+typedef struct RteCanvasConfig {
+
+    RteVideoRenderMode render_mode;
+    bool has_render_mode;
+
+    RteVideoMirrorMode mirror_mode;
+    bool has_mirror_mode;
+
+    RteRect crop_area;
+    bool has_crop_area;
+} RteCanvasConfig;
+
+
+// @{
+// InitialConfig
+AGORA_RTE_API_C void RteCanvasInitialConfigInit(RteCanvasInitialConfig *config,
+                                             RteError *err);
+AGORA_RTE_API_C void RteCanvasInitialConfigDeinit(RteCanvasInitialConfig *config,
+                                               RteError *err);
+// @}
+
+// @{
+// Config
+AGORA_RTE_API_C void RteCanvasConfigInit(RteCanvasConfig *config, RteError *err);
+AGORA_RTE_API_C void RteCanvasConfigDeinit(RteCanvasConfig *config,
+                                          RteError *err);
+
+AGORA_RTE_API_C void RteCanvasConfigSetVideoRenderMode(RteCanvasConfig *self, RteVideoRenderMode render_mode, RteError *err);
+
+AGORA_RTE_API_C void RteCanvasConfigGetVideoRenderMode(RteCanvasConfig *self, RteVideoRenderMode *render_mode, RteError *err);
+
+AGORA_RTE_API_C void RteCanvasConfigSetVideoMirrorMode(RteCanvasConfig *self, RteVideoMirrorMode mirror_mode, RteError *err);
+
+AGORA_RTE_API_C void RteCanvasConfigGetVideoMirrorMode(RteCanvasConfig *self, RteVideoMirrorMode *mirror_mode, RteError *err);
+
+AGORA_RTE_API_C void RteCanvasConfigSetCropArea(RteCanvasConfig *self, RteRect crop_area, RteError *err);
+
+AGORA_RTE_API_C void RteCanvasConfigGetCropArea(RteCanvasConfig *self, RteRect *crop_area, RteError *err);
+
+// @}
+
+AGORA_RTE_API_C RteCanvas RteCanvasCreate(::Rte *rte, RteCanvasInitialConfig *config,
+                                         RteError *err);
+AGORA_RTE_API_C void RteCanvasDestroy(RteCanvas *self, RteError *err);
+
+AGORA_RTE_API_C bool RteCanvasGetConfigs(RteCanvas *self,
+                                        RteCanvasConfig *config, RteError *err);
+AGORA_RTE_API_C bool RteCanvasSetConfigs(RteCanvas *self, RteCanvasConfig *config, RteError *err);
+
+AGORA_RTE_API_C bool RteCanvasAddView(
+    RteCanvas *self, RteView *view, RteViewConfig *config, RteError *err);
+
+AGORA_RTE_API_C bool RteCanvasRemoveView(RteCanvas *self, RteView *view, RteViewConfig *config, RteError *err);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

+ 19 - 0
app/libs/include/rte_base/c/track/layout.h

@@ -0,0 +1,19 @@
+/**
+ *
+ * Agora Real Time Engagement
+ * Copyright (c) 2024 Agora IO. All rights reserved.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+typedef struct RteLayout {
+    char placeholder;
+} RteLayout;
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus

部分文件因文件數量過多而無法顯示