this is a gstreamer plugin:

#include 
#include 
#include 
#include 

/\* Forward declarations \*/
typedef struct \_GstMyRtpHdrExt GstMyRtpHdrExt;
typedef struct \_GstMyRtpHdrExtClass GstMyRtpHdrExtClass;

static void gst\_my\_rtp\_hdr\_ext\_class\_init(GstMyRtpHdrExtClass \*klass);
static void gst\_my\_rtp\_hdr\_ext\_init(GstMyRtpHdrExt \*my\_rtp\_hdr\_ext);
static GstFlowReturn gst\_my\_rtp\_hdr\_ext\_transform\_ip(GstBaseTransform \*trans, GstBuffer \*buf);

/\* Define the GstMyRtpHdrExt structure \*/
struct \_GstMyRtpHdrExt
{
 GstBaseTransform base\_transform;
};

struct \_GstMyRtpHdrExtClass
{
 GstBaseTransformClass parent\_class;
};

/\* Register the element \*/
#define GST\_TYPE\_MY\_RTP\_HDR\_EXT (gst\_my\_rtp\_hdr\_ext\_get\_type())
#define GST\_MY\_RTP\_HDR\_EXT(obj) (G\_TYPE\_CHECK\_INSTANCE\_CAST((obj), GST\_TYPE\_MY\_RTP\_HDR\_EXT, GstMyRtpHdrExt))
G\_DEFINE\_TYPE(GstMyRtpHdrExt, gst\_my\_rtp\_hdr\_ext, GST\_TYPE\_BASE\_TRANSFORM);

/\* Pad templates \*/
static GstStaticPadTemplate sink\_template = GST\_STATIC\_PAD\_TEMPLATE("sink",
 GST\_PAD\_SINK,
 GST\_PAD\_ALWAYS,
 GST\_STATIC\_CAPS("application/x-rtp"));

static GstStaticPadTemplate src\_template = GST\_STATIC\_PAD\_TEMPLATE("src",
 GST\_PAD\_SRC,
 GST\_PAD\_ALWAYS,
 GST\_STATIC\_CAPS("application/x-rtp"));

/\* Initialize the class \*/
static void gst\_my\_rtp\_hdr\_ext\_class\_init(GstMyRtpHdrExtClass \*klass)
{
 GstElementClass \*element\_class = GST\_ELEMENT\_CLASS(klass);
 GstBaseTransformClass \*base\_transform\_class = GST\_BASE\_TRANSFORM\_CLASS(klass);

 gst\_element\_class\_set\_static\_metadata(element\_class,
 "My RTP Header Extension Element",
 "Filter/Effect",
 "A GStreamer element that adds an RTP header extension to packets",
 "CarlosC");

 base\_transform\_class->transform\_ip = GST\_DEBUG\_FUNCPTR(gst\_my\_rtp\_hdr\_ext\_transform\_ip);

 // Add pad templates
 gst\_element\_class\_add\_pad\_template(element\_class,
 gst\_static\_pad\_template\_get(&sink\_template));
 gst\_element\_class\_add\_pad\_template(element\_class,
 gst\_static\_pad\_template\_get(&src\_template));
}

/\* Initialize the element instance \*/
static void gst\_my\_rtp\_hdr\_ext\_init(GstMyRtpHdrExt \*my\_rtp\_hdr\_ext)
{
 // No initialization needed in this example
}

/\* Implement the in-place transform \*/
static GstFlowReturn gst\_my\_rtp\_hdr\_ext\_transform\_ip(GstBaseTransform \*trans, GstBuffer \*buf)
{
 GstRTPBuffer rtp\_buffer = GST\_RTP\_BUFFER\_INIT;
 guint16 ext\_id = 1; // RTP header extension id, change it according to your use case
 const gchar \*default\_data = "1234567890123456";
 guchar \*data = (guchar \*)default\_data;
 gsize data\_size = strlen(default\_data);

 if (!gst\_rtp\_buffer\_map(buf, GST\_MAP\_READWRITE, &rtp\_buffer))
 {
 GST\_ERROR\_OBJECT(trans, "Failed to map RTP buffer");
 return GST\_FLOW\_ERROR;
 }

 if (!gst\_rtp\_buffer\_add\_extension\_onebyte\_header(&rtp\_buffer, ext\_id, data, data\_size))
 {
 GST\_ERROR\_OBJECT(trans, "Failed to add RTP header extension");
 gst\_rtp\_buffer\_unmap(&rtp\_buffer);
 return GST\_FLOW\_ERROR;
 }

 gst\_rtp\_buffer\_unmap(&rtp\_buffer);
 return GST\_FLOW\_OK;
}

/\* Register the plugin \*/
#define PACKAGE "myrtpheaderextensionplugin"
static gboolean
plugin\_init(GstPlugin \*plugin)
{
 return gst\_element\_register(plugin, "myrtpheaderextension", GST\_RANK\_NONE, GST\_TYPE\_MY\_RTP\_HDR\_EXT);
}

GST\_PLUGIN\_DEFINE(
 GST\_VERSION\_MAJOR,
 GST\_VERSION\_MINOR,
 myrtpheaderextensionplugin,
 "My RTP Header Extension Element",
 plugin\_init,
 "1.0",
 "LGPL",
 "MyGStreamer",
 "http://gstreamer.net/")
it sends rtp header extensions. In this case is a one byte, but this could could be differetnt.
const dgram = require('dgram');

// Create a UDP socket to receive the RTP stream
const socket = dgram.createSocket('udp4');
socket.bind(5004);

// Event handler for when a new message is received
socket.on('message', (msg, rinfo) => {
 // Parse the RTP packet header
 const version = (msg[0] & 0xC0) >> 6;
 const padding = (msg[0] & 0x20) >> 5;
 const extension = (msg[0] & 0x10) >> 4;
 const cc = msg[0] & 0x0F;
 const marker = (msg[1] & 0x80) >> 7;
 const pt = msg[1] & 0x7F;
 const seq = msg.readUInt16BE(2);
 const timestamp = msg.readUInt32BE(4);
 const ssrc = msg.readUInt32BE(8);

 // Log the RTP timestamp
 console.log(`RTP timestamp: ${timestamp}`);

 // Check if the packet contains header extensions
 if (extension === 1) {
 // Extract the extension data
 const extensionLengthFieldOffset = 4 + (cc \* 4); // Offset of the extension length field in the RTP header
 const extensionBitMask = 0x10; // Mask for the extension bit

 if ((msg[0] & extensionBitMask) !== 0) {
 const extensionLengthFieldOffset = 4 + (cc \* 4) + 2; // Offset of the extension length field in the RTP header
 const extensionLength = msg.readUInt8(extensionLengthFieldOffset); // Length of the extension header in bytes
 const extensionData = msg.slice(extensionLengthFieldOffset + 4, extensionLengthFieldOffset + 4 + extensionLength);
 
 console.log(extensionLength)
 // Log the extension data as a string
 console.log(`Extension data: ${extensionData.toString('utf-8')}`);
 }
 }
});

I want a code that parse those rtp packets, and prints each and eveyone of the rtp specficiation fields in that packet. Use node and dgram for instance. No external libraies
이것은 스트리머 플러그인입니다:#포함 #포함 #포함 #include /\* 포워드 선언 \*/typedef 구조체 \_GstMyRtpHdrExt GstMyRtpHdrExt;typedef 구조체 \_GstMyRtpHdrExtClass GstMyRtpHdrExtClass;static void gst\_my\_rtp\_hdr\_ext\_class\_init(GstMyRtpHdrExtClass \*klass);static void gst\_my\_rtp\_hdr\_ext\_init(GstMyRtpHdrExt \*my\_rtp\_hdr\_ext);static GstFlowReturn gst\_my\_rtp\_hdr\_ext\_transform\_ip(GstBaseTransform \*trans, GstBuffer \*buf);/\* GstMyRtpHdrExt 구조체 정의 \*/구조체 \_GstMyRtpHdrExt{ GstBaseTransform base\_transform;};구조체 \_GstMyRtpHdrExtClass{ GstBaseTransformClass 부모\_class;};/\* 요소 등록 \*/#define GST\_TYPE\_MY\_RTP\_HDR\_EXT (gst\_my\_rtp\_hdr\_ext\_get\_type())#GST\_MY\_RTP\_HDR\_EXT(obj) (G\_TYPE\_CHECK\_INSTANCE\_CAST((obj), GST\_TYPE\_MY\_RTP\_HDR\_EXT, GstMyRtpHdrExt))G\_DEFINE\_TYPE(GstMyRtpHdrExt, gst\_my\_rtp\_hdr\_ext, GST\_TYPE\_BASE\_TRANSFORM);/\* 패드 템플릿 \*/static GstStaticPadTemplate sink\_template = GST\_STATIC\_PAD\_TEMPLATE("싱크", GST\_PAD\_SINK, GST\_PAD\_ALWAYS, GST\_STATIC\_CAPS("application/x-rtp"));static GstStaticPadTemplate src\_template = GST\_STATIC\_PAD\_TEMPLATE("src", GST\_PAD\_SRC, GST\_PAD\_ALWAYS, GST\_STATIC\_CAPS("application/x-rtp"));/\* 클래스 초기화 \*/static void gst\_my\_rtp\_hdr\_ext\_class\_init(GstMyRtpHdrExtClass \*klass){ GstElementClass \*element\_class = GST\_ELEMENT\_CLASS(klass); GstBaseTransformClass \*base\_transform\_class = GST\_BASE\_TRANSFORM\_CLASS(klass); GST\_ELEMENT\__CLASS\_SET\_STATIC\_METADATA(ELEMENT\__CLASS, "내 RTP 헤더 확장 요소", "필터/효과", "패킷에 RTP 헤더 확장자를 추가하는 GStreamer 엘리먼트", "CarlosC"); base\_transform\_class->transform\_ip = GST\_DEBUG\_FUNCPTR(gst\_my\_rtp\_hdr\_ext\_transform\_ip); // 패드 템플릿 추가 gst\_element\_class\_add\_pad\_template(element\_class, gst\_static\_pad\_template\_get(&sink\_template)); gst\_element\_class\_add\_pad\_template(element\_class, gst\_static\_pad\_template\_get(&src\_template));}/\* 엘리먼트 인스턴스 초기화 \*/static void gst\_my\_rtp\_hdr\_ext\_init(GstMyRtpHdrExt \*my\_rtp\_hdr\_ext){ // 이 예제에서는 초기화 필요 없음}/\* 인 플레이스 트랜스폼 구현 \*/static GstFlowReturn gst\_my\_rtp\_hdr\_ext\_transform\_ip(GstBaseTransform \*trans, GstBuffer \*buf){ GstRTP버퍼 rtp\_buffer = GST\_RTP\_BUFFER\_INIT; guint16 ext\_id = 1; // RTP 헤더 확장 ID, 사용 사례에 따라 변경하세요. const gchar \*기본값\_data = "1234567890123456"; 구차 \*데이터 = (구차 \*)기본값\_data; gsize data\_size = strlen(default\_data); if (!gst\_rtp\_buffer\_map(buf, GST\_MAP\_READWRITE, &rtp\_buffer)) { GST\_ERROR\_OBJECT(trans, "RTP 버퍼 매핑에 실패했습니다"); 반환 GST\_FLOW\_ERROR; } if (!gst\_rtp\_buffer\_add\_extension\_onebyte\_header(&rtp\_buffer, ext\_id, data, data\_size)) { GST\_ERROR\_OBJECT(trans, "RTP 헤더 확장자를 추가하지 못했습니다"); GST\_RTP\_BUFFER\_UNMAP(&RTP\_BUFFER); 반환 GST\_FLOW\_ERROR; } GST\_RTP\_BUFFER\_UNMAP(&RTP\_BUFFER); 반환 GST\_FLOW\_OK;}/\* 플러그인 등록 \*/#define PACKAGE "myrtpheaderextensionplugin"정적 gbooleanplugin\_init(GstPlugin \*plugin){ return gst\_element\_register(plugin, "myrtpheaderextension", GST\_RANK\_NONE, GST\_TYPE\_MY\_RTP\_HDR\_EXT);}GST\_PLUGIN\_DEFINE( GST\_VERSION\_MAJOR, GST\_VERSION\_MINOR, myrtpheaderextensionplugin, "내 RTP 헤더 확장 요소", plugin\_init, "1.0", "LGPL", "MyGStreamer", "http://gstreamer.net/")는 RTP 헤더 확장자를 전송합니다. 이 경우 1바이트이지만 다를 수 있습니다.const dgram = require('dgram');// RTP 스트림을 수신할 UDP 소켓을 생성합니다.const socket = dgram.createSocket('udp4');socket.bind(5004);// 새 메시지 수신 시 이벤트 처리기socket.on('message', (msg, rinfo) => { // RTP 패킷 헤더를 파싱합니다. const version = (msg[0] & 0xC0) >> 6; const padding = (msg[0] & 0x20) >> 5; const extension = (msg[0] & 0x10) >> 4; const cc = msg[0] & 0x0F; const marker = (msg[1] & 0x80) >> 7; const pt = msg[1] & 0x7F; const seq = msg.readUInt16BE(2); const timestamp = msg.readUInt32BE(4); const ssrc = msg.readUInt32BE(8); // RTP 타임스탬프 기록 console.log(`RTP 타임스탬프: ${timestamp}`); // 패킷에 헤더 확장자가 포함되어 있는지 확인합니다. if (extension === 1) { // 확장자 데이터 추출 const extensionLengthFieldOffset = 4 + (cc \* 4); // RTP 헤더의 확장자 길이 필드 오프셋 const extensionBitMask = 0x10; // 확장 비트에 대한 마스크 if ((msg[0] & extensionBitMask) !== 0) { const extensionLengthFieldOffset = 4 + (cc \* 4) + 2; // RTP 헤더의 확장 길이 필드 오프셋 const extensionLength = msg.readUInt8(extensionLengthFieldOffset); // 확장 헤더의 길이(바이트) const extensionData = msg.slice(extensionLengthFieldOffset + 4, extensionLengthFieldOffset + 4 + extensionLen)