我在PCAP文件中捕获了H264流,并试图从数据中创建媒体文件。容器并不重要(avi,mp4,mkv,…)。
当我使用录像纳夫或rtpbreak (结合python代码在每个数据包之前添加了00000001),然后使用ffmpeg时,只有当输入帧速率为常数(或接近常数)时,结果才是确定的。但是,当输入是vfr时,结果播放得太快(在同样罕见的情况下,结果太慢)。
例如:
-i captured.pcap -c -i H 264-媒体-1.264 output.avi
在对这个问题做了一些调查之后,我现在相信,由于视频纳夫(和rtpbreak)正在从数据包中移除RTP报头,时间戳丢失了,ffmpeg将输入数据称为cbr。
注意:所有工作都是脱机完成的,对输出没有限制。它可以是cbr/vbr,任何可播放的容器和代码转换。我唯一的“限制”是:它应该都运行在linux…上。
谢谢Y
一些补充资料:
由于nothing为FFMPEG提供了时间戳数据,所以我决定尝试一种不同的方法:跳过视频并使用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 IP4中的o=- 0 0:1 s=No名称 c=IN IP4 ::1 t=0 %0 a=tool:libavformat 53.32.100 m=video 0 RTP/AVP 109 a=rtpmap:109 H 264/90000 packetization-mode=1;profile-level-id=64000c;sprop-parameter-sets=Z2QADKwkpAeCP6wEQAAAAwBAAAAFI8UKkg==,a=fmtp:109 aMvMsiw=; b=AS:200
结果:
版权(c) 2000-2012年ffmpeg开发人员 建基于2002年3月20日04:34:50,gcc 4.4.6 20110731 (Red 4.4.6-3)配置:前缀=/usr-libdir=/usr/lib64 64-shlibdir=/usr/lib64 64- Mar =/usr/share/man-启用共享-启用运行时-cpudetect启用-gpl-启用-版本3-启用-后期postproc启用avfilter-启用线程-启用-x11抓取-启用-vdpau-禁用-avisynth-启用-frei0r--启用-libopencv--启用-libnut 1394-启用-libdirac-启用-libschroedinger启用-libmp3ame-启用-libopencore-libopencore amrnb启用-libopencore-amrwb-启用-libopenjpeg-enable-libschroedinger enable-libschroedinger enable-libtheora-enable-libvorbis-enable-libvpx-enable-libvpx 264-enable-libxavs enable-libxvid- -Wall libxvid libvpx= -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack保护器--param=ssp-缓冲器-size=4 -m64 -mtune=generic -fPIC‘-禁用-剥离libavutil 51。35.100 / 51。35.100 libavcodec 5361.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 520.100 / 52。0.100 sdp @ 0x15c0c00格式size=2048探测,score=50 sdp @ 0x15c0c00视频编解码器设置为: h264 NULL @ 0x15c7240 RTP分组模式:1 NULL @ 0x15c7240 RTP配置文件IDC: 64配置文件IOP: 0级别:C NULL @ 0x15c7240 Extradata设置为0x15c78e0 (大小:36)!err{或}_recognition分离: 1;1 h264 @ 0x15c7240 err{或,}_recognition组合: 1;10001 sdp @ 0x15c0c00对流0的解码失败sdp @ 0x15c0c00无法找到编解码参数(视频: h264) sdp @ 0x15c0c00从比特率估计持续时间,这可能是不准确的。 109c.sdp:无法找到编解码器参数跟踪(最近一次调用):File "./ffpipe.py",第26行,在 ffmpeg_proc.stdin.write(data42:) IOError: Errno 32断管
(请原谅上面的大量内容,编辑器继续抱怨没有缩进的代码,好吗?)
我一直在研究这个问题.任何帮助/建议/暗示都将不胜感激。
发布于 2014-08-21 16:22:37
我确信(明智地)的唯一方法是使用数据包之间的网络时间作为延迟来重放rtp流。
问题是可变帧速率,因为h264周围没有容器来告诉它在这个帧和最后一个帧之间传递的时间长度,所以它不知道如何对所有事情进行计时。
如果h264流是一个恒定的帧速率,您可以在没有设置输入fp的时间的情况下将rtp数据推送到ffmpeg,但是我不知道有任何h264 rtp流是那样工作的。你最有可能看到的是视频流在某些部分快速播放,而在另一些部分播放速度慢。
https://stackoverflow.com/questions/16552107
复制相似问题