V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wodong
V2EX  ›  程序员

大疆 PSDK 获取视频流技术求助

  •  
  •   wodong · 2023-04-14 10:53:47 +08:00 · 1117 次点击
    这是一个创建于 588 天前的主题,其中的信息可能已经有所发展或是发生改变。
    本人在开发大疆 PSDK 时遇到了视频流数据是一个 const uint8* buf 的裸流缓存数据,音视频才入门的小白不知道应该如何解析出来了。
    需求是将这个 buf 推送到 rtmp 服务器进行显示

    相关函数如下:

    static void LiveviewConvertH264ToRgbCallback(E_DjiLiveViewCameraPosition position, const uint8_t* buf, uint32_t bufLen) {


    }
    2 条回复    2023-04-14 14:35:31 +08:00
    Zoozy
        1
    Zoozy  
       2023-04-14 12:10:34 +08:00
    在这个函数中,您需要使用 RTMP 协议将 H264 编码的裸流数据推送到 RTMP 服务器上,以便在视频播放器中显示。

    以下是可能的实现方式:

    ```c++
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <ctime>
    #include <cmath>
    #include <algorithm>
    #include <sstream>

    #include "librtmp/rtmp.h"

    #define RTMP_HEAD_SIZE (sizeof(RTMPPacket)+RTMP_MAX_HEADER_SIZE)

    static void LiveviewConvertH264ToRgbCallback(E_DjiLiveViewCameraPosition position, const uint8_t* buf, uint32_t bufLen) {

    static RTMP *rtmp = NULL;
    static char *url = "rtmp://your-rtpm-server-url.com/live/stream";
    static int fps = 30;
    static int width = 1280;
    static int height = 720;

    if (!rtmp) {
    rtmp = RTMP_Alloc();
    RTMP_Init(rtmp);
    rtmp->Link.timeout = 5; // Timeout in seconds
    RTMP_SetupURL(rtmp, url);
    RTMP_EnableWrite(rtmp);
    RTMP_SetBufferMS(rtmp, 3600*1000); // Set the buffer size to 1 hour
    if (!RTMP_Connect(rtmp, NULL) || !RTMP_ConnectStream(rtmp, 0)) {
    RTMP_Free(rtmp);
    rtmp = NULL;
    std::cerr << "Failed to connect to RTMP server" << std::endl;
    return;
    }
    }

    // Create and initialize RTMP packet
    RTMPPacket packet = {0};
    RTMPPacket_Alloc(&packet, bufLen + RTMP_HEAD_SIZE);

    packet.m_packetType = RTMP_PACKET_TYPE_VIDEO;
    packet.m_nChannel = 0x04;

    // Fill in the packet headers
    char *data_ptr = packet.m_body;
    data_ptr[0] = 0x17; // Video codec id: 7 (AVC)
    data_ptr[1] = 0x01; // AVCPacketType: 1 (NALU without length field)
    *((uint32_t *)(data_ptr + 2)) = 0x01000000; // Composition time offset: 0
    std::memcpy(data_ptr + 6, buf, bufLen);

    packet.m_nTimeStamp = RTMP_GetTime() - RTMP_GetStartTime(rtmp);
    packet.m_nBodySize = bufLen + 5;

    if (!RTMP_SendPacket(rtmp, &packet, TRUE)) {
    std::cerr << "Failed to send packet to RTMP server" << std::endl;
    }

    // Free memory used by packet
    RTMPPacket_Free(&packet);
    }
    ```
    在此实现中,我们使用 librtmp 库来完成 RTMP 协议的推流。在函数中的第一个参数 position 未被使用,因为它不需要对这个问题产生任何影响。

    该代码假定你已经熟练掌握了 RTMP 协议和使用方法,并且服务器配置正确。

    by gpt
    wodong
        2
    wodong  
    OP
       2023-04-14 14:35:31 +08:00
    @Zoozy 感谢好兄弟,确实可以,只是头部显示会有一堆马赛克
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3456 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 05:03 · PVG 13:03 · LAX 21:03 · JFK 00:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.