** 이 글의 결론은 맨 아래, ‘경과 4‘ 에 있다.
ffmpeg 를 사용해서 ip 카메라 영상을 녹화 중인데, 정확하게 같은 시간에, 다음과 같은 오류가 발생한다.
5월 05 16:15:05 cubietruck cctv-rec.sh[3947]: [segment @ 0x2375580] Non-monotonous DTS in output stream 0:0; previous: 610073298, current: -764920; changing to 610073299. This may result in incorrect timestamps in the output file.
특정 시간에 한번씩 이러기 때문에, 다음 결과를 보려면 또 그만큼 기다려야 한다. (대략 13시간 15분이라는 사실이, 아래에 있는 글에서도, 내 경험으로도 증명되긴 했다.)
첫번째 시도는 -fflags +igndts
이었는데, 효과가 없었다.
두번째 시도는 -copytb 1
다. 결과는 내일 알 수 있다.
** copytb 는 별 효과가 없는 듯?
그런데, 이틀 연속으로 같은 시간에 오류가 발생했다는게 좀 신기하다. 그 시간에 왜?
IP 카메라에서는 저 시간과 관련된 어떤 시도도 찾지 못했다.
마찬가지로, 녹화를 하고 있는 기기(큐비트럭)에서도 그 시간에 뭔가 특별한 작업이 있진 않았다.
그럼 대체 왜??
당시 로그를 보자.
May 5 16:15:05 localhost cctv-rec.sh[3947]: frame=1156526 fps= 24 q=-1.0 size=N/A time=13:14:00.12 bitrate=N/A speed= 1x #015frame=1156540 fps= 24 q=-1.0 size=N/A time=13:14:00.69 bitrate=N/A speed= 1x #015frame=1156552 fps= 24 q=-1.0 size=N/A time=13:14:01.18 bitrate=N/A speed= 1x #015frame=1156567 fps= 24 q=-1.0 size=N/A time=13:14:01.80 bitrate=N/A speed= 1x #015frame=1156578 fps= 24 q=-1.0 size=N/A time=13:14:02.25 bitrate=N/A speed= 1x #015frame=1156594 fps= 24 q=-1.0 size=N/A time=13:14:02.91 bitrate=N/A speed= 1x #015frame=1156603 fps= 24 q=-1.0 size=N/A time=13:14:03.28 bitrate=N/A speed= 1x #015frame=1156619 fps= 24 q=-1.0 size=N/A time=13:14:03.93 bitrate=N/A speed= 1x #015frame=1156632 fps= 24 q=-1.0 size=N/A time=13:14:04.46 bitrate=N/A speed= 1x #015frame=1156645 fps= 24 q=-1.0 size=N/A time=13:14:05.00 bitrate=N/A speed= 1x #015frame=1156656 fps= 24 q=-1.0 size=N/A time=13:14:05.45 bitrate=N/A speed= 1x #015frame=1156670 fps= 24 q=-1.0 size=N/A time=13:14:06.02 bitrate=N/A speed= 1x #015frame=1156682 fps= 24 q=-1.0 size=N/A time=13:14:06.51 bitrate=N/A speed= 1x #015frame=1156694 fps= 24 q=-1.0 size=N/A time=13:14:07.01 bitrate=N/A speed= 1x #015frame=1156704 fps= 24 q=-1.0 size=N/A time=13:14:07.43 bitrate=N/A speed= 1x #015frame=1156720 fps= 24 q=-1.0 size=N/A time=13:14:08.07 bitrate=N/A speed= 1x #015frame=1156728 fps= 24 q=-1.0 size=N/A time=13:14:08.40 bitrate=N/A speed= 1x #015frame=1156745 fps= 24 q=-1.0 size=N/A time=13:14:09.10 bitrate=N/A speed= 1x #015frame=1156757 fps= 24 q=-1.0 size=N/A time=13:14:09.59 bitrate=N/A speed= 1x #015frame=1156771 fps= 24 q=-1.0 size=N/A time=13:14:10.16 bitrate=N/A speed= 1x #015frame=1156778 fps= 24 q=-1.0 size=N/A time=13:14:10.45 bitrate=N/A speed= 1x #015frame=1156797 fps= 24 q=-1.0 size=N/A time=13:14:11.23 bitrate=N/A speed= 1x #015frame=1156810 fps= 24 q=-1.0 size=N/A time=13:14:11.76 bitrate=N/A speed= 1x #015frame=1156822 fps= 24 q=-1.0 size=N/A time=13:14:12.25 bitrate=N/A speed= 1x #015frame=1156836 fps= 24 q=-1.0 size=N/A time=13:14:12.83 bitrate=N/A speed= 1x #015frame=1156849 fps= 24 q=-1.0 size=N/A time=13:14:13.36 bitrate=N/A speed= 1x #015frame=1156861 fps= 24 q=-1.0 size=N/A time=13:14:13.85 bitrate=N/A speed= 1x #015frame=1156875 fps= 24 q=-1.0 size=N/A time=13:14:14.43 bitrate=N/A speed= 1x #015frame=1156888 fps= 24 q=-1.0 size=N/A time=13:14:14.96 bitrate=N/A speed= 1x #015frame=1156900 fps= 24 q=-1.0 size=N/A time=13:14:15.45 bitrate=N/A speed= 1x #015frame=1156913 fps= 24 q=-1.0 size=N/A time=13:14:15.99 bitrate=N/A speed= 1x #015frame=1156926 fps= 24 q=-1.0 size=N/A time=13:14:16.52 bitrate=N/A speed= 1x #015frame=1156939 fps= 24 q=-1.0 size=N/A time=13:14:17.05 bitrate=N/A speed= 1x #015frame=1156951 fps= 24 q=-1.0 size=N/A time=13:14:17.54 bitrate=N/A speed= 1x #015frame=1156965 fps= 24 q=-1.0 size=N/A time=13:14:18.12 bitrate=N/A speed= 1x #015frame=1156976 fps= 24 q=-1.0 size=N/A time=13:14:18.57 bitrate=N/A speed= 1x #015frame=1156990 fps= 24 q=-1.0 size=N/A time=13:14:19.14 bitrate=N/A speed= 1x #015frame=1157001 fps= 24 q=-1.0 size=N/A time=13:14:19.59 bitrate=N/A speed= 1x #015frame=1157014 fps= 24 q=-1.0 size=N/A time=13:14:20.13 bitrate=N/A speed= 1x #015frame=1157026 fps= 24 q=-1.0 size=N/A time=13:14:20.62 bitrate=N/A speed= 1x #015frame=1157040 fps= 24 q=-1.0 size=N/A time=13:14:21.19 bitrate=N/A speed= 1x #015frame=1157052 fps= 24 q=-1.0 size=N/A time=13:14:21.68 bitrate=N/A speed= 1x #015[segment @ 0x2375580] Non-monotonous DTS in output stream 0:0; previous: 610073297, current: -765447; changing to 610073298. This may result in incorrect timestamps in the output file.
원래는 한 줄인데, 나눠봤다.
이 이후로 계속 오류 발생. frame=1156526 정도 됐을 때 딱 이 오류가 발생하는걸까?
글을 쓰던 중, 답(?)을 찾았다.
그래, 맞다. 위 연결 글에서처럼, 정확하게 녹화를 시작하고 13시간 14분에 이 오류가 발생하는 듯 하다.
사실 내 시스템은 매일 밤 12시에 새로 녹화를 시작한다. 그런데, 3시에 네트웍이 리셋되므로, 아마도 그 시간부터 다시 ffmpeg 가 시작하게 되는 모양이고, 그렇게 따지만 대략 오후 4시 15분 경이 맞다.
오호.. 검색으로 찾아내다니! 나도 놀랍고, 3년 하고도 1개월 전에 이에 대해 올려준 글쓴이에게도 고마움을 전한다.
뭐라 복잡하게 많이 써 있는데, 이렇게 옵션을 주면 된다고 한다.
-correct_ts_overflow 0
써 있는 내용은 봐도 잘 이해가 안되고.. 일단 이걸 주고 다시 해보자!
며칠 뒤 결과가 어떻게 나올지 무척이나 궁금하네.
# 경과 1
-correct_ts_overflow 0
을 붙이긴 했는데, output 쪽에 붙였다. 설명을 보니 앞에 붙여야할 듯 한데.. 아무튼 실패. 뒤로 넣어봤는데, 결과는 또 다시 내일에나.
다만, 또 다른 글을 보면 이 역시 효과가 없는 모양이다. 몇가지 해보고 정 안되면, 12시간쯤 됐을 때 강제로 재실행하도록 하는 수 밖에.
나는 꽃삽질이 싫어요~!!!
# 경과 2
예정된 시간(?)이 지났는데, 오작동이 없다.
성공인가??
아직은 섣불리 판단하긴 좀 그렇고, 며칠은 더 봐야겠지?
아무튼, 현재 성공한 선택사항은 이렇다. -correct_ts_overflow 0
을 input(-i) 앞에 써주는게 관건이다.
ffmpeg -fflags +igndts \ -correct_ts_overflow 0 \ -i rtsp://주소 \ -vcodec copy \ -map 0:v \ -metadata title="카메라" \ -f segment \ -reset_timestamps 1 \ -break_non_keyframes 1 \ -segment_time 120 \ -write_empty_segments 1 \ -segment_format mp4 \ -strftime 1 \ "$BASEDIRECTORY/$YEAR/$MONTH/$DAY/cam-%Y%m%d-%H%M.mp4"
헌데.. 이걸 굳이 무한루프에 넣어놓을 필요는 없는 듯?
현재 systemd 화해서 돌리는 중인데, 만약 오류가 발생해서 ffmpeg 가 죽으면, systemd 선에서 알아서 다시 재시작을 해주는 모양이다. (이 부분은 좀 더 공부가 필요하긴 하다.) 따라서 굳이 무한루프를 만들지 않아도 되는 듯도 한데..
아무튼, 아직 최종 성공이라 만세 부를 시간은 아니네.
# 경과 3
경과 #2 는 성공으로 보인다. 며칠은 더 봐야겠지만, 적어도 13시간 15분 오류는 사라졌다.
헌데, 또 다른 글에서 찾은 내용이 있어 덧붙여본다.
이 글에서는 -use_wallclock_as_timestamps 1
으로 성공했다는 내용과 함께, 경우에 따라 'max delay reached. need to consume packet'
가 발생할 경우 -rtsp_transport tcp
을 넣어야 할 수도 있다고 한다.
use_wallclock_as_timestamps 는 넣어보지 않았다. 일단은 #경과 2 가 잘 먹히기 때문에. 다만, rtsp_transport 는, 이전에도 써봤던 옵션이기도 했고, 저 오류도 나왔기 때문에 이번에 시험삼아 넣어봤는데, 가장 추악한(?) 결과를 보여줬다.
이제까지 보여줬던 오류와 달리, 이건 아무런 오류가 없이 그냥 멈춰버린다. 아마도 내가 쓴 어떤 옵션과 상충하는건 아닐지? 로그를 봐도 딱히 오류가 뜨지 않고, 하염없이 대기하고 있는 상태가 돼 버린다.
사실 뭐가 뭔지 정확하겐 알 지 못하는 상황에서, 장님 문고리 잡듯 이거 저거 적당히 골라잡다 보니, 정확한 선택을 하기가 어렵다.
아무튼간에, 적어도 지금 내 설정 상황에서 -rtsp_transport tcp
는 좋지 않은 결과를 보여줬다.
# 경과 4 및 (현재까지) 마지막 정리
결국 -correct_ts_overflow 0
가 답이었다. 며칠 째 시험해본 결과, 죽지 않고 잘 살아있음을 확인했다.
이게 최종 모범(?) 답안이다.
ffmpeg -fflags +igndts \ -correct_ts_overflow 0 \ -i rtsp://주소 \ -vcodec copy \ -map 0:v \ -an \ -metadata title="카메라 녹화" \ -f segment \ -reset_timestamps 1 \ -break_non_keyframes 1 \ -segment_time 120 \ -write_empty_segments 1 \ -segment_format mp4 \ -strftime 1 \ "$BASEDIRECTORY/$YEAR/$MONTH/$DAY/cam-%Y%m%d-%H%M.mp4"
-an
은 오디오를 빼라는 선택사항인데, 어차피 map 0:v 가 되어 있어서 중복되는 느낌도 있으나, 정확한 의미를 잘 모르기에 그냥 넣어줘봤다. 넣으나 안넣으나 오디오가 안나오기는 마찬가지고, 용량도 차이가 없다.
또, 이 상태로는 ffmpeg 가 죽질 않는다. 따라서 굳이 while 을 사용한 무한루프에 넣을 필요가 없다.
한가지 더. 위에도 언급했지만, 혹시나 죽더라도 systemd 가 되살리는 모양이다.
또 다른 문제가 생기기 전까진 이걸로 정리.
마지막으로 선택사항이 뭘 뜻하는지 정리해봤다.
- -fflags +igndts \ # 이건 잘 모르겠고.. 추가 확인 필요.
- -correct_ts_overflow 0 \ # NON— 오류 해결용. input 앞에 써야 한다.
- -rtsp_transport tcp \ # tcp 로 접속. 그러나 그냥 멈춰버리는 오류가 있다. https://superuser.com/questions/1326829/non-monotonous-dts-in-output-stream
- -i rtsp://카메라주소 \ # 주소
- -vcodec copy \ # video copy
- -an \ # 소리는 넣지 말기.
- -map 0:v \ # 비디오만 선택
- -metadata title=”카메라” \ # Title
- -f segment \ # 파일 분할 저장.
- -reset_timestamps 1 \ # 이건 아마도 분할된 파일의 시간이 제대로 표시되지 않는 문제 해결을 위해
- -break_non_keyframes 1 \ # 이것도 상동.
- -segment_time 120 \ # 분할 파일 길이 : 2분
- -write_empty_segments 1 \ # 영상이 제대로 전송되지 않아서 비어있어도 저장
- -segment_format mp4 \ # 분할 파일 컨테어너 형식
- -strftime 1 \ # 파일명에 %H 등을 쓸 수 있도록.