2013-05-14 130 views
13

我已經在PCAP文件中捕獲到H264流,並嘗試從數據創建媒體文件。容器並不重要(avi,mp4,mkv,...)。
當我使用videosnarf或rtpbreak(與每個數據包之前添加00 00 00 01的python代碼結合)然後使用ffmpeg時,只有輸入幀速率恆定(或接近恆定),結果才爲OK。但是,當輸入爲vfr時,結果播放得太快(並且在相同的罕見情況下太慢)。
例如:如何將H264 RTP流從PCAP轉換爲可播放的視頻文件

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上都跑......

感謝 Ÿ

一些額外的信息:
由於沒有提供FFMPEG與時間戳數據,我決定嘗試一種不同的方法:跳過videosnarf並使用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=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

(原諒的質量上面,編輯不斷抱怨代碼沒有縮進OK?)

我工作的這個問題幾天...任何幫助/建議/提示將不勝感激。

+0

對此有何好運?尋找相同的 – spicyramen

+0

尋找同樣的東西 – Rhys

+0

如果你可以編寫c/C++,你可以修改videosnarf以將h264數據傳遞給libavformat。但是,如果您從未使用libavformat,則需要時間才能習慣它,但是您可以從ffmpeg郵件列表獲得幫助,瞭解如何執行此操作。 – Pavel

回答

1

我非常確定唯一的方法是(理智地)使用數據包之間的聯網時間作爲延遲重放rtp流。

問題是可變幀頻,因爲h264周圍沒有容器來告訴它X在這幀和最後一幀之間傳遞的時間量,它不知道如何計時。

如果h264流是一個固定的幀速率,你可能可以將rtp數據推到ffmpeg上,而不需要設置輸入fps的時間,但是我不知道任何h264 rtp流都是這樣工作的。您最可能看到的是視頻流播放方式,在某些部分快速播放,在其他部分播放速度較慢。

相關問題