如何基于Linux SDK开发Link Visual视频设备的功能

发布时间:2024-11-18 17:30

如何在音频设备上开启噪音消除功能 #生活技巧# #数码产品使用技巧# #音频设备设置教学#

前提条件

请您先完成Link Visual Demo体验,以提前熟悉整体流程。体验Link Visual请参见快速体验Link Visual。

已完成生活物联网平台SDK的开发。这部分请参见开发指导。

背景信息

Linux版本的Link Visual SDK的资源占用、平台支持和运行依赖如下。

项目

限制条件

项目

限制条件

资源占用情况

RAM:1 MB的码流,预计占用500 KB的RAM内存。

ROM:占用2 MB的ROM存储。

平台支持

目前只能在支持C++11标准(GCC版本4.8.1以上)的Linux平台中使用。

运行依赖

依赖生活物联网平台SDK,您需要同时获取Link Visual SDK和生活物联网平台SDK来完成设备接入。

生活物联网平台SDK:主要提供物联网控制通道能力,包括长连接、消息通知、事件上报等。

Link Visual SDK:主要提供音视频流通道能力,并响应生活物联网平台SDK的控制消息,进行流媒体业务处理。

Linux版本的Link Visual设备端SDK以静态库的形式提供,支持通过编译SDK接入不同芯片的设备,需要您发送邮件申请。

请按以下模板发送邮件至fangyu.hfy@alibaba-inc.com联系我们获取Link Visual设备端SDK。收到邮件后,我们会在收到邮件后的5个工作日内联系您。

邮件主题:获取固件升级SDK和操作说明文档

邮件内容:

公司名称: 公司地址: 联系人: 联系电话: 应用场景描述:

说明

我们给您提供Link Visual SDK时会一并提供配套版本的生活物联网平台SDK,您无需单独下载生活物联网平台SDK。

二、了解SDK目录结构及Demo源码

在开发Link Visual SDK前,建议您先了解整个SDK目录结构以及Link Visual Demo的源码,可以帮助您快速熟悉整个开发流程。

了解SDK目录结构

解压获取到的Link Visual SDK压缩包,并查看压缩包的内容。

# 解压压缩包,并查看压缩包内容(注:压缩包文件名含有版本等可变信息,执行命令时以实际压缩包名称为准) $ tar -xf link_visual_ipc_vxxx.tar.gz $ tree -L 2 link_visual_ipc_vxxx ├── CMakeLists.txt #基于cmake的编译的基础示例 ├── linkvisual # lv库和头文件 │ ├── liblink_visual_ipc.a # lv库(注:实际压缩包可能含有动态库) │ ├── link_visual_def.h # lv头文件 │ └── link_visual_ipc.h # lv头文件 ├── sample # 示例代码 │ ├── demo.c # 示例代码的入口文件 │ ├── demo.h # 示例代码的入口头文件 │ ├── ipc_operation # 示例伪造了ipc的功能,相关实现文件 │ └── sdk_api_operation # 示例中lv sdk的相关实现文件 ├── third_party # 三方库 │ ├── cJSON-1.7.7.tar.gz # JSON解析库,使用版本为1.7.7 │ ├── libevent-2.1.8-stable.tar.gz # libevent,使用版本为2.1.8 │ └── linkkit-sdk-c.tar.gz # 生活物联网平台SDK,提供生活物联网平台接入能力 └── version.txt # 版本说明

了解Demo源码

Link Visual Demo的下载请参见快速体验Link Visual。

# 代码取自文件 sample/demo.c int main(int argc, char* argv[]) { char product_key[PRODUCT_KEY_LEN + 1] = {0}; char device_name[DEVICE_NAME_LEN + 1] = {0}; char device_secret[DEVICE_SECRET_LEN + 1] = {0}; char product_secret[PRODUCT_SECRET_LEN + 1] = {0}; int ret = 0; #ifdef DUMMY_IPC /* 0.初始化虚拟IPC的功能 */ ret = dummy_ipc_start(&dummy_ipc_config); #endif // DUMMY_IPC /* 1. 初始化LinkVisual的资源 */ ret = linkvisual_client_init(product_key, device_name, device_secret, (lv_log_level_e) log_level); /* 2. 初始化linkkit的资源,并长连接到服务器 */ ret = linkkit_client_start(product_key, product_secret, device_name, device_secret); /* 3. 运行,等待服务器命令 */ while(1) { usleep(1000 * 500); } /* 4. linkkit长连接断开,并释放资源 */ linkkit_client_destroy(); /* 5. LinkVisual断开音视频连接,并释放资源 */ linkvisual_client_destroy(); #ifdef DUMMY_IPC /* 停止虚拟IPC的功能 */ dummy_ipc_stop(); #endif // DUMMY_IPC return 0; }

如上述代码所示,设备端Link Visual Demo共完成了3个模块的功能。

启动了一个虚拟IPC,用于模拟IPC的出流功能。这部分功能仅用于测试,您无需过多关注其实现原理、细节等,实际产品中您需要替换成实际的IPC出流功能。

启动了生活物联网平台SDK,建立信令通道,用于接收各类命令,如直播命令等。此外配网、OTA等功能,也属于生活物联网平台SDK功能范畴。

启动了视频服务SDK,用于处理视频相关命令,如直播命令等,并建立媒体通道,发送视音频数据。

这3个模块的功能之间的关系如下图所示(以直播数据转发为例)。

三、编译Link Visual SDK

配置环境。

编译依赖cmake等一些相关软件,这里以Ubuntu 16.04下安装编译环境为例。

$ sudo apt-get install -y build-essential make git gcc g++ cmake tree

编译cJSON。

进入third_party目录,并解压cJSON-1.7.7。

$ cd third_party # 解压代码压缩包 $ tar -xf cJSON-1.7.7.tar.gz $ cd cJSON-1.7.7

在Makefile文件中加入工具链的声明,并替换成对应的交叉编译工具链。

CC = arm-linux-gcc LD = arm-linux-ld AR = arm-linux-ar

编译cJSON,并确认是否生成了libcjson.a,以及头文件cJSON.h是否存在。

$ make # 确认libcjosn.a和相关头文件已存在 $ ls lib*.a $ ls *.h

编译libevent。

在third_party目录里解压libevent。

$ cd third_party # 解压代码压缩包 $ tar -xf libevent-2.1.8-stable.tar.gz

编译libevent。

$ cd libevent-2.1.8-stable # 配置编译条件,注意host和cc需要改为对应的交叉编译工具链信息,编译条件可根据自身需求调整 $ ./configure --host=arm-linux CC=arm-linux-gcc --enable-static --disable-samples --disable-openssl $ make # 编译 $ ls .libs/libevent.* # 确认是否有libevent.a生成

编译生活物联网平台SDK。

在third_party目录里解压ali-smartliving-device-sdk-c。

$ cd third_party $ tar -xf ali-smartliving-device-sdk-c-1.4.tar.gz; #解压代码压缩包 $ cd ali-smartliving-device-sdk-c

修改src/board/config.ubuntu.x86来准备交叉编译。

CROSS_PREFIX :=arm-linux- #在最后加上CROSS_PREFIX :=交叉编译工具链路径前缀(请替换成对应的交叉编译工具链)

选择Ubuntu编译,并确认生成库libiot_tls.a/libiot_sdk.a/libiot_hal.a。

# 这里选择ubuntu对应的数字,一般是数字6 $ make reconfig $ make # 确认有libiot_tls.a/libiot_sdk.a/libiot_hal.a $ ls output/lib/*.a # 确认有如iot_import.h等头文件 $ tree include

整理编译。

返回到SDK解压后的文件夹根目录,修改CMakeLists.txt里的TOOLCHAINS_PREFIX参数值。

set(TOOLCHAINS_PREFIX "arm-linux-" CACHE STRING "set the toolchain") #第二个参数设置为交叉编译工具链前缀(请替换成对应的交叉编译工具链)

执行编译操作。

# 建立一个build文件夹,用于归类编译产物 $ mkdir -p build # 进入build目录,使用根目录的CMakeLists.txt进行cmake $ cd build $ cmake .. # 编译并安装运行所需相关文件 $ make $ make install

编译(compilation)时,您可以添加-std=c++11来支持C++和C++11。

链接(linking)时,您可以在链接选项中添加-lstdc++来支持C++和C++11。

链接(linking)时,库的连接顺序为:link_visual_ipc、iot_sdk cjson、iot_hal、iot_tls pthread、rt。

运行设备。

# 运行方式和Ubuntu Demo或Docker Demo类似,传入设备的激活凭证信息 $ ./link_visual_demo -p your_product_key -n your_product_name -s your_product_secret

四、API简述

由于Link Visual SDK依赖于生活物联网平台SDK,开发Link Visual SDK前,请确认已完成生活物联网平台SDK的开发。请参见开发指导。

生命周期功能

生命周期相关的API如下。

功能说明

API名称

功能说明

API名称

SDK初始化

lv_init

SDK停止

lv_destroy

SDK动态开关等其他功能

功能说明

API名称

功能说明

API名称

生活物联网平台SDK消息注入

lv_linkkit_adapter

SDK功能动态控制

lv_control

直播、卡录像点播、云存等功能

功能说明

API名称

功能说明

API名称

通知直播、点播服务已开启

lv_start_push_streaming_cb

通知直播、点播服务已结束

lv_stop_push_streaming_cb

推送视音频配置参数

lv_stream_send_config

推送视频数据

lv_stream_send_video

推送音频数据

lv_stream_send_audio

推流过程中命令控制(暂停等)

lv_on_push_streaming_cmd_cb

点播的文件列表查询

lv_query_storage_record_cb

点播的文件列表按月查询

lv_query_storage_record_by_month_cb

录像文件播放结束

lv_post_file_close

预录数据结束

lv_post_pre_complete

抓图功能

功能说明

API名称

功能说明

API名称

图片上传

lv_post_alarm_image

通知上传图片

lv_trigger_pic_capture_cb

语音对讲功能

功能说明

API名称

功能说明

API名称

通知开启服务

lv_start_voice_intercom_cb

通知结束服务

lv_stop_voice_intercom_cb

开启服务

lv_voice_intercom_start_service

停止服务

lv_voice_intercom_stop_service

发送音频

lv_voice_intercom_send_audio

接收音频

lv_voice_intercom_receive_data_cb

接收音频参数配置

lv_voice_intercom_receive_metadata_cb

五、API详述-SDK生命周期

SDK生命周期管理相关的API如下。

lv_init

接口名称

接口详情

描述

接口名称

接口详情

描述

lv_init

int lv_init(const lv_config_s *config)

SDK初始化,该接口的使用说明如下。

lv_init主要完成各个IPC功能的回调,以及一些配置类信息。

lv_init会打印相关版本号信息,便于您追溯问题。

初始化失败时,一般不会与网络有关,请优先检查入参是否正确或者资源分配是否成功。

lv_init注册了大量的回调函数,这些回调函数共用一个消息队列线程,因此建议您不要在回调中做过于耗时的操作。

lv_init定义了日志类型log_level,建议对接初期将日志类型设置为LV_LOG_DEBUG。

推荐您在调用lv_init成功后再调用IOT_Linkkit_Connect。

请求参数说明如下。

参数

类型

说明

参数

类型

说明

config

lv_config_s*

配置参数结构体。

示例代码如下。

//新建一个配置结构体,并置空 lv_config_s config; memset(&config, 0, sizeof(lv_config_s)); //以下是设置具体的配置属性 //设备证书(ProductKey、DeviceName、DeviceSecret) memcpy(config.product_key, product_key.c_str(), product_key.length()); memcpy(config.device_name, device_name.c_str(), device_name.length()); memcpy(config.device_secret, device_secret.c_str(), device_secret.length()); //SDK的日志配置 config.log_level = LV_LOG_DEBUG; config.log_dest = LV_LOG_DESTINATION_STDOUT; //config.log_dest_file; //音视频推流服务 config.start_push_streaming_cb = startPushStreamingCallback; config.stop_push_streaming_cb = stopPushStreamingCallback; config.on_push_streaming_cmd_cb = onPushStreamingCmdCb; //语音对讲服务 config.start_voice_intercom_cb = startVoiceIntercomCallback; config.stop_voice_intercom_cb = stopVoiceIntercomCallback; config.voice_intercom_receive_metadata_cb = voice_intercom_receive_metadata_cb; config.voice_intercom_receive_data_cb = VoiceIntercomReceiveDataCallback; //获取存储录像列表 config.query_storage_record_cb = queryStorageRecordCallback; //触发设备抓图 config.trigger_pic_capture_cb = triggerPicCaptureCallback; //触发设备录像 config.trigger_record_cb = triggerRecordCallback; //初始化SDK,失败则退出 int ret = lv_init(&config); if (ret < 0) { return -1; }

lv_destroy

接口名称

接口详情

描述

接口名称

接口详情

描述

lv_destroy

int lv_destroy(void);

SDK销毁,该接口的使用说明如下。

推荐在调用lv_destroy前调用IOT_Linkkit_Close。

调用lv_destroy时,耗时会高达数秒。在正常的业务逻辑内,不建议您反复调用lv_destroy。

无请求参数。

示例代码如下。

六、API详述-视频播放功能

视频播放分为直播、卡录像点播、云储存播放,在视音频数据传输的过程,SDK采用了同一套API来实现视频播放。相关API如下。

lv_start_push_streaming_cb

接口名称

接口详情

描述

接口名称

接口详情

描述

lv_start_push_streaming_cb

typedef int (lv_start_push_streaming_cb)(int service_id, lv_stream_type_e type, const lv_stream_param_s *param)

回调函数,通知视频播放链路已经建立成功,并附带一些配置信息。收到此回调后,您应该根据配置信息初始化编码器,并开始推送音视频数据。

请求参数说明如下。

参数

类型

说明

参数

类型

说明

service_id

int

链路的ID。

type

lv_stream_type_e

链路的类型,分为直播和卡录像点播。

param

const lv_stream_param_s*

链路的参数,例如卡录像要点播的文件名称。

示例代码如下。

//demo,定义了回调函数start_push_streaming_cb作为lv_start_push_streaming_cb的实现 lv_start_push_streaming_cb = start_push_streaming_cb; //demo,回调函数startPushStreamingCallback int start_push_streaming_cb(int service_id, lv_stream_type_e cmd_type, const lv_stream_param_s *param) { if (cmd_type == LV_STREAM_CMD_LIVE) { //使用lv_stream_send_video/lv_stream_send_audio推送音视频数据; //实际使用中建议新建线程进行数据发送 ...... return 0; } else if (cmd_type == LV_STREAM_CMD_STORAGE_RECORD_BY_FILE) { //使用lv_stream_send_video/lv_stream_send_audio推送音视频数据 //实际使用中建议新建线程进行数据发送 ...... return 0; } return 0; }

lv_stop_push_streaming_cb

接口名称

接口详情

描述

接口名称

接口详情

描述

lv_stop_push_streaming_cb

typedef int (*lv_stop_push_streaming_cb)(int service_id)

回调函数,通知视频播放链路已经断开。收到此回调后,您应该停止推送音视频数据。

请求参数说明如下。

参数

类型

说明

参数

类型

说明

service_id

int

链路的ID。

示例代码如下。

//demo,定义了回调函数stop_push_streaming_cb作为lv_start_push_streaming_cb的实现 lv_stop_push_streaming_cb = stop_push_streaming_cb; //demo,回调函数stop_push_streaming_cb int stop_push_streaming_cb(int service_id) { if (service_id == g_live_service_id) { //您停止推流 } else if (service_id == g_storage_record_service_id) { //您停止推流 } return 0; }

lv_on_push_streaming_cmd_cb

接口名称

接口详情

描述

接口名称

接口详情

描述

lv_on_push_streaming_cmd_cb

typedef int (*lv_on_push_streaming_cmd_cb)(int service_id, lv_on_push_streaming_cmd_type_e cmd, const lv_on_push_streaming_cmd_param_s *param)

回调函数,通知视频播放链路建立期间,可以进行一些命令控制,例如要求发送I帧命令。

请求参数说明如下。

参数

类型

说明

参数

类型

说明

service_id

int

链路的ID。

cmd

lv_on_push_streaming_cmd_type_e

控制命令,目前有开始播放、停止播放、暂停播放、恢复播放、定位、强制I帧。

param

lv_on_push_streaming_cmd_param_s *

参数值和lv_on_push_streaming_cmd_type_e有关

示例代码如下。

//demo,定义了回调函数on_push_streaming_cmd_cb作为lv_on_push_streaming_cmd_cb的实现 on_push_streaming_cmd_cb = on_push_streaming_cmd_cb; int on_push_streaming_cmd_cb(int service_id, lv_on_push_streaming_cmd_type_e cmd, const lv_on_push_streaming_cmd_param_s *param) { if (cmd == LV_STORAGE_RECORD_START) { //卡录像开始推流 } else if (cmd == LV_STORAGE_RECORD_STOP) { //卡录像停止推流 } else if (cmd == LV_STORAGE_RECORD_PAUSE) { //卡录像暂停推流 } else if (cmd == LV_STORAGE_RECORD_UNPAUSE) { //卡录像恢复推流 } else if (cmd == LV_STORAGE_RECORD_SEEK) { //卡录像定位到某一段 } else if (cmd == LV_LIVE_REQUEST_I_FRAME) { //对于直播,需要强制生成一个I帧 } return 0; }

lv_stream_send_config

接口名称

接口详情

描述

接口名称

接口详情

描述

lv_stream_send_config

int lv_stream_send_config(int service_id, unsigned int bitrate_kbps, double duration, const lv_video_param_s *video_param, const lv_audio_param_s *audio_param)

配置发送音视频的参数。

请求参数说明如下。

参数

类型

说明

参数

类型

说明

service_id

int

链路的ID。

bitrate_kbps

unsigned int

链路的码流,设置的码流越大,内部音视频数据缓冲区越大。

duration

double

文件时长,卡录像点播有效。

video_param

const lv_video_param_s*

视频的参数集。

audio_param

const lv_audio_param_s*

音频的参数集。

示例代码如下。

lv_video_param_s video_param; memset(&video_param, 0, sizeof(lv_video_param_s)); video_param.format = LV_VIDEO_FORMAT_H264; video_param.fps = 25; lv_audio_param_s audio_param; memset(&audio_param, 0, sizeof(lv_audio_param_s)); audio_param.format = LV_AUDIO_FORMAT_G711A; audio_param.channel = LV_AUDIO_CHANNEL_MONO; audio_param.sample_bits = LV_AUDIO_SAMPLE_BITS_16BIT; audio_param.sample_rate = LV_AUDIO_SAMPLE_RATE_8000; lv_stream_send_config(service_id, 1000, 0, &video_param, &audio_param);

lv_stream_send_video

接口名称

接口详情

描述

接口名称

接口详情

描述

lv_stream_send_video

int lv_stream_send_video(int service_id, lv_video_format_e format,unsigned char* buffer, unsigned int buffer_len, bool key_frame, unsigned int timestamp_ms)

发送视频数据。

请求参数说明如下。

参数

类型

说明

参数

类型

说明

service_id

int

链路的ID。

format

lv_video_format_e

视频编码类型

buffer

unsigned char*

视频的数据。

buffer_len

unsigned int

视频的数据长度。

key_frame

bool

是否为关键帧。I帧为关键帧,P帧为非关键帧,不接受B帧。

timestamp_ms

unsigned int

视频的时间戳。

示例代码如下。

//demo,这个函数回调输入视频帧数据 void linkvisual_client_video_handler(int service_id, lv_video_format_e format, unsigned char *buffer, unsigned int buffer_size, unsigned int present_time, int nal_type) { lv_stream_send_video(service_id, format, buffer, buffer_size, nal_type, present_time); }

lv_stream_send_audio

接口名称

接口详情

描述

接口名称

接口详情

描述

lv_stream_send_audio

int lv_stream_send_audio(int service_id, lv_audio_format_e format,unsigned char* buffer, unsigned int buffer_len, unsigned int timestamp_ms)

发送音频数据。

请求参数说明如下。

参数

类型

说明

参数

类型

说明

service_id

int

链路的ID。

format

lv_audio_format_e

音频编码类型

buffer

unsigned char*

音频的数据。

buffer_len

unsigned int

音频的数据长度。

timestamp_ms

unsigned int

音频的时间戳。

示例代码如下。

//demo,这个函数回调输入音频帧数据 void linkvisual_client_audio_handler(int service_id, lv_audio_format_e format, unsigned char *buffer, unsigned int buffer_size, unsigned int present_time) { lv_stream_send_audio(service_id, format, buffer, buffer_size, present_time); }

lv_query_storage_record_cb

接口名称

接口详情

描述

接口名称

接口详情

描述

lv_query_storage_record_cb

typedef void (lv_query_storage_record_cb)(unsigned int start_time, unsigned int stop_time, int num, const char *id, int (on_complete)(int num, const char *id, const lv_query_storage_record_response_s *response))

回调函数,查询卡录像的文件信息。

请求参数说明如下。

参数

类型

说明

参数

类型

说明

start_time

unsigned int

查询录像的开始时间。

stop_time

unsigned int

查询录像的结束时间。

num

int

录像数量小于等于0的时候表示已查询全部的录像。

id

const char *

查询的会话ID,需要回传。

on_complete

函数指针

将查询结果通过该函数同步返回。

示例代码如下。

int dummy_ipc_report_vod_list(unsigned int start_time, unsigned int stop_time, int num, const char *id, int (*on_complete)(int num, const char *id, const lv_query_storage_record_response_s *response)) { int answer_num = g_vod_media_file_group.size(); auto *response = new lv_query_storage_record_response_s[answer_num]; memset(response, 0, sizeof(lv_query_storage_record_response_s) * answer_num); double duration = 0; for (int i = 0; i < answer_num; i ++) { MediaParse::GetDuration(g_vod_media_file_group[i], duration); response[i].file_size = 0; response[i].record_type = LV_STORAGE_RECORD_INITIATIVE; snprintf(response[i].file_name, 64, g_vod_media_file_group[i].c_str(), i);//注意不要溢出 if (i == 0) { response[i].start_time = (int)start_time; response[i].stop_time = (int)start_time + (int)duration; } else { response[i].start_time = response[i - 1].stop_time; response[i].stop_time = response[i - 1].stop_time + (int)duration; } } int result = on_complete(answer_num, id, response); printf("dummy_ipc_report_vod_list result: %d\n", result); delete[] response; return 0; }

直播流程图

卡录像点播流程图

预录事件点播流程图

云存

云存分为事件触发云存和连续云存两种场景。您基于SDK实现直播功能即可同时实现云存功能,无需您额外开发。

视频播放功能的接口调用说明如下。

强制I帧命令发出时,为了保证尽可能快速的发出I帧,您应尽可能快的产生I帧,建议在300毫秒(ms)内完成

强制I帧命令发出时,您需要重新调用lv_stream_send_config发送流配置。

进行卡录像的定位操作时,为了尽可能快速的显示定位后的数据,您在定位操作后,应该尽可能快速的发出I帧,同时SDK在定位操作后也不再接收音频数据和视频的P帧数据,直到I帧到达。

H264/H265的帧结构会有一定的要求,可以打印I帧的前256个字节进行查看,打印代码如下。

for (int i = 0; i < ((buffer_size > 256)?256:buffer_size); i++) { printf("%02x ", buffer[i]); if ((i + 1) % 30 == 0) { printf("\n"); } } printf("\n");

H264要求I帧为:帧分隔符+SPS+帧分隔符+PPS+帧分隔符+IDR。如下图所示。

0x000001或者0x00000001是帧分隔符,0x67是SPS的开始,0x68是PPS的开始,0x65是IDR的开始。

H265要求I帧为:帧分隔符+VPS+帧分隔符+SPS+帧分隔符+PPS+帧分隔符+IDR,如下图所示。

说明

音频目前支持G711A/LC-AAC编码方式,编码参数的支持需要参考头文件link_visual_def.h中的宏定义值。

同一路流切换视频码流时(如主码流切为子码流、修改码流分辨率、H264/H265切换等),请保证切换后的第一帧为I帧,否则会引发花屏等现象。

七、API详述-图片服务

图片服务相关的API如下。

lv_trigger_pic_capture_cb

接口名称

接口详情

描述

接口名称

接口详情

描述

lv_trigger_pic_capture_cb

typedef int (lv_trigger_pic_capture_cb)(const char *id)

通知设备开始抓取图片。

请求参数说明如下。

参数

类型

说明

参数

类型

说明

id

const char *

本次请求的ID,需要回传。

lv_post_alarm_image

接口名称

接口详情

描述

接口名称

接口详情

描述

lv_post_alarm_image

int lv_post_alarm_image(const char *buffer, int buffer_len, lv_event_type_e type, const char *id)

发送图片和报警事件,适用于抓图回调后进行上报,或者设备主动发起上报。

请求参数说明如下。

参数

类型

说明

参数

类型

说明

buffer

const char *

图片数据。

buffer_len

int

图片数据长度。

type

lv_event_type_e

上报类型,分为抓图回调后进行上报和设备主动发起上报。

id

const char *

抓图回调的ID回传,主动上报时传空字符串或者NULL。

抓图功能分为App端触发抓图请求和事件侦测触发设备端主动抓图两种场景。

调用图片服务相关接口的说明如下。

上传的最大图片大小为1MB。

图片上传的最小间隔为1秒,频繁触发的图片将会被丢弃。

图片会由SDK内部保存一份拷贝,并形成待发送的图片队列。图片队列的长度为5,在网络差的情况下,图片队列可能会满,满队列后新生成的图片将会被丢弃。

SDK不限制图片的格式,只要云端或者从云端拉取图片的设备能够支持解析即可。推荐使用常见的图片格式,如,jpg格式。

八、API详述-语音对讲服务

语音对讲服务相关的API如下。

lv_start_voice_intercom_cb

接口名称

接口详情

描述

接口名称

接口详情

描述

lv_start_voice_intercom_cb

typedef int (*lv_start_voice_intercom_cb)(int service_id)

回调函数,返回一路语音对讲服务链路已可以建立的通知。

请求参数说明如下。

参数

类型

说明

参数

类型

说明

service_id

int

链路的ID。

lv_voice_intercom_start_service

接口名称

接口详情

描述

接口名称

接口详情

描述

lv_voice_intercom_start_service

int lv_voice_intercom_start_service(int service_id, const lv_audio_param_s *audio_param)

建立一路语音对讲链路,在收到语音对讲开始的回调后,调用该接口。

请求参数说明如下。

参数

类型

说明

参数

类型

说明

service_id

int

链路的ID。

audio_param

const lv_audio_param_s *

设备的音频参数结构体。

示例代码如下。

//demo,start_voice_intercom_cb是lv_start_voice_intercom_cb的实际实现 lv_start_voice_intercom_cb = start_voice_intercom_cb; int start_voice_intercom_cb(int service_id) { //收到开始语音对讲请求时,主动开启对讲服务 lv_audio_param_s audio_param; memset(&audio_param, 0, sizeof(lv_audio_param_s)); audio_param.format = LV_AUDIO_FORMAT_G711A; audio_param.channel = LV_AUDIO_CHANNEL_MONO; audio_param.sample_bits = LV_AUDIO_SAMPLE_BITS_16BIT; audio_param.sample_rate = LV_AUDIO_SAMPLE_RATE_8000; int ret = lv_voice_intercom_start_service(service_id, &audio_param); return 0; }

lv_stop_voice_intercom_cb

接口名称

接口详情

描述

接口名称

接口详情

描述

lv_stop_voice_intercom_cb

typedef int (*lv_stop_voice_intercom_cb)(int service_id)

回调函数,返回一路语音对讲服务链路已可以断开的通知。

请求参数说明如下。

参数

类型

说明

参数

类型

说明

service_id

int

链路的ID。

lv_voice_intercom_stop_service

接口名称

接口详情

描述

接口名称

接口详情

描述

lv_voice_intercom_stop_service

int lv_voice_intercom_stop_service(int service_id)

断开一路语音对讲链路,在收到语音对讲结束的回调后,调用该接口。

请求参数说明如下。

参数

类型

说明

参数

类型

说明

service_id

int

链路的ID。

示例代码如下。

//demo,stop_voice_intercom_cb是lv_start_voice_intercom_cb的实际实现 lv_stop_voice_intercom_cb = stop_voice_intercom_cb; int stop_voice_intercom_cb(int service_id) { lv_voice_intercom_stop_service(service_id); }

lv_voice_intercom_receive_metadata_cb

接口名称

接口详情

描述

接口名称

接口详情

描述

lv_voice_intercom_receive_metadata_cb

typedef int (lv_voice_intercom_receive_metadata_cb)(int service_id, const lv_audio_param_s *audio_param)

回调函数,通知语音对讲时,App发送的音频参数格式。

请求参数说明如下。

参数

类型

说明

参数

类型

说明

service_id

int

链路的ID。

audio_param

const lv_audio_param_s *

APP发送的音频格式结构体。

lv_voice_intercom_receive_data_cb

接口名称

接口详情

描述

接口名称

接口详情

描述

lv_voice_intercom_receive_data_cb

typedef void (lv_voice_intercom_receive_data_cb)(const char *buffer, unsigned int buffer_len)

回调函数,语音对讲时,App发送的音频数据。

请求参数说明如下。

参数

类型

说明

参数

类型

说明

buffer

const char *

APP发送的音频数据。

buffer_len

int

APP发送的音频数据长度。

lv_voice_intercom_send_audio

接口名称

接口详情

描述

接口名称

接口详情

描述

lv_voice_intercom_send_audio

int lv_voice_intercom_send_audio(int service_id, const char *buffer, int buffer_len , unsigned int timestamp_ms)

向其中一路语音对讲链路发送音频数据。

请求参数说明如下。

参数

类型

说明

参数

类型

说明

service_id

int

链路的ID。

buffer

const char *

设备音频数据。

buffer_len

int

设备音频数据长度。

timestamp_ms

unsigned int

设备音频时间戳。

示例代码如下。

void linkvisual_client_audio_handler(int service_id, lv_audio_format_e format, unsigned char *buffer, unsigned int buffer_size, unsigned int present_time) { lv_voice_intercom_send_audio(g_voice_intercom_service_id, buffer, buffer_size, present_time); }

语音对讲流程图如下:

九、后续操作

生成设备固件后,您可以将固件烧录到设备中,并使用App调试Link Visual功能。建议您直接使用公版App来调试。公版App的下载请参见云智能App介绍。

网址:如何基于Linux SDK开发Link Visual视频设备的功能 https://www.yuejiaxmz.com/news/view/122749

相关内容

从开发者角度入门Linux世界资料整理=Linux介绍+Ubuntu系统安装(视频+文字)
我是如何使用影石 Insta360 Link 教老人使用手机的?
基于STM32开发的智能语音助手系统
如何使用Android的移动应用推送SDK
如何配置移动应用服务和开发推送功能
镜头随人物而动,视频编辑服务让用户稳站C位现如今,视频是用户记录生活最热门的方式,各种App在发布视频界面都提供了视频简
Python项目设计:个人财务管理系统实现与功能详解
基于ShineBlink物联网开发板和机智云平台开发的“针对短期内宠物无人照顾的智能宠物屋”系统
Halcon linux makefile 配置
设计源·LINK创新

随便看看