벽 시간 대신 비디오 시간으로 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 900a) 벽시계 값인 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 Copyright (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=-- static --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  
libav코덱 57. 38.100 / 57. 38.100  
libavformat 57.34.103 / 57.34.103  
libav장치 57.0.101 / 57.0.101  
libavfilter 6. 44.100 / 6. 44.100  
libswscale 4. 1.100 / 4. 1.100  
libswresample 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 demuxer를 사용하십시오.

텍스트 파일 만들기

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 muxer를 사용하여 좋은 스트림을 얻습니다.

Capture-1469547000.mp4와 captemp.mp4의 차이점이 무엇인지 잘 모르겠습니다. AtomicParsley는 captemp.mp4가 'elst' 원자에서 12바이트 더 짧음을 보여줍니다.

원래 설정을 다시 살펴보고 추가하면 segment_list세그먼트가 올바르게 생성되었지만 매우 빠르게 생성되었다는 사실이 드러났습니다. 새 세그먼트 파일을 만드는 대신 기존 세그먼트 파일에 추가되었을 뿐입니다. 부분적으로는 그 사람의 잘못이기도 하고...

strftime 잠재적인 버그

strftime형식 으로 사용하고 있었습니다 %s. strftime은 비디오 세그먼트 내의 시간이 아닌 호스트 시스템의 시계 시간을 사용하는 것으로 나타났습니다. 이는 '작업'의 경우에도 마찬가지입니다. 대신 세그먼트 다중화기의 형식을 사용하도록 전환했습니다 %d.

이는 아마도 버그일 수 있으며 작동하지 않는 경우 세그먼트가 서로 추가되는 이유입니다.

-re플래그를 사용하면 처리 속도가 느려져 이 문제가 해결될 것이라고 확신 하지만 실제로는 처리 속도를 높이고 싶습니다. 그래서 나는 이것을 시도하지 않았습니다.

관련 정보