【场景实践征文】英伟达Nano实现家庭监控小系统

我正在参加「RTE 实时万象」征文活动

本文介绍如何通过 Agora SDK 应用在NvidiaNano芯片上搭建一个简易的家庭视频监控用小系统。

首先,你要具备一套NvidiaNano开发板,开发板自带芯片,内存,SD存储卡,外设需要有Camera;

其次,有效的 Agora 账户

最后,一台电脑以及你熟悉的C语言IDE环境如SI、Slime等你熟悉的就好,Nvidia本身没有什么开发框架,基本是写完代码后上传到开发板上进行编译运行

下面章节将介绍如何创建整个工程,并将 Agora SDK 集成至中:

一 开发环境准备

1 搭建好NvidiaNano开发板环境

直接参考官网教程即可,这里不做过多介绍,但是记得一定要选对相应的版本,不然后续做AI的时候可能要重新刷机

https://developer.nvidia.com/embedded/learn/get-started-jetson-nano-devkit#write

2 采集端(NvidiaNano)集成SDK

由于Nvidia芯片集成的是armv8架构芯片,因此在选择sdk包时,选择Agora嵌入式端的SDK,否则编译时会出现格式不兼容的情况出现。使用下面链接的sdk包,不然会报格式不对的错误。https://download.agora.io/rtsasdk/release/Agora-RTSALite-LRmAcAjCP-aarch64-linux-gnu-v1.8.0.tgz

3 浏览端(Chrome)集成SDK

环境windows+Chrome(Version 104.0.5112.102),下载视频 Web SDK,作为浏览端处理

整体运行流程如下

二 代码部分

(一)准备工作,创建并获取AgoraRTC的AppID

1. 登录 [Agora 控制台](https://console.agora.io/),点击左侧导航栏项目管理按钮进入项目管理页面。

2. 在项目管理页面,点击创建按钮。在弹出的对话框内输入项目名称,选择鉴权机制为 App ID。点击提交,Agora 会给每个项目自动分配一个 App ID 作为项目唯一标识。复制并保存,稍后运行示例项目时会用到 App ID。

(二) Nvidia Nano端代码

整体参加SDK中的Example,但是将相应的音视频获取使用,Nvidia中的GStreamer硬件编码或者采集Camera裸流后通过FFmpeg进行编码,具体可使用自己熟悉的,建议使用硬件处理,速率高,不占用设备自身CPU

RtcNanoIPC_init() //初始化Nano的USB Camera,Mac,Ethernet等设备,初始化相关变量
char acAppID[] = "AppID***********************"
agora_rtc_init(); //初始化Agora相关环境变量
void *pAppid = acAppID;

typedef struct tagServConfig{
  char *pSdkLog;
  char *pChannelID;
  unsigned int uiUserID;
  unsigned int uiArea;

  // video related config
  video_data_type_e enVideoType;
  int iVideoSendFrameRate;

  // audio related config
  audio_data_type_e enAudioData;
  audio_codec_type_e enAudioCodec;

  // advanced config
  bool bSndVideoFlag;
  bool bSndOnly;
} SEV_CONFIG_S;

SEV_CONFIG_S g_stSevConfig = {
        .pChannelID = DEFAULT_CHANNEL_NAME,
        .uiUserID = 0,
        .uiArea = AREA_CODE_GLOB,

        // video related config
        .enVideoType = VIDEO_DATA_TYPE_H264,
        .iVideoSendFrameRate = DEFAULT_SEND_VIDEO_FRAME_RATE,

        // audio related config
        .enAudioData = AUDIO_DATA_TYPE_PCM,
        .enAudioCodec = AUDIO_CODEC_TYPE_OPUS,

        // advanced config
        .bSndVideoFlag = false,
        .bSndOnly = true,
};
/*设置事件响应回调, 本工程比较简单,只用到oin,audio,video相关,mute静音等暂未用到/
  agora_rtc_event_handler_t stEventHandler = { 0 };
  init_event_handler(&stEventHandler , &g_stSevConfig );
  
  /初始化/
  rtc_service_option_t stServiceOption = { 0 };
  stServiceOption .area_code = g_stSevConfig.uiArea;
  stServiceOption .log_cfg.log_level = RTC_LOG_INFO;
  stServiceOption .log_cfg.log_path = g_stSevConfig.pSdkLog;
  
  agora_rtc_init(p_appid, &event_handler, &service_opt);
  
  connection_id_t g_stConnId = {0};
  agora_rtc_create_connection(&g_stConnId);
  
  rtc_channel_options_t g_stChannelOptions = {0};
  agora_rtc_join_channel(g_stConnId, g_stSevConfig.pChannelID , g_stSevConfig.uiUserID+1, pAppid,  &g_stChannelOptions );
  
  pthread_t stVideoThdID;
  pthread_t stAudioThdID;
  
  pthread_create(&stVideoThdID, NULL, video_send_process, 0);
  pthread_create(&stAudioThdID, NULL, audio_send_process, 0)

好,上面操作成功后,至此可以发送音视频到服务器端了;

但是当前无参加者观看,为了可以看到效果,采用浏览器端实时浏览的方式(同样参考WebSDK的Example)

var vBrowseClient = AgoraRTC.createClient({ mode: "rtc", codec: "h264" }); //与采集端要一致,采用H264
// Join a channel and create local tracks. Best practice is to use Promise.all and run them concurrently.
[ options.uid, localTracks.audioTrack, localTracks.videoTrack ] = await Promise.all([
// Join the channel.
vBrowseClient .join(options.appid, options.channel, options.token || null, options.uid || null);

vBrowseClient .on("user-published", handleUserPublished);
function handleUserPublished(user, mediaType) {
  const id = user.uid;
  remoteUsers[id] = user;
  subscribe(user, mediaType);
}

async function subscribe(user, mediaType) {
  const uid = user.uid;
  // subscribe to a remote user
  await client.subscribe(user, mediaType);
  console.log("subscribe success");
  if (mediaType === 'video') {
    const player = $(`
      <div id="player-wrapper-${uid}">
        <p class="player-name">remoteUser(${uid})</p>
        <div id="player-${uid}" class="player"></div>
      </div>
    `);
    $("#remote-playerlist").append(player);
    user.videoTrack.play(`player-${uid}`);
  }
  if (mediaType === 'audio') {
    user.audioTrack.play();
  }
}

首先运行基于Nano上的代码,然后在浏览器中输入AppID,UserID就可以实时观看Nano传输过来的视频画面了

推荐阅读
相关专栏
开发者实践
182 文章
本专栏仅用于分享音视频相关的技术文章,与其他开发者和声网 研发团队交流、分享行业前沿技术、资讯。发帖前,请参考「社区发帖指南」,方便您更好的展示所发表的文章和内容。