我已经在 PCAP 文件中捕获了 H264 流,并尝试从数据中创建媒体文件。容器并不重要(avi、mp4、mkv、...)。
当我使用videosnarf或rtpbreak(与在每个数据包之前添加00 00 00 01的python代码相结合)然后使用ffmpeg时,仅当输入帧速率恒定(或接近恒定)时结果才可以。但是,当输入为 vfr 时,结果播放速度过快(并且在极少数情况下播放速度过慢)。
例如:
videosnarf -i capture.pcap –c
ffmpeg -i H264-media-1.264 output.avi
在对该问题进行了一些调查之后,我现在相信由于videosnarf(和rtpbreak)正在从数据包中删除RTP标头,时间戳丢失并且ffmpeg将输入数据称为cbr。
- 我想知道是否有办法(在单独的文件上?)将时间戳矢量或任何其他信息传递给 ffmpeg,以便正确创建结果?
- 有没有其他方法可以将数据从 PCAP 文件中取出并播放或转换然后播放?
- 由于所有工作都是在 Python 中完成的,因此也欢迎任何可以帮助完成工作的库/模块的建议(即使需要一些编码)。
注意:所有工作都是离线完成的,对输出没有限制。它可以是 cbr/vbr,任何可播放的容器和转码。我唯一的“限制”:它应该都在 linux 上运行……</p>
谢谢你
一些附加信息:
由于没有为 FFMPEG 提供时间戳数据,我决定尝试一种不同的方法:跳过 videonarf 并使用 Python 代码将数据包直接通过管道传输到 ffmpeg(使用“-f -i -”选项)但随后除非我提供 SDP 文件,否则它拒绝接受它...
如何提供 SDP 文件?它是一个额外的输入文件吗?("-i config.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
o=- 0 0 IN IP4 ::1
s=无名称
c=IN IP4 ::1
t=0 0
a=tool:libavformat 53.32.100
m=video 0 RTP/AVP 109
a=rtpmap:109 H264 /90000
a=fmtp:109 打包模式=1;profile-level-id=64000c;sprop-parameter-sets=Z2QADKwkpAeCP6wEQAAAAwBAAAAFI8UKkg==,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) 配置:--prefix=/usr --libdir=/usr/lib64 --shlibdir=/usr/lib64 - -mandir=/usr/share/man --enable-shared --enable-runtime-cpudetect --enable-gpl --enable-version3 --enable-postproc --enable-avfilter --enable-pthreads --enable- x11grab --enable-vdpau --disable-avisynth --enable-frei0r --enable-libopencv --enable-libdc1394 --enable-libdirac --enable-libgsm --enable-libmp3lame --enable-libnut --enable- libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-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' --disable-stripping 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
libpostproc 52. 0.100 / 52. 0.100 [sdp @ 0x15c0c00] 探测格式 sdp05 [size=2048 和 score=2048 @ 0x15c0c00] 视频编解码器设置为:h264 [NULL @ 0x15c7240] RTP 打包模式:1 [NULL @ 0x15c7240] RTP Profile IDC:64 Profile IOP:0 级别:c [NULL @ 0x15c7240] Extradata 设置为 0x15c78e0(大小:36) !err{or,}_recognition 分开:1;1 [h264 @ 0x15c7240] err{or,}_recognition 组合:1;10001 [sdp @ 0x15c0c00] 流 0 解码失败 [sdp @ 0x15c0c00] 找不到编解码器参数(视频:h264)[sdp @ 0x15c0c00] 从比特率估计持续时间,这可能不准确
109c.sdp:找不到编解码器参数 Traceback(最近一次调用最后一次):文件“./ffpipe.py”,第 26 行,在
ffmpeg_proc.stdin.write(data[42:]) IOError: [Errno 32] Broken pipe
(原谅上面的质量,编辑一直在抱怨没有缩进的代码好吗??)
我正在研究这个问题好几天......任何帮助/建议/提示将不胜感激。