Hello Stack Overflow community,
I'm attempting to develop a video recording application using Node.js. I'm trying to record and play back VP8 streams within RTP data sent over Siprec using UDP. However, it seems like I'm encountering issues either while parsing RTP packets or at some other step, and I'm unable to successfully extract, combine, and play the received packets as a video.
I've broken down my process into several steps:
RTP Parsing Saving Packets to a File Combining Packets Converting the Combined File Playback However, I'm facing issues in one of these steps. I either can't parse the payload correctly, or there might be some other problem that I'm not aware of.
Below, you can find some different functions I've tried:
[You can insert any code snippets or error messages you'd like to add here.]
I'm looking for assistance in resolving my issue. Thank you!
SDP Data:
Content-Type: application/sdp
v=0
o=MySiprecServer 672778243 713822205 IN IP4 192.168.0.205
s=SBC-Call
c=IN IP4 192.168.0.205
t=0 0
m=audio 8040 RTP/AVP 8 101
c=IN IP4 192.168.0.205
a=ptime:20
a=sendonly
a=label:1
a=mid:2
a=rtcp-mux
a=rtcp:8041 IN IP4 192.168.0.205
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15,16
m=audio 8045 RTP/AVP 8 101
c=IN IP4 192.168.0.205
a=ptime:20
a=sendonly
a=label:2
a=mid:3
a=rtcp-mux
a=rtcp:8046 IN IP4 192.168.0.205
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15,16
m=video 8000 RTP/AVP 96
c=IN IP4 192.168.0.205
a=rtcp:8001 IN IP4 192.168.0.205
a=mid:1
a=extmap:14 urn:ietf:params:rtp-hdrext:toffset
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:13 urn:3gpp:video-orientation
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type
a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing
a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
a=sendonly
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:96 VP8/90000
a=rtcp-fb:96 goog-remb
a=rtcp-fb:96 transport-cc
a=rtcp-fb:96 ccm fir
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli
a=ssrc:4115522635 cname:Z2Ddcyd5sthBDaqs
a=label:3
m=video 8005 RTP/AVP 96
a=sendonly
a=rtpmap:96 vp8/90000
a=label:4
a=mid:4
a=rtcp-mux
a=rtcp:8006 IN IP4 192.168.0.205
this is my code attempt:
const fs = require('fs');
const path = require('path');
const dgram = require('dgram');
const server = dgram.createSocket('udp4');
function parseRtpPacket(buffer) {
// RTP Header Fields
const version = (buffer[0] >> 6) & 0x03;
const padding = (buffer[0] >> 5) & 0x01;
const extension = (buffer[0] >> 4) & 0x01;
const csrcCount = buffer[0] & 0x0F;
const marker = (buffer[1] >> 7) & 0x01;
const payloadType = buffer[1] & 0x7F;
const sequenceNumber = buffer.readUInt16BE(2);
const timestamp = buffer.readUInt32BE(4);
const ssrc = buffer.readUInt32BE(8);
// Calculate the RTP header size
let headerSize = 12 + 4 * csrcCount;
// Check if there's an extension header
if (extension === 1) {
const extensionLength = buffer.readUInt16BE(headerSize + 2);
headerSize += 4 + extensionLength * 4;
}
// VP8 Frame
const vp8Frame = buffer.slice(headerSize);
// Save to file (example)
//fs.writeFileSync(`frame_${sequenceNumber}.bin`, vp8Frame);
return {
version,
padding,
extension,
csrcCount,
marker,
payloadType,
sequenceNumber,
timestamp,
ssrc,
vp8Frame
};
}
const receivedData = JSON.parse(process.argv[2]);
const { Command, CallID, ChannelPort } = receivedData
console.log("Komut: " + Command + " CallID: " + CallID + " ChannelPort: " + ChannelPort);
if (Command == 'start') {
// listen udp socket
server.on('message', (msg, rinfo) => {
const parsedPacket = parseRtpPacket(msg);
console.log(`Received RTP packet from ${rinfo.address}:${rinfo.port}`);
console.log(parsedPacket);
const ssrc = parsedPacket.ssrc.toString();
const sequenceNumber = parsedPacket.sequenceNumber.toString();
const mainDirPath = path.join('calls', CallID.toString());
const portDirPath = path.join(mainDirPath, ChannelPort.toString());
if (!fs.existsSync(portDirPath)) {
fs.mkdirSync(portDirPath);
}
// const filePath = path.join(ssrc, `${sequenceNumber}.bin`);
const filePath = path.join(portDirPath, `${sequenceNumber}.bin`);
fs.writeFileSync(filePath, parsedPacket.vp8Frame);
});
server.on('listening', () => {
const address = server.address();
console.log(`UDP Server listening on ${address.address}:${address.port}`);
});
// listen 5000 port
server.bind(ChannelPort);
} else if (Command == 'stop') {
console.log("stopped");
} else { }