ten / esp32-client /main /rtc_proc.c
3v324v23's picture
Зафиксирована рабочая версия TEN-Agent для HuggingFace Space
87337b1
raw
history blame
8.29 kB
#include <string.h>
#include "board.h"
#include "common.h"
#include "agora_rtc_api.h"
#include "audio_proc.h"
#include "rtc_proc.h"
#define DEFAULT_SDK_LOG_PATH "io.agora.rtc_sdk"
#define DEFAULT_AREA_CODE AREA_CODE_GLOB
static connection_id_t g_conn_id;
static void __on_join_channel_success(connection_id_t conn_id, uint32_t uid, int elapsed)
{
connection_info_t conn_info = { 0 };
audio_sema_pend();
g_app.b_call_session_started = true;
agora_rtc_get_connection_info(conn_id, &conn_info);
printf("[conn-%lu] Join the channel %s successfully, uid %lu elapsed %d ms\n", conn_id, conn_info.channel_name, uid, elapsed);
}
static void __on_connection_lost(connection_id_t conn_id)
{
g_app.b_call_session_started = false;
printf("[conn-%lu] Lost connection from the channel\n", conn_id);
}
static void __on_rejoin_channel_success(connection_id_t conn_id, uint32_t uid, int elapsed_ms)
{
g_app.b_call_session_started = true;
printf("[conn-%lu] Rejoin the channel successfully, uid %lu elapsed %d ms\n", conn_id, uid, elapsed_ms);
}
static void __on_user_joined(connection_id_t conn_id, uint32_t uid, int elapsed_ms)
{
printf("[conn-%lu] Remote user \"%lu\" has joined the channel, elapsed %d ms\n", uid, conn_id, elapsed_ms);
}
static void __on_user_offline(connection_id_t conn_id, uint32_t uid, int reason)
{
printf("[conn-%lu] Remote user \"%lu\" has left the channel, reason %d\n", conn_id, uid, reason);
}
static void __on_user_mute_audio(connection_id_t conn_id, uint32_t uid, bool muted)
{
printf("[conn-%lu] audio: uid=%lu muted=%d\n", conn_id, uid, muted);
}
static void __on_error(connection_id_t conn_id, int code, const char *msg)
{
if (code == ERR_VIDEO_SEND_OVER_BANDWIDTH_LIMIT) {
printf("Not enough uplink bandwdith. Error msg \"%s\"\n", msg);
return;
}
if (code == ERR_INVALID_APP_ID) {
printf("Invalid App ID. Please double check. Error msg \"%s\"\n", msg);
} else if (code == ERR_INVALID_CHANNEL_NAME) {
printf("Invalid channel name. Please double check. Error msg \"%s\"\n", msg);
} else if (code == ERR_INVALID_TOKEN || code == ERR_TOKEN_EXPIRED) {
printf("Invalid token. Please double check. Error msg \"%s\"\n", msg);
} else if (code == ERR_DYNAMIC_TOKEN_BUT_USE_STATIC_KEY) {
printf("Dynamic token is enabled but is not provided. Error msg \"%s\"\n", msg);
} else {
printf("Error %d is captured. Error msg \"%s\"\n", code, msg);
}
}
#ifdef CONFIG_ENABLE_AUDIO_MIXING
static void __on_mixed_audio_data(connection_id_t conn_id, const void *data, size_t len,
const audio_frame_info_t *info_ptr)
{
//LOG_I("[conn-%u] on_mixed_audio_data, data_type %d, len %zu\n", conn_id, info_ptr->data_type, len);
}
#else
static void __on_audio_data(connection_id_t conn_id, const uint32_t uid, uint16_t sent_ts, const void *data, size_t len,
const audio_frame_info_t *info_ptr)
{
// printf("[conn-%lu] on_audio_data, uid %lu sent_ts %u data_type %d, len %zu\n", conn_id, uid, sent_ts,
// info_ptr->data_type, len);
playback_stream_write((char *)data, len);
}
#endif //#ifdef CONFIG_ENABLE_AUDIO_MIXING
#ifndef CONFIG_AUDIO_ONLY
static void __on_video_data(connection_id_t conn_id, const uint32_t uid, uint16_t sent_ts, const void *data, size_t len,
const video_frame_info_t *info_ptr)
{
/*LOG_I("[conn-%u] on_video_data: uid %u sent_ts %u data_type %d frame_type %d stream_type %d len %zu\n", conn_id, uid,
sent_ts, info_ptr->data_type, info_ptr->frame_type, info_ptr->stream_type, len);*/
}
static void __on_target_bitrate_changed(connection_id_t conn_id, uint32_t target_bps)
{
printf("[conn-%lu] Bandwidth change detected. Please adjust encoder bitrate to %lu kbps\n", conn_id, target_bps / 1000);
}
static void __on_key_frame_gen_req(connection_id_t conn_id, uint32_t uid, video_stream_type_e stream_type)
{
printf("[conn-%lu] Frame loss detected. Please notify the encoder to generate key frame immediately\n", conn_id);
}
static void __on_user_mute_video(connection_id_t conn_id, uint32_t uid, bool muted)
{
printf("[conn-%lu] video: uid=%lu muted=%d\n", conn_id, uid, muted);
}
#endif //#ifndef CONFIG_AUDIO_ONLY
static void app_init_event_handler(agora_rtc_event_handler_t *event_handler)
{
event_handler->on_join_channel_success = __on_join_channel_success;
event_handler->on_connection_lost = __on_connection_lost;
event_handler->on_rejoin_channel_success = __on_rejoin_channel_success;
event_handler->on_user_joined = __on_user_joined;
event_handler->on_user_offline = __on_user_offline;
event_handler->on_user_mute_audio = __on_user_mute_audio;
#ifdef CONFIG_ENABLE_AUDIO_MIXING
event_handler->on_mixed_audio_data = __on_mixed_audio_data;
#else
event_handler->on_audio_data = __on_audio_data;
#endif
#ifndef CONFIG_AUDIO_ONLY
event_handler->on_user_mute_video = __on_user_mute_video;
event_handler->on_target_bitrate_changed = __on_target_bitrate_changed;
event_handler->on_key_frame_gen_req = __on_key_frame_gen_req;
event_handler->on_video_data = __on_video_data;
#endif
event_handler->on_error = __on_error;
}
int agora_rtc_proc_create(char *license, uint32_t uid)
{
int rval = -1;
// 1. API: init agora rtc sdk
agora_rtc_event_handler_t event_handler = { 0 };
app_init_event_handler(&event_handler);
rtc_service_option_t service_opt = { 0 };
service_opt.area_code = AREA_CODE_GLOB;
service_opt.log_cfg.log_disable = false;
service_opt.log_cfg.log_level = RTC_LOG_WARNING;
service_opt.log_cfg.log_path = DEFAULT_SDK_LOG_PATH;
if (!license) {
service_opt.license_value[0] = '\0';
} else {
memcpy(service_opt.license_value, license, 32);
}
service_opt.domain_limit = false;
rval = agora_rtc_init(g_app.app_id, &event_handler, &service_opt);
if (rval < 0) {
printf("Failed to initialize Agora sdk, license %p, reason: %s\n", service_opt.license_value, agora_rtc_err_2_str(rval));
return -1;
}
printf("~~~~~agora_rtc_init success~~~~\r\n");
// 2. API: Create connection
rval = agora_rtc_create_connection(&g_conn_id);
if (rval < 0) {
printf("Failed to create connection, reason: %s\n", agora_rtc_err_2_str(rval));
return -1;
}
// 3. API: join channel
rtc_channel_options_t channel_options = { 0 };
channel_options.auto_subscribe_audio = true;
channel_options.auto_subscribe_video = false;
#ifdef CONFIG_SEND_PCM_DATA
/* If we want to send PCM data instead of encoded audio like AAC or Opus, here please enable
* audio codec, as well as configure the PCM sample rate and number of channels
*/
channel_options.audio_codec_opt.audio_codec_type = AUDIO_CODEC_TYPE;
channel_options.audio_codec_opt.pcm_sample_rate = CONFIG_PCM_SAMPLE_RATE;
channel_options.audio_codec_opt.pcm_channel_num = CONFIG_PCM_CHANNEL_NUM;
#endif
rval = agora_rtc_join_channel(g_conn_id, AI_AGENT_CHANNEL_NAME, uid, g_app.token, &channel_options);
if (rval < 0) {
printf("Failed to join channel \"%s\", reason: %s\n", AI_AGENT_CHANNEL_NAME, agora_rtc_err_2_str(rval));
return -1;
}
return 0;
}
void agora_rtc_proc_destroy(void)
{
agora_rtc_leave_channel(g_conn_id);
agora_rtc_destroy_connection(g_conn_id);
agora_rtc_fini();
}
int send_rtc_audio_frame(uint8_t *data, uint32_t len)
{
// API: send audio data
audio_frame_info_t info = { 0 };
info.data_type = AUDIO_DATA_TYPE_PCM;
int rval = agora_rtc_send_audio_data(g_conn_id, data, len, &info);
if (rval < 0) {
printf("Failed to send audio data, reason: %s\n", agora_rtc_err_2_str(rval));
return -1;
}
return 0;
}
int send_rtc_video_frame(uint8_t *data, uint32_t len)
{
// API: send video data
video_frame_info_t info = {
.data_type = VIDEO_DATA_TYPE_GENERIC_JPEG,
.stream_type = VIDEO_STREAM_HIGH,
.frame_type = VIDEO_FRAME_KEY,
.rotation = VIDEO_ORIENTATION_0,
.frame_rate = 0
};
int rval = agora_rtc_send_video_data(g_conn_id, data, len, &info);
if (rval < 0) {
printf("Failed to send video data, reason: %s\n", agora_rtc_err_2_str(rval));
return -1;
}
return 0;
}