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

2024-05-18 05:51:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经捕获了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 output.avi

在对这个问题做了一些调查之后,我认为现在由于videosnarf(和rtpbreak)正在从包中删除RTP报头,时间戳丢失,ffmpeg将输入数据称为cbr。

  1. 我想知道是否有一种方法可以传递(在单独的文件上?) 时间戳向量或任何其他信息到ffmpeg,因此 将正确创建结果?
  2. 有没有其他方法可以从PCAP文件中取出数据并播放或转换它然后播放?
  3. 因为所有的工作都是用Python完成的,所以任何可以帮助完成工作的库/模块的建议(即使需要一些编码)也是受欢迎的。

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

谢谢 是的

一些附加信息:
由于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
o=- 0 0 IN IP4 ::1
s=No Name
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 packetization-mode=1;profile-level-id=64000c;sprop-parameter-sets=Z2QADKwkpAeCP6wEQAAAAwBAAAAFI8UKkg==,aMvMsiw=;
b=AS:200

结果:

ffmpeg version 0.10.2 Copyright (c) 2000-2012 the FFmpeg developers
built on Mar 20 2012 04:34:50 with gcc 4.4.6 20110731 (Red Hat 4.4.6-3) configuration: --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] Format sdp probed with size=2048 and score=50 [sdp @ 0x15c0c00] video codec set to: h264 [NULL @ 0x15c7240] RTP Packetization Mode: 1 [NULL @ 0x15c7240] RTP Profile IDC: 64 Profile IOP: 0 Level: c [NULL @ 0x15c7240] Extradata set to 0x15c78e0 (size: 36)!err{or,}_recognition separate: 1; 1 [h264 @ 0x15c7240] err{or,}_recognition combined: 1; 10001 [sdp @ 0x15c0c00] decoding for stream 0 failed [sdp @ 0x15c0c00] Could not find codec parameters (Video: h264) [sdp @ 0x15c0c00] Estimating duration from bitrate, this may be inaccurate
109c.sdp: could not find codec parameters Traceback (most recent call last): File "./ffpipe.py", line 26, in
ffmpeg_proc.stdin.write(data[42:]) IOError: [Errno 32] Broken pipe

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

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


Tags: 文件数据代码importsdpenablesyspcap
1条回答
网友
1楼 · 发布于 2024-05-18 05:51:07

我非常确定(sanly)的唯一方法是使用包之间的网络时间作为延迟来重放rtp流。

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

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

相关问题 更多 >