gpt4 book ai didi

c# - 我有一个包含 RTP 数据包 : now what? 的日志文件

转载 作者:太空宇宙 更新时间:2023-11-03 16:33:18 24 4
gpt4 key购买 nike

我有一个日志文件,其中包含来自黑匣子设备的 RTP 数据包。我也有相应的 SDP 文件 (RTSP DESCRIBE)。我需要将此文件转换成某种可播放的视频文件。我可以将这两个文件传递给 FFMpeg 或 VLC 或其他东西,然后让它将这些数据复用成可播放的东西吗?

作为替代计划,我可以在代码中循环遍历各个数据包,并对每个数据包执行一些操作。但是,似乎存在用于解析此数据的现有库。而且它似乎手工完成会要求一个大项目。是否有某种视频文件格式是 SDP 和 RTP 的原始混合?感谢您的宝贵时间。

有没有办法让 FFmpeg 或 VLC 打开一个 SDP 文件,然后通过 STDIN 获取它们的输入数据包?

我通常使用 C#,但如果需要我也可以使用 C。

更新 1:这是我的无效代码。我正在尝试获得某种输出来玩 ffplay,但我还没有任何运气。它给我无效的数据错误。据我所知,它确实正确地遍历了所有数据。我的输出几乎和我的输入一样大(大约 4MB)。

    public class RtpPacket2
{
public byte VersionPXCC;
public byte MPT;
public ushort Sequence; // length?
public uint Timestamp;
public uint Ssrc;
public int Version { get { return VersionPXCC >> 6; } }
public bool Padding { get { return (VersionPXCC & 32) > 0; } }
public bool Extension { get { return (VersionPXCC & 16) > 0; } }
public int CsrcCount { get { return VersionPXCC & 0xf; } } // ItemCount
public bool Marker { get { return (MPT & 0x80) > 0; } }
public int PayloadType { get { return MPT & 0x7f; } } // PacketType
}


static void Main(string[] args)
{
if (args.Length != 2)
{
Console.WriteLine("Usage: <input RTP file> <output 3GP file>");
return;
}
var inputFile = args[0];
var outputFile = args[1];
if(File.Exists(outputFile)) File.Delete(outputFile);

// FROM the SDP : fmtp 96 profile-level-id=4D0014;packetization-mode=0
var sps = Convert.FromBase64String("Z0LAHoiLUFge0IAAA4QAAK/IAQ=="); // BitConverter.ToString(sps) "67-42-C0-1E-88-8B-50-58-1E-D0-80-00-03-84-00-00-AF-C8-01" string
var pps = Convert.FromBase64String("aM44gA=="); // BitConverter.ToString(pps) "68-CE-38-80" string
var sep = new byte[] { 00, 00, 01 };

var packet = new RtpPacket2();
bool firstFrame = true;
using (var input = File.OpenRead(inputFile))
using (var reader = new BinaryReader(input))
using (var output = File.OpenWrite(outputFile))
{
//output.Write(header, 0, header.Length);
output.Write(sep, 0, sep.Length);
output.Write(sps, 0, sps.Length);
output.Write(sep, 0, sep.Length);
output.Write(pps, 0, pps.Length);
output.Write(sep, 0, sep.Length);
while (input.Position < input.Length)
{
var size = reader.ReadInt16();
packet.VersionPXCC = reader.ReadByte();
packet.MPT = reader.ReadByte();
packet.Sequence = reader.ReadUInt16();
packet.Timestamp = reader.ReadUInt32();
packet.Ssrc = reader.ReadUInt32();
if (packet.PayloadType == 96)
{
if (packet.CsrcCount > 0 || packet.Extension) throw new NotImplementedException();

var header0 = reader.ReadByte();
var header1 = reader.ReadByte();

var fragmentType = header0 & 0x1F; // should be 28 for video
if(fragmentType != 28) // 28 for video?
{
input.Position += size - 14;
continue;
}
var nalUnit = header0 & ~0x1F;
var nalType = header1 & 0x1F;
var start = (header1 & 0x80) > 0;
var end = (header1 & 0x40) > 0;

if(firstFrame)
{
output.Write(sep, 0, sep.Length);
output.WriteByte((byte)(nalUnit | fragmentType));
firstFrame = false;
}

for (int i = 0; i < size - 14; i++)
output.WriteByte(reader.ReadByte());
if (packet.Marker)
firstFrame = true;
}
else input.Position += size - 12;
}
}
}

最佳答案

http://www.bogotobogo.com/VideoStreaming/videostreaming_etc.php

远离在数据包级别做任何事情,因为您可能会陷入编码流如何打包的细节中。

通过上面的链接查看。 SDP/RTP/RTSP 流媒体是非常复杂的协议(protocol),当您尝试将它们直接连接到期望只打开本地媒体文件的播放器时,这些协议(protocol)通常不起作用。

如果您正在处理流并且想要从流中保存文件,您可能需要使用任何大型媒体项目(ffmpeg、vlc、live555、openrtsp)在 google 上搜索“filesinks”,因为这些项目已经有开源 fileSink实现(C、C++)。

例如,在 live555 中,所有编解码器在 ./live/liveMedia 目录中都有 fileSink 实现。

如果您有来自 SDP 源的流,则可以使用该轨道使用的编解码器的 fileSink 处理每个轨道(音频、视频)。然后您可以将这些轨道混合到播放器或独立播放轨道。

关于c# - 我有一个包含 RTP 数据包 : now what? 的日志文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10078873/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com