我們在上一期使用RTP協議,並進行了配置,打包了視頻數據,這一期我們就對發送的數據進行重組,並顯示在接受端上。最后對其進行擴展,支持多客戶端視頻發送,並在接收端分屏顯示。完成遠程監控的模擬。
先來個效果圖吧

private bool NewRTPPacket(RTPPacket packet)
{
if (!Clients.ContainsKey(packet.SSRC))//如果接受端第一次接受到某源的數據,則加入到
{
if (Clients.Count < 4)//如果發送端為4,則丟棄包
{
Clients.Add(packet.SSRC, new List<RTPPacket> {packet});
ImagesBoxMapping[ImagesBoxMapping.First(pair => pair.Value == null).Key] = packet.SSRC;
}
}
else
{
Clients[packet.SSRC].Add(packet);
}
if (packet.Marker)//如果已經發送完畢
{
//丟包檢測
var orderPackets = Clients[packet.SSRC].OrderBy(rtpPacket => rtpPacket.SequenceNumber);
if (Clients[packet.SSRC].Count != (orderPackets.Last().SequenceNumber - orderPackets.First().SequenceNumber + 1))
{
Clients[packet.SSRC].Clear();//清空緩存區
return true;
}
//1.包重組
var count = Clients[packet.SSRC].Sum(rtpPacket => rtpPacket.DataSize);//數據總數
var newData = new byte[count];
long offSet = 0;
foreach (var rtpPacket in Clients[packet.SSRC])
{
Array.Copy(rtpPacket.DataPointer, 0, newData, offSet, rtpPacket.DataSize);
offSet += rtpPacket.DataSize;
}
Clients[packet.SSRC].Clear();//清空緩存區
var ms = new MemoryStream(newData);
try
{
var bmp = new Bitmap(Image.FromStream(ms));
var img = new Image<Bgr, Byte>(bmp);
ImagesBoxMapping.First(pair => pair.Value == packet.SSRC).Key.Image = img;
}
catch (Exception)
{
}
finally
{
ms.Close();
}
}
return true;
}
完整代碼可以到百度雲下載:包括發送端和接收端
