비디오를 디스크에 녹화하는 시스템이 있는데 가끔 시스템에 오류가 발생합니다. 오류를 일으키는 사용 패턴을 복제하기 위해 실제 카메라 없이(비싸고 예비품이 없음) 실험실에서 녹화 시스템을 다시 만들려고 합니다.
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 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.mp4
stream_loop 또는 concat muxer를 사용하여 좋은 스트림을 얻습니다.
Capture-1469547000.mp4와 captemp.mp4의 차이점이 무엇인지 잘 모르겠습니다. AtomicParsley는 captemp.mp4가 'elst' 원자에서 12바이트 더 짧음을 보여줍니다.
원래 설정을 다시 살펴보고 추가하면 segment_list
세그먼트가 올바르게 생성되었지만 매우 빠르게 생성되었다는 사실이 드러났습니다. 새 세그먼트 파일을 만드는 대신 기존 세그먼트 파일에 추가되었을 뿐입니다. 부분적으로는 그 사람의 잘못이기도 하고...
strftime 잠재적인 버그
strftime
형식 으로 사용하고 있었습니다 %s
. strftime은 비디오 세그먼트 내의 시간이 아닌 호스트 시스템의 시계 시간을 사용하는 것으로 나타났습니다. 이는 '작업'의 경우에도 마찬가지입니다. 대신 세그먼트 다중화기의 형식을 사용하도록 전환했습니다 %d
.
이는 아마도 버그일 수 있으며 작동하지 않는 경우 세그먼트가 서로 추가되는 이유입니다.
-re
플래그를 사용하면 처리 속도가 느려져 이 문제가 해결될 것이라고 확신 하지만 실제로는 처리 속도를 높이고 싶습니다. 그래서 나는 이것을 시도하지 않았습니다.