Link Visual device development - Linux SDK

更新时间:
复制 MD 格式

The IoT Platform provides a Linux version of the LinkVisual device-side SDK. You can use this SDK to develop features such as live streaming, video-on-demand, voice intercom, and image capture for LinkVisual video devices.

Prerequisites

  • Complete the LinkVisual demo to familiarize yourself with the overall workflow. For more information, see Quickly experience LinkVisual.

  • Complete the development of the IoT Platform SDK. For more information, see Development guide.

Background information

The resource usage, platform support, and runtime dependencies of the Linux version of the LinkVisual SDK are as follows.

Item

Limitations

Resource usage

  • RAM: A 1 MB stream uses approximately 500 KB of RAM.

  • ROM: Uses 2 MB of ROM storage.

Platform support

Currently supported only on Linux platforms that comply with the C++11 standard (GCC version 4.8.1 or later).

Runtime dependencies

Depends on the IoT Platform SDK. You must obtain both the Link Visual SDK and the IoT Platform SDK to connect your device.

  • IoT Platform SDK: Provides IoT control channel capabilities, including persistent connections, message notifications, and event reporting.

  • Link Visual SDK: Provides audio and video stream channel capabilities and processes streaming media operations in response to control messages from the IoT Platform SDK.

1. Obtain the Link Visual SDK

The Linux version of the LinkVisual device-side SDK is provided as a static library. It supports integration with devices that use different chips through compilation. You must request the SDK by email.

Send an email to fangyu.hfy@alibaba-inc.com using the following template to request the LinkVisual device-side SDK. We will contact you within five business days after we receive your email.

  • Subject: Request for firmware upgrade SDK and operation documentation

  • Body:

    Company name:
    Company address:
    Contact:
    Phone number:
    Scenario description:
Note

When we provide the LinkVisual SDK, we also include the corresponding version of the IoT Platform SDK. You do not need to download the IoT Platform SDK separately.

2. Understand the SDK directory structure and demo source code

Before you develop with the LinkVisual SDK, review the SDK directory structure and the LinkVisual demo source code to quickly understand the development workflow.

  • Understand the SDK directory structure

    Extract the LinkVisual SDK archive and examine its contents.

    # Extract the archive and view its contents (note: the filename includes version-specific information; use the actual filename when running the command)
    $ tar -xf link_visual_ipc_vxxx.tar.gz
    $ tree -L 2 link_visual_ipc_vxxx
    
    ├── CMakeLists.txt # Basic CMake-based build example
    ├── linkvisual # LV libraries and header files
    │   ├── liblink_visual_ipc.a # LV library (note: the actual archive may contain a dynamic library)
    │   ├── link_visual_def.h # LV header file
    │   └── link_visual_ipc.h # LV header file
    ├── sample # Sample code
    │   ├── demo.c # Entry file for sample code
    │   ├── demo.h # Header file for sample code
    │   ├── ipc_operation # Simulated IPC functionality for demonstration
    │   └── sdk_api_operation # LV SDK implementation files for the sample
    ├── third_party # Third-party libraries
    │ ├── cJSON-1.7.7.tar.gz # JSON parsing library, version 1.7.7
    │ ├── libevent-2.1.8-stable.tar.gz # libevent, version 2.1.8
    │ └── linkkit-sdk-c.tar.gz # IoT Platform SDK for IoT Platform connectivity
    └── version.txt  # Version information
  • Understand the demo source code

    For instructions on how to download the LinkVisual demo, see Quickly experience LinkVisual.

    # Code excerpt from 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. Initialize virtual IPC functionality */
        ret = dummy_ipc_start(&dummy_ipc_config);
    #endif // DUMMY_IPC
    
        /* 1. Initialize LinkVisual resources */
        ret = linkvisual_client_init(product_key, device_name, device_secret, (lv_log_level_e) log_level);
    
        /* 2. Initialize linkkit resources and establish a persistent connection to the server */
        ret = linkkit_client_start(product_key, product_secret, device_name, device_secret);
    
        /* 3. Run and wait for server commands */
        while(1) {
            usleep(1000 * 500);
        }
    
        /* 4. Disconnect the linkkit persistent connection and release resources */
        linkkit_client_destroy();
    
        /* 5. Disconnect the LinkVisual audio/video connection and release resources */
        linkvisual_client_destroy();
    
    #ifdef DUMMY_IPC
        /* Stop virtual IPC functionality */
        dummy_ipc_stop();
    #endif // DUMMY_IPC
    
        return 0;
    }

    As shown in the preceding code, the LinkVisual device demo implements three modules.

    • Starts a virtual IPC to simulate IPC stream output. This is for testing only. You do not need to focus on its implementation details. In a real product, you must replace it with actual IPC stream output functionality.

    • Starts the IoT Platform SDK to establish a signaling channel for receiving commands, such as live streaming requests. Features such as network provisioning and Over-the-Air (OTA) updates are also part of the IoT Platform SDK.

    • Starts the video service SDK to handle video-related commands, such as live streaming, and establish a media channel to send audio and video data.

    The relationship among these three modules is shown in the following figure. The figure uses live stream forwarding as an example.

    demo结构

3. Compile the Link Visual SDK

  1. Set up the environment.

    Compilation requires tools such as CMake. The following example shows how to install the build environment on Ubuntu 16.04.

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

    1. Go to the third_party directory and extract cJSON-1.7.7.

      $ cd third_party
      # Extract the source archive
      $ tar -xf cJSON-1.7.7.tar.gz
      $ cd cJSON-1.7.7
    2. Add toolchain declarations to the Makefile and replace them with your cross-compilation toolchain.

      CC        =   arm-linux-gcc
      LD        =   arm-linux-ld
      AR       =   arm-linux-ar
    3. Compile cJSON and verify that libcjson.a and the header file cJSON.h exist.

      $ make
      # Confirm libcjosn.a and related header files exist
      $ ls lib*.a
      $ ls *.h
  3. Compile libevent.

    1. In the third_party directory, extract libevent.

      $ cd third_party
      # Extract the source archive
      $ tar -xf libevent-2.1.8-stable.tar.gz
    2. Compile libevent.

      $ cd libevent-2.1.8-stable 
      # Configure build options; update host and CC to match your cross-compilation toolchain. Adjust other options as needed.
      $ ./configure --host=arm-linux CC=arm-linux-gcc --enable-static --disable-samples --disable-openssl
      $ make # Compile
      $ ls .libs/libevent.* # Confirm libevent.a is generated
  4. Compile the IoT Platform SDK.

    1. In the third_party directory, extract ali-smartliving-device-sdk-c.

      $ cd third_party
      $ tar -xf ali-smartliving-device-sdk-c-1.4.tar.gz;
      # Extract the source archive
      $ cd ali-smartliving-device-sdk-c
    2. Modify src/board/config.ubuntu.x86 to prepare for cross-compilation.

      CROSS_PREFIX :=arm-linux- 
      # Append CROSS_PREFIX := [your cross-compilation toolchain path prefix] (replace with your actual toolchain)
    3. Select Ubuntu compilation and confirm that the libraries libiot_tls.a, libiot_sdk.a, and libiot_hal.a are generated.

      # Select the Ubuntu option (usually number 6)
      $ make reconfig
      $ make
      # Confirm libiot_tls.a/libiot_sdk.a/libiot_hal.a exist
      $ ls output/lib/*.a
      # Confirm header files such as iot_import.h exist
      $ tree include
  5. Organize the build.

    1. Return to the root directory of the extracted SDK and modify the TOOLCHAINS_PREFIX parameter in CMakeLists.txt.

      set(TOOLCHAINS_PREFIX "arm-linux-" CACHE STRING "set the toolchain")
      # Set the second parameter to your cross-compilation toolchain prefix (replace with your actual toolchain)
    2. Perform the build.

      # Create a build folder to organize build artifacts
      $ mkdir -p build
      # Enter the build directory and run CMake using CMakeLists.txt from the root
      $ cd build
      $ cmake ..
      # Compile and install required runtime files
      $ make
      $ make install
      • During compilation, add -std=c++11 to enable C++11 support.

      • During linking, add -lstdc++ to enable C++11 support.

      • Link the libraries in the following order: link_visual_ipc, iot_sdk cjson, iot_hal, iot_tls pthread, and rt.

  6. Run the device.

    # Run similarly to the Ubuntu or Docker demo, passing your device's activation credentials
    $ ./link_visual_demo -p your_product_key -n your_product_name -s your_product_secret

4. API overview

Because the LinkVisual SDK depends on the IoT Platform SDK, you must confirm that you have completed the IoT Platform SDK development before you proceed. For more information, see Development guide.

  • Lifecycle functions

    The following APIs manage the SDK lifecycle.

    Features

    API name

    SDK initialization

    lv_init

    SDK shutdown

    lv_destroy

  • Dynamic control and other functions

    Description

    API name

    Inject IoT Platform SDK messages

    lv_linkkit_adapter

    Dynamic SDK control

    lv_control

  • Live streaming, SD card video-on-demand, and cloud storage functions

    Features

    API name

    Notify that live streaming or video-on-demand has started

    lv_start_push_streaming_cb

    Notify that live streaming or video-on-demand has ended

    lv_stop_push_streaming_cb

    Push audio/video configuration parameters

    lv_stream_send_config

    Push video data

    lv_stream_send_video

    Push audio data

    lv_stream_send_audio

    Control commands during streaming (pause, etc.)

    lv_on_push_streaming_cmd_cb

    Query a list of video-on-demand files

    lv_query_storage_record_cb

    You can query video-on-demand files by month.

    lv_query_storage_record_by_month_cb

    End playback of a recorded file

    lv_post_file_close

    End pre-recording data

    lv_post_pre_complete

  • Image capture function

    Description

    API name

    Upload images

    lv_post_alarm_image

    Image Upload Notifications

    lv_trigger_pic_capture_cb

  • Voice intercom function

    Features

    API name

    Notify service start

    lv_start_voice_intercom_cb

    Notify service end

    lv_stop_voice_intercom_cb

    Start service

    lv_voice_intercom_start_service

    Stop service

    lv_voice_intercom_stop_service

    Send audio

    lv_voice_intercom_send_audio

    Receive audio

    lv_voice_intercom_receive_data_cb

    Receive audio parameter configuration

    lv_voice_intercom_receive_metadata_cb

5. Detailed API reference - SDK lifecycle

The following APIs manage the SDK lifecycle.

  • lv_init

    API name

    API details

    Description

    lv_init

    int lv_init(const lv_config_s *config)

    Initializes the SDK. Notes:

    • Registers callbacks for various IPC functions and configuration information.

    • Prints version information to help troubleshoot issues.

    • Initialization failures are usually unrelated to network issues. First check if input parameters are correct or if resource allocation succeeded.

    • Registers many callbacks that share a single message queue thread. Avoid time-consuming operations in callbacks.

    • Defines the log level log_level. Set it to LV_LOG_DEBUG during initial integration.

    • Call IOT_Linkkit_Connect only after successfully calling lv_init.

    Request parameters:

    Parameter

    Type

    Description

    config

    lv_config_s*

    Configuration structure.

    Example code:

    // Create and zero-initialize a configuration structure
    lv_config_s config;
    memset(&config, 0, sizeof(lv_config_s));
    
    // Set specific configuration properties
    // Device certificate (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 logging configuration
    config.log_level = LV_LOG_DEBUG;
    config.log_dest = LV_LOG_DESTINATION_STDOUT;
    //config.log_dest_file;
    
    // Audio/video streaming service
    config.start_push_streaming_cb = startPushStreamingCallback;
    config.stop_push_streaming_cb = stopPushStreamingCallback;
    config.on_push_streaming_cmd_cb = onPushStreamingCmdCb;
    
    // Voice intercom service
    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;
    
    // Query stored recordings
    config.query_storage_record_cb = queryStorageRecordCallback;
    
    // Trigger device image capture
    config.trigger_pic_capture_cb = triggerPicCaptureCallback;
    
    // Trigger device recording
    config.trigger_record_cb = triggerRecordCallback;
    
    // Initialize SDK; exit on failure
    int ret = lv_init(&config);
    if (ret < 0) {
        return -1;
    }
  • lv_destroy

    API name

    Interface details

    Description

    lv_destroy

    int lv_destroy(void);

    Shuts down the SDK. Notes:

    • Call IOT_Linkkit_Close before calling lv_destroy.

    • Calling lv_destroy can take several seconds. Avoid repeated calls in normal business logic.

    No request parameters.

    Example code:

    // After execution ends
    lv_destroy();

6. Detailed API reference - Video playback

Video playback includes live streaming, SD card video-on-demand, and cloud storage playback. The SDK uses the same set of APIs for all video playback scenarios. The relevant APIs are as follows.

  • lv_start_push_streaming_cb

    API name

    API Details

    Description

    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)

    Callback function that notifies your application that a video playback link has been established successfully, along with configuration details. After receiving this callback, initialize your encoder based on the provided configuration and begin pushing audio/video data.

    Request parameters:

    Parameter

    Type

    Description

    service_id

    int

    Link ID.

    type

    lv_stream_type_e

    Link type: live streaming or SD card video-on-demand.

    param

    const lv_stream_param_s*

    Link parameters, such as the filename for SD card video-on-demand.

    Example code:

    // Demo: define start_push_streaming_cb as the implementation of lv_start_push_streaming_cb
    lv_start_push_streaming_cb = start_push_streaming_cb;
    
    // Demo: callback function 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) {
            // Push audio/video data using lv_stream_send_video/lv_stream_send_audio;
            // In practice, create a new thread for data transmission
            ......
            return 0;
        } else if (cmd_type == LV_STREAM_CMD_STORAGE_RECORD_BY_FILE) {
           // Push audio/video data using lv_stream_send_video/lv_stream_send_audio
           // In practice, create a new thread for data transmission
           ......
           return 0;
        }
    
        return 0;
    }
  • lv_stop_push_streaming_cb

    API name

    Interface details

    Description

    lv_stop_push_streaming_cb

    typedef int (*lv_stop_push_streaming_cb)(int service_id)

    Callback function that notifies your application that a video playback link has been disconnected. After receiving this callback, stop pushing audio/video data.

    Request parameters:

    Parameter

    Type

    Description

    service_id

    int

    Link ID.

    Example code:

    // Demo: define stop_push_streaming_cb as the implementation of lv_stop_push_streaming_cb
    lv_stop_push_streaming_cb = stop_push_streaming_cb;
    
    // Demo: callback function stop_push_streaming_cb
    int stop_push_streaming_cb(int service_id)
    {
        if (service_id == g_live_service_id) {
            // Stop streaming
        } else if (service_id == g_storage_record_service_id) {
           // Stop streaming
        }
    
        return 0;
    }
  • lv_on_push_streaming_cmd_cb

    API name

    Interface details

    Description

    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)

    Callback function that notifies your application of control commands during video playback link establishment, such as a request to send an I-frame.

    Request parameters:

    Parameter

    Type

    Description

    service_id

    int

    Link ID.

    cmd

    lv_on_push_streaming_cmd_type_e

    Control command. Supported commands: start playback, stop playback, pause playback, resume playback, seek, and force I-frame.

    param

    lv_on_push_streaming_cmd_param_s *

    Parameter value, which depends on lv_on_push_streaming_cmd_type_e.

    Example code:

    // Demo: define on_push_streaming_cmd_cb as the implementation of 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) {
            // Start SD card recording stream
        } else if (cmd == LV_STORAGE_RECORD_STOP) {
            // Stop SD card recording stream
        } else if (cmd == LV_STORAGE_RECORD_PAUSE) {
            // Pause SD card recording stream
        } else if (cmd == LV_STORAGE_RECORD_UNPAUSE) {
            // Resume SD card recording stream
        } else if (cmd == LV_STORAGE_RECORD_SEEK) {
            // Seek to a specific segment in SD card recording
        } else if (cmd == LV_LIVE_REQUEST_I_FRAME) {
            // For live streaming, force generation of an I-frame
        }
    
        return 0;
    }
  • lv_stream_send_config

    API name

    API details

    Description

    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)

    Configures audio/video transmission parameters.

    Request parameters:

    Parameter

    Type

    Description

    service_id

    int

    Link ID.

    bitrate_kbps

    unsigned int

    Stream bitrate. Higher bitrates require larger internal audio/video data buffers.

    duration

    double

    File duration. Valid only for SD card video-on-demand.

    video_param

    const lv_video_param_s*

    Video parameter set.

    audio_param

    const lv_audio_param_s*

    Audio parameter set.

    Example code:

    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

    API name

    API Details

    Description

    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)

    Sends video data.

    Request parameters:

    Parameter

    Type

    Description

    service_id

    int

    Link ID.

    format

    lv_video_format_e

    Video codec.

    buffer

    unsigned char*

    Video data.

    buffer_len

    unsigned int

    Video data length.

    key_frame

    bool

    Indicates whether the frame is a keyframe. I-frames are keyframes. P-frames are non-keyframes. B-frames are not accepted.

    timestamp_ms

    unsigned int

    Video timestamp.

    Example code:

    // Demo: this function receives video frames as input
    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

    API name

    API details

    Description

    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)

    Sends audio data.

    Request parameters:

    Parameter

    Type

    Description

    service_id

    int

    Link ID.

    format

    lv_audio_format_e

    Audio codec.

    buffer

    unsigned char*

    Audio data.

    buffer_len

    unsigned int

    Audio data length.

    timestamp_ms

    unsigned int

    Audio timestamp.

    Example code:

    // Demo: this function receives audio frames as input
    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

    API name

    API Details

    Description

    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))

    Callback function that queries SD card recording file information.

    Request parameters:

    Parameter

    Type

    Description

    start_time

    unsigned int

    Start time of the recording query.

    stop_time

    unsigned int

    End time of the recording query.

    num

    int

    If less than or equal to zero, indicates all recordings have been queried.

    id

    const char *

    Session ID for the query. Must be returned in the response.

    on_complete

    Function pointer

    Returns query results synchronously through this function.

    Example code:

    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);// Avoid buffer overflow
            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;
    }
  • Live streaming flowchart直播

  • SD card video-on-demand flowchart点播

  • Pre-recorded event video-on-demand flowchart预录

  • Cloud storage

    Cloud storage includes event-triggered and continuous recording scenarios. If you implement live streaming with the SDK, cloud storage is automatically enabled. No additional development is required.

Notes on using video playback APIs:

  • When a forced I-frame command is issued, you must generate the I-frame as quickly as possible, ideally within 300 ms.

  • After a forced I-frame command, you must call lv_stream_send_config again to resend the stream configuration.

  • During SD card recording seek operations, you must send an I-frame as quickly as possible after seeking. The SDK stops accepting audio and P-frame video data until the I-frame arrives.

  • H.264 and H.265 frame structures have specific requirements. You can print the first 256 bytes of an I-frame to verify using the following code.

    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");

    H.264 requires I-frames in the following format: frame delimiter + SPS + frame delimiter + PPS + frame delimiter + IDR, as shown in the following figure.

    I帧

    Frame delimiters are 0x000001 or 0x00000001. SPS starts with 0x67, PPS starts with 0x68, and IDR starts with 0x65.

    H.265 requires I-frames in the following format: frame delimiter + VPS + frame delimiter + SPS + frame delimiter + PPS + frame delimiter + IDR, as shown in the following figure.

    I帧

    Note

    The supported audio codecs are G711A and LC-AAC. For more information about the supported encoding parameters, see the macro definitions in the link_visual_def.h header file.

    When you switch video streams on the same channel, for example, from the main stream to the sub-stream, change the resolution, or switch between H.264 and H.265, you must ensure that the first frame after the switch is an I-frame. Otherwise, visual artifacts may occur.

7. Detailed API reference - Image service

The following APIs support image services.

  • lv_trigger_pic_capture_cb

    API name

    API Details

    Description

    lv_trigger_pic_capture_cb

    typedef int (lv_trigger_pic_capture_cb)(const char *id)

    Notifies the device to start capturing an image.

    Request parameters:

    Parameter

    Type

    Description

    id

    const char *

    Request ID. Must be returned in the response.

  • lv_post_alarm_image

    API name

    Interface description

    Description

    lv_post_alarm_image

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

    Sends an image and alarm event. Use this after an image capture callback or for device-initiated uploads.

    Request parameters:

    Parameter

    Type

    Description

    buffer

    const char *

    Image data.

    buffer_len

    int

    Image data length.

    type

    lv_event_type_e

    Upload type: post-capture callback or device-initiated.

    id

    const char *

    Callback ID for image capture. For device-initiated uploads, pass an empty string or NULL.

Image capture supports two scenarios: app-triggered requests and device-initiated captures that are triggered by event detection.

抓图

Notes on using image service APIs:

  • The maximum image size for an upload is 1 MB.

  • The minimum interval between image uploads is 1 second. More frequent uploads are discarded.

  • The SDK internally saves a copy of each image and maintains a pending upload queue. The queue can hold up to five images. If the network is slow and the queue becomes full, new images are discarded.

  • The SDK does not restrict image formats, as long as the cloud or client devices can parse them. We recommend that you use common formats such as .jpg.

8. Detailed API reference - Voice intercom service

The following APIs support voice intercom services.

  • lv_start_voice_intercom_cb

    API name

    API Details

    Description

    lv_start_voice_intercom_cb

    typedef int (*lv_start_voice_intercom_cb)(int service_id)

    Callback function that notifies your application that a voice intercom link can be established.

    Request parameters:

    Parameter

    Type

    Description

    service_id

    int

    Link ID.

  • lv_voice_intercom_start_service

    API name

    API Details

    Description

    lv_voice_intercom_start_service

    int lv_voice_intercom_start_service(int service_id, const lv_audio_param_s *audio_param)

    Establishes a voice intercom link. Call this after receiving the voice intercom start callback.

    Request parameters:

    Parameter

    Type

    Description

    service_id

    int

    Link ID.

    audio_param

    const lv_audio_param_s *

    Device audio parameter structure.

    Example code:

    // Demo: start_voice_intercom_cb is the actual implementation of lv_start_voice_intercom_cb
    lv_start_voice_intercom_cb = start_voice_intercom_cb;
    
    int start_voice_intercom_cb(int service_id)
    {
        // When a voice intercom request is received, actively start the intercom service
        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

    API name

    API Details

    Description

    lv_stop_voice_intercom_cb

    typedef int (*lv_stop_voice_intercom_cb)(int service_id)

    Callback function that notifies your application that a voice intercom link can be disconnected.

    Request parameters:

    Parameter

    Type

    Description

    service_id

    int

    Link ID.

  • lv_voice_intercom_stop_service

    API name

    API Details

    Description

    lv_voice_intercom_stop_service

    int lv_voice_intercom_stop_service(int service_id)

    Disconnects a voice intercom link. Call this after receiving the voice intercom end callback.

    Request parameters:

    Parameter

    Type

    Description

    service_id

    int

    Link ID.

    Example code:

    // Demo. stop_voice_intercom_cb is the actual implementation of lv_stop_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

    API name

    API Details

    Description

    lv_voice_intercom_receive_metadata_cb

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

    Callback function that notifies your application of the audio format used by the App during voice intercom.

    Request parameters:

    Parameter

    Type

    Description

    service_id

    int

    Link ID.

    audio_param

    const lv_audio_param_s *

    App audio format structure.

  • lv_voice_intercom_receive_data_cb

    API name

    API Details

    Description

    lv_voice_intercom_receive_data_cb

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

    Callback function that delivers audio data sent by the App during voice intercom.

    Request parameters:

    Parameter

    Type

    Description

    buffer

    const char *

    App audio data.

    buffer_len

    int

    App audio data length.

  • lv_voice_intercom_send_audio

    API name

    API Details

    Description

    lv_voice_intercom_send_audio

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

    Sends audio data over a voice intercom link.

    Request parameters:

    Parameter

    Type

    Description

    service_id

    int

    Link ID.

    buffer

    const char *

    Device audio data.

    buffer_len

    int

    Device audio data length.

    timestamp_ms

    unsigned int

    Device audio timestamp.

    Example code:

    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);
    }

Voice intercom flowchart:

对讲

9. What to do next

After you generate the device firmware, you can flash it onto your device and test LinkVisual features using the app. We recommend that you use the public app for testing. For more information, see Introduction to Cloud Intelligence App.