当前位置: 首页 > 知识库问答 >
问题:

如何将H264 RTP流从PCAP转换为可播放的视频文件

赏光霁
2023-03-14

我在PCAP文件中捕获了H264流,并试图从数据中创建媒体文件。容器并不重要(avi、mp4、mkv、...)。
当我使用Videosnarf或rtpbref(结合在每个数据包之前添加00 00 00 01的python代码)然后ffmpeg时,只有当输入帧率恒定(或接近恒定)时,结果才OK。但是,当输入为vfr时,结果播放得太快(在同样罕见的情况下太慢)。
例如:

videosnarf-我捕捉到了。pcap–c ffmpeg-i H264-media-1.264输出。avi公司

在对这个问题进行了一些调查之后,我现在相信由于Videosnarf(和rtpBreb)正在从数据包中删除RTP标头,因此时间戳丢失并且ffmpeg将输入数据称为cbr。

  1. 我想知道是否有办法通过(单独的文件?)ffmpeg的时间戳向量或任何其他信息,以便正确创建结果
  2. 是否有其他方法可以将数据从Phtml" target="_blank">CAP文件中取出并播放或转换后播放
  3. 由于所有的工作都是在Python中完成的,所以任何有助于这项工作的库/模块的建议(即使需要一些编码)都是受欢迎的

注意:所有工作都是脱机完成的,对输出没有限制。它可以是cbr/vbr、任何可播放的容器和转码。我唯一的“限制”是:它应该都在linux上运行…

谢谢Y

一些附加信息:
由于无为FFMPEG提供时间戳数据,我决定尝试一种不同的方法:跳过Videosnarf并使用Python代码将数据包直接传输到ffmpeg(使用“-f-i-”选项),但它拒绝接受它,除非我提供一个SDP文件...
如何提供SDP文件?它是一个额外的输入文件吗?(“-iconfig.sdp”)

以下代码是执行上述操作失败的尝试:

import time  
import sys  
import shutil  
import subprocess  
import os  
import dpkt  

if len(sys.argv) < 2:  
    print "argument required!"  
    print "txpcap <pcap file>"  
    sys.exit(2)  
pcap_full_path = sys.argv[1]  

ffmp_cmd = ['ffmpeg','-loglevel','debug','-y','-i','109c.sdp','-f','rtp','-i','-','-na','-vcodec','copy','p.mp4']  

ffmpeg_proc = subprocess.Popen(ffmp_cmd,stdout = subprocess.PIPE,stdin = subprocess.PIPE)  

with open(pcap_full_path, "rb") as pcap_file:  
    pcapReader = dpkt.pcap.Reader(pcap_file)  
    for ts, data in pcapReader:  
        if len(data) < 49:  
            continue  
        ffmpeg_proc.stdin.write(data[42:])

sout, err = ffmpeg_proc.communicate()  
print "stdout ---------------------------------------"  
print sout  
print "stderr ---------------------------------------"  
print err  

通常,这将通过管道将数据包从PCAP文件传输到以下命令:

ffmpeg -loglevel debug -y -i 109c.sdp -f rtp -i - -na -vcodec copy p.mp4

SDP文件:[RTP包括动态有效负载类型#109,H264]

IP4中的v=0
o=-0 0::1
s=无名称
c=IP4::1
t=0 0
a=工具:libavformat 53.32.100
m=视频0 RTP/AVP 109
a=rtpmap:109 H264/90000
a=fmtp:109打包模式=1;剖面标高id=64000c;sprop参数集=Z2QADKWKPAECP6WEQAAAAAWBAAAFI8UKKG==,aMvMsiw=
b=AS:200

结果:

ffmpeg版本0.10.2版权所有(c)2000-2012 ffmpeg开发人员于2012年3月20日04:34:50构建,gcc 4.4.6 20110731(Red Hat 4.4.6-3)配置:---前缀=/usr--libdir=/usr/lib64--shlibdir=/usr/lib64--mandir=/usr/share/man--启用共享--启用运行时cpudetec--启用gpl--启用版本3--启用后期处理--启用avfilter--启用pUthreads--启用x11grab--启用VD--禁用avisynth--enable-frei0r--enable libopencv--enable-libdc1394--enable libdirac--enable libgsm--enable-libmp3lame--enable libnut--enable libopencore amrnb--enable libopenjpeg--enable librtmp--enable libschroedinger--enable libspeex--enable libtheora--enable libvorbis--enable libvpx--enable-libx264--enable libxavs--enable libxvid--额外cflags=“-O2-g-管道-墙壁-Wp,-D\U FORTIFY\U SOURCE=2-FEExceptions-fstack protector-param=ssp buffer size=4-m64-mtune=generic-fPIC”-禁用剥离libavutil 51。35.100 / 51. 35.100 libavcodec 53。61.100 / 53. 61.100 libavformat 53。32.100 / 53. 32.100 libavdevice 53。4.100 / 53. 4.100 libavfilter 2。61.100 / 2. 61.100 libswscale 2。1.100 / 2. 1.100 libswresample 0。6.100 / 0. 6.100 libpostroc 52。0.100 / 52. 0.100[sdp@0x15c0c00]格式sdp探测,大小=2048,分数=50[sdp@0x15c0c00]视频编解码器设置为:h264[NULL@0x15c7240]RTP打包模式:1[NULL@0x15c7240]RTP配置文件IDC:64配置文件IOP:0级别:c[NULL@0x15c7240]外部数据设置为0x15c78e0(大小:36)!错误{或,}\u识别分离:1;1[h264@0x15c7240]错误{或,}\u识别组合:1;10001[sdp@0x15c0c00]流0解码失败[sdp@0x15c0c00]找不到编解码器参数(视频:h264)[sdp@0x15c0c00]根据比特率估计持续时间,这可能不准确。sdp:在ffmpeg\U过程中,找不到编解码器参数回溯(上次调用):文件“/ffpipe.py”,第26行。标准DIN。写入(数据[42:])IOError:[错误号32]管道破裂

(请原谅上面的内容,编辑一直在抱怨代码没有缩进好吗?)

我在这个问题上工作了几天...任何帮助/建议/提示都将不胜感激。

共有1个答案

娄鹤轩
2023-03-14

我非常确定(sanely)的唯一方法是使用数据包之间的联网时间作为延迟来重播rtp流。

问题是可变的帧速率,因为h264周围没有容器来告诉它这个帧和最后一个帧之间经过的时间量,所以它不知道如何对所有事情计时。

如果h264流是一个恒定的帧速率,那么您可能可以将rtp数据推送到ffmpeg,而无需设置输入fps的计时,但我不知道有任何h264 rtp流是这样工作的。您很可能会看到视频流播放方式在某些部分变快,在其他部分变慢。

 类似资料:
  • 我需要读取pcap文件,并使用gstreamer将其转换为带有音频和视频的avi文件。 如果我尝试以下命令,它只适用于生成视频文件。 gst启动-0.10-m-v filesrc位置=h264Audio.pcap! pcapparse src-port=44602\!"应用程序/x-rtp,有效负载=96"! rtph264Depay!"视频/x-h264,宽=352,高=288,帧率=(分数)3

  • 将(从webm、rtmp等任何格式)编码为通用hls或dash格式的“好”方法是什么??? 我看到大量关于HLS和MPEG-DASH的讨论,视频标签看起来像这样 但FFMPEG中的好命令是什么? 当我这么做的时候 它只能在chrome中播放:( 但我需要它能在safari、firefox、opera等平台上播放 我最近看过关于MP4box的讨论,能将任何源代码转换成通用可播放流的最佳线路是什么?

  • 我在codename one是新的,我在codename one的文档中找不到任何关于如何从codename one的URL播放视频的东西。

  • 我试着用两种语言播放一部电影。音频1至扬声器音频2至耳机 播放视频并混合音频1 用audio1播放视频 仅播放音频2 如何结合这一点?

  • 我正在使用这个项目的例子来在电视屏幕上投射一个视频内容。当我尝试在LocalPlayerActivity中播放视频时,会出现一些奇怪的问题。因此,在中,我单击play按钮以便在本地播放器中播放视频,之后,我单击Cast按钮并选择用于播放视频内容的设备。(应该随后显示)出现一秒钟,然后立即消失。问题是我没有触及代码中的任何内容。 这里的视频以及更好的理解,有人知道什么可能是问题吗? Android日

  • 我设置了一个相机预览与onPreviewFrame回调,我想知道,“如何编码onPreviewFrame数据到一个mp4视频文件?” 谢谢,如果有任何评论、意见或建议,我们将不胜感激,