ffmpeg 按視訊時間而不是牆壁時間分段

ffmpeg 按視訊時間而不是牆壁時間分段

我有一個將視訊記錄到磁碟的系統,有時系統會出錯。我正在嘗試在實驗室中重新建立記錄系統,而無需實際的相機(價格昂貴且沒有任何備件),以嘗試複製導致錯誤的使用模式。

我在馴服 ffmpeg 時遇到了麻煩。

背景:

使用以下命令從附加相機提供的 rtsp:// URL 在一個執行緒中連續擷取影片:

ffmpeg -i rtsp://192.168.0.10/h264 -c copy -map 0 -f segment -segment_time 900 -segment_format mp4 -segment_atclocktime 1 -strftime 1 /tmp/capture-%s.mp4

這可以正常工作並按預期生成持續時間為 15 分鐘的視訊檔案。

問題:

在實驗室中,我沒有攝像頭,也沒有 rtsp:// 流。相反,我從真實系統複製了一個捕獲的 MP4,並將其用作 ffmpeg 的輸入。就像是:

ffmpeg -stream_loop -1 -i capture-1469547000.mp4 -c copy -map 0 -f segment **-{NEED PARAM}** -segment_format mp4 -strftime 1 /tmp/captest-%s.mp4

-stream_loop -1參數執行預期的操作:它從輸入檔案(持續時間為 15 分鐘)中讀取並產生無限的輸出流。這是從 rtsp:// 流讀取的合理近似值。

我不知道使用什麼參數來使該實驗室系統將視訊分割成 15 分鐘持續時間的區塊,就像真實系統一樣。我期望的是一系列輸出文件,每個文件的大小與輸入文件的大小大致相同。

嘗試#1

使用-segment_time 900似乎要么 a) 想要使用 15 分鐘的掛鐘值,要么 b) 被忽略。由於從現有 MP4 複製比從 rtsp:// 流複製要快得多,因此生成的捕獲文件是原始文件的許多副本。

嘗試#2

我用了這個命令

ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 capture-1469547000.mp4

確定輸入檔有 13494 幀。

使用-segment_frames 13494似乎被忽略,並且輸出根本沒有分段。

嘗試#3

我已經閱讀了一堆 ffmpeg 文檔,但要么缺少我需要的內容,要么它不存在。

使用-ss *position* -t *duration*不會對輸出進行連續記錄和分段。

請求協助

我應該使用哪些參數來實現分段 a) 工作和 b) 視訊持續時間為 15 分鐘?

可能的併發症

範例 MP4 中的時間戳記(DTS?)並不“好”,因為此錯誤是連續產生的:

[segment @ 0x2abc7c0] 輸出流0:0中的非單調DTS;上一個:80990160,目前:-74730276972;更改為 80990161。  
DTS 191648787,下一個:-830336344130 st:0 無效丟棄  
PTS 191648787,下一個:-830336344130 無效刪除 st:0

但是,我不需要生成的視訊檔案實際播放或完好無損,因此我忽略了這一點,除非它影響了我需要重新創建的分段。

更多資訊

ffmpeg版本:

\# /usr/share/local/bin/ffmpeg -版本  
ffmpeg 版本 N-79587-g9f9c833 版權所有 (c) 2000-2016 FFmpeg 開發人員  
使用 gcc 4.8 建置(Ubuntu/Linaro 4.8.2-16ubuntu4)  
配置: --prefix=/home/t/dev/j/third-party/ffmpeg/../build --cross-prefix=/usr/bin/arm-linux-gnueabihf- --cpu=armv7-a - -disable-shared --enable-static --enable-gpl --enable-pthreads --enable-nonfree --enable-libx264 --enable-filters --extra-libs=-static --extra-cflags=--靜態--enable-cross-compile --target-os=linux --disable-inline-asm --arch=armv7 --disable-debug --disable-altivec --disable-sse --disable-armv6 --disable -armv6t2 --disable-mmx --disable-neon --disable-amd3dnow --disable-thumb --extra-ldflags=-L/home/t/dev/j/third-party/ffmpeg/../build/ lib --extra-cflags=-I/home/t/dev/j/third-party/ffmpeg/../build/include --extra-ldflags=-L/home/t/dev/j/third-party /ffmpeg/libavcodec --extra-ldflags=-L/home/t/dev/j/third-party/ffmpeg/libavdevice --extra-ldflags=-L/home/t/dev/j/third-party/ffmpeg /libavfilter --extra-ldflags=-L/home/t/dev/j/third-party/ffmpeg/libavformat --extra-ldflags=-L/home/t/dev/j/third-party/ffmpeg/libavresample --extra-ldflags=-L/home/t/dev/j/third-party/ffmpeg/libavutil --extra-ldflags=-L/home/t/dev/j/third-party/ffmpeg/libswscale -- extra-ldflags=-lx264 --extra-ldflags=-lm --extra-ldflags=-ldl --extra-cflags='-fpic -mthumb'  
libavutil 55.22.101 / 55.22.101  
libavcodec 57.38.100 / 57.38.100  
libav 格式 57.34.103 / 57.34.103  
libavdevice 57.0.101 / 57.0.101  
libavfilter 6. 44.100 / 6. 44.100  
libswscale 4.1.100 / 4.1.100  
libsresample 2.0.101 / 2.0.101  
libpostproc 54.0.100 / 54.0.100

答案1

segment_time應該管用。它確實指的是片段持續時間,而不是掛鐘。

關鍵影格的位置可能會妨礙,所以請嘗試

ffmpeg -fflags +genpts -i capture-1469547000.mp4 -c copy -map 0 -f segment -segment_time 900 -segment_format mp4 -break_non_keyframes 1 -strftime 1 /tmp/capture-%s.mp4

我刪除了stream_loop選項,因為目前存在與其使用相關的時間戳記產生錯誤。這也可能會幹擾這裡。

如果您需要使用很長的流,請使用 concat 解復用器。

建立一個文字文件

file 'capture-1469547000.mp4'
file 'capture-1469547000.mp4'
file 'capture-1469547000.mp4'
file 'capture-1469547000.mp4'
file 'capture-1469547000.mp4'
file 'capture-1469547000.mp4'
file 'capture-1469547000.mp4'
file 'capture-1469547000.mp4'

然後使用

ffmpeg -f concat -i list.txt -c copy ...

答案2

我有一個可行的解決方案。

根本原因

我保存的示例捕獲文件對於我想要的目的(無限輸入流)來說並不是“好”,儘管它是一個很好的視頻文件(它播放得很好,儘管它不可查找)。這個問題似乎與時間戳有關,也可能與分段復用器的一個或多個錯誤有關。

解決方案

我跑了

ffmpeg -i capture-1469547000.mp4 -c copy captemp.mp4

相反,我可以使用captemp.mp4stream_loop或concat復用器來獲得良好的流。

我不確定 capture-1469547000.mp4 和 captemp.mp4 有什麼不同; AtomicParsley 顯示 captemp.mp4 在「elst」原子中短了 12 個位元組。

再看看我原來的設置,添加後segment_list發現:這些片段生成正確,但速度非常快。它們只是被附加到現有的段文件中,而不是建立一個新的文件。這部分是因為...

strftime 潛在錯誤

我正在使用strftime一種%s格式。 strftime 原來使用的是主機的時鐘時間,而不是影片片段內的時間。即使在「工作」情況下也是如此;我已改用分段復用器的%d格式。

這可能是個錯誤,以及為什麼在非工作情況下這些段落會互相附加。

我相當確定使用該-re標誌可以透過減慢處理速度來解決這個問題,但我實際上想要加速處理。所以我還沒有嘗試過這個。

相關內容