You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Golang从RTP包提取Parrot Anafi AI无人机Protobuf元数据

从Parrot RTP包中提取TimedMetadata Protobuf负载失败

我在用Golang从RTP抓包文件(data.pcapng)中提取Parrot TimedMetadata的Protobuf负载时遇到了极大困难,按照Parrot官方开发指南操作始终无法成功。

以下是我的main.go代码:

package main

import (
    "encoding/binary"
    "fmt"
    "log"
    "os"

    "github.com/gopacket/gopacket"
    "github.com/gopacket/gopacket/pcap"
    "github.com/pion/rtp"
    "<my_module>/vmeta"
    "google.golang.org/protobuf/proto"
)

func main() {
    h, err := pcap.OpenOffline("data.pcapng")
    if err != nil {
        log.Fatalf("failed to open file: %v", err)
    }
    outputFile, err := os.Create("out.txt")
    if err != nil {
        log.Fatalf("failed to create save file: %v", err)
    }
    defer outputFile.Close()
    ps := gopacket.NewPacketSource(h, h.LinkType())
    i := 0

    for packet := range ps.Packets() {
        layer := packet.TransportLayer()
        if layer == nil {
            continue
        }
        payload := packet.TransportLayer().LayerPayload()
        rtpPacket := rtp.Packet{}
        err = rtpPacket.Unmarshal(payload)
        if err != nil {
            continue
        }
        i++
        if !rtpPacket.Extension {
            continue // no extension header
        }
        if err := parse(payload); err == nil {
            log.Println("Success !")
            os.Exit(0)
        }
    }
}

func parse(data []byte) error {
    n := 12 // skip fixed size header
    log.Printf("Initial buffer: %x", data)
    version := data[n : n+2]
    n += 2
    log.Printf("Defined by profile: 0x%x\n", version) // 0x5062 here, so no pb
    length := binary.BigEndian.Uint16(data[n : n+2])
    n += 2
    log.Printf("Length: %d\n", length)
    packIndicator := binary.BigEndian.Uint16(data[n : n+2])
    lastPack := (packIndicator >> 9) & 0x7f
    curPack := (packIndicator >> 2) & 0x7f
    padding := (packIndicator >> 0) & 0x03
    n += 2
    log.Printf("Packet: %d/%d\n", curPack, lastPack)
    log.Printf("Padding: %d\n", padding)
    offset := binary.BigEndian.Uint16(data[n : n+2])
    n += 2
    log.Printf("Offset: %d\n", offset)
    rawData := data[n : uint16(n)+(4*length)]
    log.Printf("RawData: %x", rawData)

    model := vmeta.TimedMetadata{}
    if err := proto.Unmarshal(rawData, &model); err != nil {
        return fmt.Errorf("failed to deserialize: %v", err)
    }

    return nil
}

目前遇到的具体问题:

  • 代码始终无法成功解析Protobuf负载,操作从未返回成功
  • 尝试用Wireshark提取并解码相关数据也失败
  • 参考了Parrot开源的libvideo-streaming源码,尝试跳过扩展头前两个字节后仍无效果
  • 不清楚padding字段的具体用法,Parrot官方文档中未提及该字段的说明

有没有人做过类似的开发,能提供一些解决思路?

内容的提问来源于stack exchange,提问作者user29960667

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 22:25:14