|
#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) |
|
{ |
|
|
|
} |
|
#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) |
|
{ |
|
|
|
|
|
playback_stream_write((char *)data, len); |
|
} |
|
#endif |
|
|
|
#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) |
|
{ |
|
|
|
|
|
} |
|
|
|
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 |
|
|
|
|
|
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; |
|
|
|
|
|
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"); |
|
|
|
|
|
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; |
|
} |
|
|
|
|
|
rtc_channel_options_t channel_options = { 0 }; |
|
channel_options.auto_subscribe_audio = true; |
|
channel_options.auto_subscribe_video = false; |
|
|
|
#ifdef CONFIG_SEND_PCM_DATA |
|
|
|
|
|
|
|
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) |
|
{ |
|
|
|
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) |
|
{ |
|
|
|
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; |
|
} |
|
|