我在PCAP文件中捕获了h264流,并尝试从数据创建媒体文件。容器并不重要(avi,mp4,mkv,…)。
当我使用videosnarf或rtpbreak(与在每个数据包之前添加00 00 00 01的python代码组合)然后使用ffmpeg时,只有当输入帧速率为常量(或接近常量)时,结果才正常。但是,当输入为vfr时,结果播放太快(在相同的罕见情况下播放太慢)。
例如:
videosnarf-i captured.pcap-c
ffmpeg-i h264-media-1.264输出.avi
在对这个问题做了一些调查之后,我认为既然videosnarf(和rtpbreak)正在从包中删除rtp头,时间戳就会丢失,而ffmpeg将输入数据称为cbr。
我想知道是否有一种方法可以传递(在单独的文件中?)
时间戳向量或任何其他信息到ffmpeg,因此
是否将正确创建结果?
是否有其他方法可以将数据从PCAP文件中取出并播放或转换,然后播放?
因为所有的工作都是在Python中完成的,所以也欢迎对库/模块的任何建议(即使需要一些编码)。
注意:所有工作都是离线完成的,对输出没有限制。它可以是CBR/VBR,任何可播放的容器和转码。我唯一的“限制”:它应该都在Linux上运行…
谢谢
Y
一些附加信息:
因为Nothing为ffmpeg提供了时间戳数据,所以我决定尝试一种不同的方法:跳过videosnarf并使用python代码将数据包直接传输到ffmpeg(使用“-f-i-”选项),但除非我提供一个sdp文件,否则它拒绝接受它…
如何提供SDP文件?它是一个额外的输入文件吗?(“-i配置.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】
V=0
在IP4中为-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参数集=z2qadkwkpaecp6weqaaawbaaafi8ukkg=,amvmsiw=;
B=AS:200
结果:
ffmpeg 0.10.2版版权所有(c)2000-2012 ffmpeg开发者
建造于2012年3月20日04:34:50,GCC 4.4.6 20110731(红帽
4.4.6-3)配置:--prefix=/usr--libdir=/usr/lib64--shlibdir=/usr/lib64--mandir=/usr/share/man--enable shared--enable runtime cpudetect--enable gpl--enable-version3--enable postroc--enable avfilter--enable pthreads--enable-x11grab--enable vdpau--disable avisynch--enable-frei0R--启用libopencv--启用libdc1394--启用libdirac--启用libgsm--启用libmp3name--启用libnut--启用libopencore amrnb--启用libopencore amrwb--启用libopenjpeg--启用librtmp--启用libschroedinger--启用libspeex--启用libtheora--启用libvorbis--启用libvpx--enable-libx264--enable libxavs--enable libxvid--extra cflags='o2-g-pipe-wall-wp,-d_fortify_source=2-fexceptions-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 libav格式53。三十二点一零零
53。32.100 libavdevice 53.4.100/53。四点一零零
libavfilter 2.61.100/2。61.100 libsw比例2。一点一零零
/2.第2条。1.100 libsw重新取样0.6.100/0.六点一零零
libpostroc 52。0.100/52。0.100[SDP@0x15C0C00]格式SDP
探测,尺寸=2048,得分=50[SDP@0x15C0C00]视频编解码器设置
收件人:h264[空@0x15c7240]RTP打包模式:1[空@
0x15C7240]RTP配置文件IDC:64配置文件IOP:0级别:C[空@
0x15C7240]附加数据设置为0x15C78E0(尺寸:36)!错误或,识别
分离:1;1[h264@0x15c7240]错误或,组合识别:1;
10001[SDP@0x15C0C00]流0解码失败[SDP@
0x15C0C00]找不到编解码器参数(视频:H264)[SDP@
0x15C0C00]根据比特率估计持续时间,这可能不准确。
109C.sdp:找不到编解码器参数回溯(最新
最后一个调用):file“./ffpipe.py”,第26行,in
ffmpeg_proc.stdin.write(data[42:])ioerror:[errno 32]管道损坏
(请原谅上面的大量内容,编辑不停地抱怨代码没有缩进好吗?)
我在这个问题上工作了好几天…如有任何帮助/建议/提示,我们将不胜感激。

最佳答案

我非常确定(理智地)唯一的方法是使用包之间的网络时间作为延迟来重放RTP流。
问题是可变的帧速率,因为在h264周围没有容器来告诉它x在这个帧和最后一个帧之间经过的时间量,所以它不知道如何为所有内容计时。
如果h264流是一个恒定的帧速率,您可能可以将rtp数据推送到ffmpeg,而不必设置输入fps的计时,但我不知道有任何h264 rtp流可以这样工作。你最可能看到的是视频流播放方式,在某些部分快速播放,在其他部分缓慢播放。

07-28 02:58
查看更多