ndi 推流拉流

流媒体协议详解_步基的博客-CSDN博客

ndi tools下载,需注册账号才能下载。需要的朋友可以私信。

ndi5 sdk,有win版和linux版,以下截图是win版

ndi receive

#include <cstdio>
#include <chrono>
#include <Processing.NDI.Advanced.h>

#ifdef _WIN32
#ifdef _WIN64
#pragma comment(lib, "Processing.NDI.Lib.Advanced.x64.lib")
#else // _WIN64
#pragma comment(lib, "Processing.NDI.Lib.Advanced.x86.lib")
#endif // _WIN64
#endif // _WIN32

int main(int argc, char* argv[])
{    // Not required, but "correct" (see the SDK documentation.
    if (!NDIlib_initialize()) return 0;
    
    // Create a finder
    NDIlib_find_instance_t pNDI_find = NDIlib_find_create_v2();
    if (!pNDI_find) return 0;

    // Wait until there is one source
    uint32_t no_sources = 0;
    const NDIlib_source_t* p_sources = NULL;
    while (!no_sources)
    {    // Wait until the sources on the nwtork have changed
        printf("Looking for sources ...\n");
        NDIlib_find_wait_for_sources(pNDI_find, 1000/* One second */);
        p_sources = NDIlib_find_get_current_sources(pNDI_find, &no_sources);
    }

    // We now have at least one source, so we create a receiver to look at it.
    NDIlib_recv_instance_t pNDI_recv = NDIlib_recv_create_v3();
    if (!pNDI_recv) return 0;

    // Connect to our sources
    NDIlib_recv_connect(pNDI_recv, p_sources + 0);

    // Destroy the NDI finder. We needed to have access to the pointers to p_sources[0]
    NDIlib_find_destroy(pNDI_find);    

    // Run for one minute
    using namespace std::chrono;
    for (const auto start = high_resolution_clock::now(); high_resolution_clock::now() - start < minutes(5);)
    {    // The descriptors
        NDIlib_video_frame_v2_t video_frame;
        NDIlib_audio_frame_v2_t audio_frame;

        switch (NDIlib_recv_capture_v2(pNDI_recv, &video_frame, &audio_frame, nullptr, 5000))
        {    // No data
            case NDIlib_frame_type_none:
                printf("No data received.\n");
                break;

            // Video data
            case NDIlib_frame_type_video:
                printf("Video data received (%dx%d).\n", video_frame.xres, video_frame.yres);
                NDIlib_recv_free_video_v2(pNDI_recv, &video_frame);
                break;

            // Audio data
            case NDIlib_frame_type_audio:
                printf("Audio data received (%d samples).\n", audio_frame.no_samples);
                NDIlib_recv_free_audio_v2(pNDI_recv, &audio_frame);
                break;
        }
    }

    // Destroy the receiver
    NDIlib_recv_destroy(pNDI_recv);

    // Not required, but nice
    NDIlib_destroy();

    // Finished
    return 0;
}
 

ndi send

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <chrono>
#include <Processing.NDI.Advanced.h>

#ifdef _WIN32
#ifdef _WIN64
#pragma comment(lib, "Processing.NDI.Lib.Advanced.x64.lib")
#else // _WIN64
#pragma comment(lib, "Processing.NDI.Lib.Advanced.x86.lib")
#endif // _WIN64
#endif // _WIN32

int main(int argc, char* argv[])
{    // Not required, but "correct" (see the SDK documentation.
    if (!NDIlib_initialize()) return 0;
    
    // We create the NDI sender
    NDIlib_send_instance_t pNDI_send = NDIlib_send_create();
    if (!pNDI_send) return 0;

    // We are going to create a 1920x1080 interlaced frame at 29.97Hz.
    NDIlib_video_frame_v2_t NDI_video_frame;
    NDI_video_frame.xres = 1920;
    NDI_video_frame.yres = 1080;
    NDI_video_frame.FourCC = NDIlib_FourCC_type_BGRX;
    NDI_video_frame.p_data = (uint8_t*)malloc(NDI_video_frame.xres*NDI_video_frame.yres * 4);

    // Run for one minute
    using namespace std::chrono;
    for (const auto start = high_resolution_clock::now(); high_resolution_clock::now() - start < minutes(5);)
    {    // Get the current time
        const auto start_send = high_resolution_clock::now();

        // Send 200 frames
        for (int idx = 200; idx; idx--)
        {    // Fill in the buffer. It is likely that you would do something much smarter than this.
            memset((void*)NDI_video_frame.p_data, (idx & 1) ? 255 : 0, NDI_video_frame.xres*NDI_video_frame.yres * 4);

            // We now submit the frame. Note that this call will be clocked so that we end up submitting at exactly 29.97fps.
            NDIlib_send_send_video_v2(pNDI_send, &NDI_video_frame);
        }

        // Just display something helpful
        printf("200 frames sent, at %1.2ffps\n", 200.0f / duration_cast<duration<float>>(high_resolution_clock::now() - start_send).count());
    }

    // Free the video frame
    free(NDI_video_frame.p_data);

    // Destroy the NDI sender
    NDIlib_send_destroy(pNDI_send);

    // Not required, but nice
    NDIlib_destroy();

    // Success
    return 0;
}

小结:

1 ndi sdk提供了多个demo,如果要实现产品化,需要自行添加处理逻辑。比如本人的项目中添加了定时扫描ndi source上线下线,动态管理各ndi source的状态。

2 其次要注意recv video,audio frame之后,要free释放堆内存,否则运行一段时间,内存泄露,导致程序异常崩溃。

3 如果部署云端(服务端和客户端在云端的同一局域网内),find ndi时,接收端需要设置发送到的ip地址列表,逗号分隔。局域网内设置ip list,都能接收到局域网内所有ndi source。

4 send ndi,可以设置ndi名称,比如设置output1,ndi tools monitor工具查看,

ubuntu (output1),ubuntu是机器名,自动加的。

5 同一台主机,可能有多个ndi source

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
安装NDI SDK的教程如下: 1. 首先,你需要前往NDI SDK的官方网站下载完整的SDK。你可以在https://www.newtek.com/ndi/sdk/找到下载链接。点击下载链接,然后选择适合你操作系统的版本进行下载。 2. 下载完成后,解压缩SDK文件到你想要安装的目录。 3. 打开你的开发环境,比如Visual Studio等。 4. 在你的项目中,找到你的main函数所在的文件。 5. 在main函数的开头,添加以下代码来初始化NDI库: ```c++ if (!NDIlib_initialize()) return 0; ``` 这段代码会初始化NDI库,确保你的程序可以正常使用NDI功能。 6. 如果你需要使用NDI的发现功能,你可以在main函数中添加以下代码来创建一个NDI发现实例: ```c++ NDIlib_find_instance_t pNDI_find = NDIlib_find_create_v2(); if (!pNDI_find) return 0; ``` 这段代码会创建一个NDI发现实例,用于搜索和连接到NDI设备。 7. 如果你需要使用NDI的发送功能,你可以在main函数中添加以下代码来创建一个NDI发送实例: ```c++ NDIlib_send_instance_t pNDI_send = NDIlib_send_create(); if (!pNDI_send) return 0; ``` 这段代码会创建一个NDI发送实例,用于发送视频和音频数据。 8. 现在,你可以根据你的需求在main函数中继续编写你的代码,使用NDI SDK提供的功能。 请注意,以上代码只是示例,你需要根据你的具体情况进行适当的修改和调整。此外,为了正确使用NDI SDK,你还需要阅读SDK文档,并遵守SDK许可条款。 希望这个教程对你有帮助!如果你有任何其他问题,请随时提问。 #### 引用[.reference_title] - *1* [NDI技术实践与应用](https://blog.csdn.net/u014162133/article/details/103309780)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [ndi 推流拉流](https://blog.csdn.net/wangbuji/article/details/123012285)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

步基

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值