我有一個將視訊記錄到磁碟的系統,有時系統會出錯。我正在嘗試在實驗室中重新建立記錄系統,而無需實際的相機(價格昂貴且沒有任何備件),以嘗試複製導致錯誤的使用模式。
我在馴服 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.mp4
stream_loop或concat復用器來獲得良好的流。
我不確定 capture-1469547000.mp4 和 captemp.mp4 有什麼不同; AtomicParsley 顯示 captemp.mp4 在「elst」原子中短了 12 個位元組。
再看看我原來的設置,添加後segment_list
發現:這些片段生成正確,但速度非常快。它們只是被附加到現有的段文件中,而不是建立一個新的文件。這部分是因為...
strftime 潛在錯誤
我正在使用strftime
一種%s
格式。 strftime 原來使用的是主機的時鐘時間,而不是影片片段內的時間。即使在「工作」情況下也是如此;我已改用分段復用器的%d
格式。
這可能是個錯誤,以及為什麼在非工作情況下這些段落會互相附加。
我相當確定使用該-re
標誌可以透過減慢處理速度來解決這個問題,但我實際上想要加速處理。所以我還沒有嘗試過這個。