반응형


00. 링크


[DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #1

[DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #2 - V4L2로 스트리밍 하기

[DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #3 - RTSP 클라이언트 

[DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #4 - CVLC 자동실행 

[DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #5 - DDNS와 Port Forwarding 설정

[DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #6 - ffmpeg와 crontab을 이용한 녹화 기능 구현  <= (현재글)

[DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #7 - 녹화 영상에 시간 넣기




01. 개요



5편까지는 스트리밍관련한 내용을 소개를 하였다. 하지만, 본 포스팅의 본질은 DVR 을 만드는 것이다. 지금까지 소개했던 모든 기능은 DVR을 위한 기반작업이라고 생각하면 된다.

이번 6편에서는 ffmpeg 와 crontab을 이용하여 스트리밍 영상의 녹화 방법을 기술할 예정이다. 2편, 4편의 내용은 아날로그 카메라의 영상을 RTSP 로 스트리밍하는 방법에 대해 소개한 내용이므로, RTSP가 지원되는 IP 카메라를 이용한 DVR을 만들기 위해 필자의 글을 참고하시는 분은 2편과 4편의 내용은 참고를 하지 않아도 된다.

1편 부터 현재까지의 과정을 잘 수행했다면, 현 시점 부터의 모든 입력 영상은 스트리밍(RTSP) 영상이다. 즉 모든 데이터는 디지털 데이터이다.


02. ffmpeg



ffmpeg 란 디지털 미디어파일(동영상, 음악, 사진)의 디코딩 또는 인코딩을 위해 다양한 기능을 제공하는 오픈소스 프로젝트이다. ffmpeg의 ff는 fast forward 를 의미한다. mpeg 는 MPEG 영상 표준화 그룹에서 유래했다고 한다.

우리가 사용하는 대부분의 동영상 플레이어들은 ffmpeg 기반으로 제작되었다. 즉, ffmpeg 가 LGPL 라이선스를 가지고 있는 오픈소스진영의 무료 프로젝트이지만, 만약 유료화한다면 그 시점부터 동영상을 감상하지 못하는 일이 발생할 수도 있다.(하지만, 오픈소스프로젝트는 그럴일이 거의 없으니 걱정 안해도 된다.)

ffmpeg에서는 다양한 기능들을 제공하지만, 본 포스팅에서는 ffmpeg의 미디어 포멧 변환 도구를 활용하여 스트리밍 영상을 h.264 형식의 mp4 동영상 파일로 저장하려고 한다.


[그림1] FFmpeg 로고[그림1] FFmpeg 로고


03. Crontab



Cron은 유닉스 혹은 리눅스 운영체제에서 사용하는 스케줄러이다. Crontab 은 Cron + Table의 조합으로 만들어진 이름이다.

Crontab을 이용하면 주어진 일정에 주기적으로 쉘 명령어들을 실행할 수 있다.




이미 4편에서 잠시 소개한 명령어이다.(4편에서는 주기적인 실행이 아닌, 부팅이 되면 자동 실행을 할 수 있는 @reboot 명령을 소개 했었다.)

본 포스팅에서는 Crontab 의 스케줄링 기능을 활용하여 1분 마다 미리 만들어 놓은 ffmpeg 스크립트(60초 녹화)를 실행하고, 하루에 한 번씩 특정 시간에 오래된 영상을 자동으로 지워주는 스크립트를 실행하는 방법을 소개할 예정이다.



04. 녹화


04-01. ffmpeg의 설치



필자의 DVR 만들기를 소개하는 포스팅은 Linux Mint 19 Tara 기반으로 작성되고 있다. 따라서 ffmpeg의 설치는 apt-get 을 활용하여 설치한다.


sudo apt-get install ffmpeg


리눅스의 터미널에 위와 같이 실행하면 ffmpeg 가 설치된다.

[그림2] FFmpeg 설치화면[그림2] FFmpeg 설치화면


04-02. RTSP 스트리밍 영상을 파일로 저장하는 방법



ffmpeg 를 사용하기 위해서는 사용 방법을 알아야 한다. ffmpeg 명령어에 옵션을 사용해서 원하는 영상을 녹화할 수 있다. 옵션에 대한 자세한 내용은 나무위키의 FFmpeg 4.4절을 참고하면 된다.

필자는 간단히 다음과 같은 명령어를 구성하였다.


ffmpeg -i "rtsp://192.168.219.112:8554/test.sdp" '/home/junwrap/smbroot/[test]Video1.mp4'


-i 옵션은 입력파일을 지정하는 옵션이다. -i 이후에 "rtsp://192.168.219.112:8554/test.sdp" 라는 스트링이 붙었으니, 스트리밍 영상을 입력으로 사용하겠다는 의미이다. 그 뒤에 따라 붙는 '/home/junwrap/smbroot/[test]Video1.mp4' 라는 스트링은 저장 파일을 지정한 것이다.

[그림3] ffmpeg를 이용하여 스트리밍 영상을 파일로 저장하고 있는 화면[그림3] ffmpeg를 이용하여 스트리밍 영상을 파일로 저장하고 있는 화면


약 40초간 녹화를 진행한 후 파일을 확인해 본다.




[그림4] 녹화 결과물[그림4] 녹화 결과물


[그림4] 와 같이 녹화가 잘 진행 된 것을 확인 할 수 있다.



04-03. 1분단위로 녹화를 하는 방법



스트리밍 영상이 파일로 저장되는 것 까지 확인을 했으니, 본격적으로 1분단위로 녹화를 하는 방법에 대해서 기술한다. CCTV 영상은 파일을 특정시간 단위로 분할하여 저장하는 것이 추후 확인하기도 좋고, 파일의 손상에 의한 녹화물 손실을 막을 수 있다.

ffmpeg 옵션 중에는 -t 옵션이 있다. 인코딩 시간을 초 단위로 지정하는 옵션이다. 하기와 같이 명령어를 수정하였다.


ffmpeg -i "rtsp://192.168.219.112:8554/test.sdp" -t 60 -an '/home/junwrap/smbroot/[test]Video1.mp4'


-an 옵션은 오디오를 끄는 옵션이다. CCTV 영상이기 때문에 오디오를 사용하지 않아 오디오를 Off 시켰다.

60초동안 인코딩이 잘 되고 종료되는지를 확인해 본다.


[그림5] 59.9초 녹화된 결과 로그[그림5] 59.9초 녹화된 결과 로그


[그림5] 와 같이 59.90초가 녹화된 것을 확인할 수 있다. 프레임 수에 따른 계산이기 때문에 정확히 60초가 나오지 않을 수 있다.


[그림6] 1분 동안 녹화된 파일의 사이즈[그림6] 1분 동안 녹화된 파일의 사이즈


[그림6]에서 보면 1분동안 녹화된 파일의 사이즈(480x320 30fps 기준)는 약 2MB 정도이다. 24시간 녹화시 약 3GB 정도의 용량이 필요한 것을 확인할 수 있다.(물론 움직임이 많거나, 주변 상황에 따라서 용량은 달라질 수 있다.)

컴퓨터를 구성할 때, 400GB 정도를 home 영역으로 잡고, 이 공간에 저장할 수 있게 구성할 예정이니 130일 이상의 영상을 저장할 수 있다.(다른 카메라의 녹화도 병행해야 하기 때문에 130일까지 저장하지는 않을 것이다.)



04-04. 매 1분 마다 영상 저장을 실행 하는 방법



04-03에서 1분 단위 녹화의 가능성을 확인했다. 매 1분 마다 녹화를 진행해야 하는데, 1분 마다 수행할 수 있도록 해당 명령어을 crontab에 지정하면 간단하지만 파일명이 같으면 안된다. 따라서, 파일명이 변경되는 쉘 스크립트를 작성해 본다. 이 스크립트가 crontab에 지정될 것이다.





  #!/bin/sh

   YEAR=$(date +\%Y)
   MON=$(date +\%m)
   DAY=$(date +\%d)
   HOUR=$(date +\%H)
   MIN=$(date +\%M)
   SEC=$(date +\%S)

   DATESTRING=/home/junwrap/smbroot/"(""$YEAR""$MON""$DAY"")"_"$HOUR"h"$MIN"m"$SEC"s".mp4"

   ffmpeg -i "rtsp://192.168.219.112:8554/test.sdp" -t 60 -an $DATESTRING



필자는 dvr.sh 라는 파일로 저장한 후 실행 권한을 주었다. 간단히 "sudo chmod 755 dvr.sh" 를 사용하면 된다. 위의 스크립트는 현재 시스템 시간 기준으로 "년, 월, 일, 시, 분, 초" 를 구하여, CCTV 영상의 파일명으로 사용하는 스크립트이다. 매 1분마다 새로운 파일명이 생성되어 영상이 저장될 것이다.

만들어진 스크립트를 crontab 에 등록한다.

crontab 에 등록하는 방법은 crontab -e 이다.


*/1 * * * * /home/junwrap/dvr.sh


필자는 crontab에 [그림7]과 같이 추가를 하였다. 매 1분마다 dvr.sh 를 실행하라는 뜻이다.


[그림7] crontab에 dvr.sh 스크립트 등록화면[그림7] crontab에 dvr.sh 스크립트 등록화면


여기서 crontab에 대해서 잠깐 설명하도록 한다.

crontab의 반복스케쥴링 형식은 하기와 같이 총 6개의 항목으로 되어있다.


*(1)
*(2) *(3) *(4) *(5) [명령](6)


(1) 시간의 분을 명기하는 자리이다. 0~59 의 숫자를 사용할 수 있고, */1 처럼 사용할 수 있다.
     */1의 의미는 1분마다 명령을 수행하라는 것이다.

(2) 시간의 시를 명기하는 자리이다. 0~23의 숫자를 사용할 수 있고, 분과 마찮가지로 */1 처럼 사용할 수 있다.

(3) 날짜의 일을 명기하는 자리이다. 1~31의 숫자를 사용할 수 있다.

(4) 날짜의 월을 명기하는 자리이다. 1~12의 숫자를 사용할 수 있다.

(5) 요일을 명기하는 자리이다. 0~7의 숫자를 사용할 수 있다.(0과 7은 일요일)

(6) (1 ~ 5) 의 스케줄에 맞게 실행할 스크립트 혹은 커맨드이다.


[그림8] 분 단위로 저장되고 있는 화면[그림8] 분 단위로 저장되고 있는 화면


[그림8] 처럼 1분 단위의 날짜, 시간 파일명으로 잘 저장되고 있다.


04-05. 오래된 영상 자동 삭제 방법



하드디스크의 용량은 제한적이기 때문에 영상을 무한히 저장할 수 없다. 따라서 특정 시일이 지난 영상은 자동으로 삭제해 주는 기능을 구현해야 한다. 간단히 find 명령어와 rm 명령어의 조합으로 파일 생성일 기준 원하는 기간 이전의 데이터를 삭제하는 명령어를 crontab에 등록하도록 한다.

find 명령어는 리눅스에서 파일을 찾는 명령어이다. find 명령어의 옵션 중 -mtime 라는 옵션이 있는데 시스템 시간 기준으로 mtime(일 단위) 전의 파일을 찾는 옵션이다.


find /home/junwrap/smbroot/ -mtime +3


위의 커맨드는 시스템 시간 기준 3일 이전의 데이터를 /home/junwrap 하위디렉터리로 검색하라는 명령어이다.




[그림9] /home/junwrap/smbroot/ 디렉터리의 파일 리스트[그림9] /home/junwrap/smbroot/ 디렉터리의 파일 리스트


포스팅을 하고 있는 현재 시간은 2018년 12월 5일 이다. [그림9]은 /home/junwrap/smbroot/ 디렉터리의 파일 리스트이다. cvlc.txt 파일만 2018년 11월 28일에 만들어진 파일이다. find 명령어에 -mtime 옵션을 사용하여 검색을 해 보도록 한다.


[그림10] find 검색 결과(mtime 옵션 사용)[그림10] find 검색 결과(mtime 옵션 사용)

[그림10]은 mtime 옵션을 사용하여 find 한 결과 화면이다. [그림9] 의 12월 5일 파일들을 제외한 현 시간(12월 5일) 기준 3일 이전의 데이터인 cvlc.txt 만을 결과 값으로 출력을 해 주고 있다.

좀 더 자세히 확인하고 싶으면 touch 명령어로 파일의 생성시간 조작을 하여 테스트를 해 보면 된다.


find 로 찾은 결과 파일들을 삭제해야 하는데 rm 명령어를 사용하면 된다. 다만, find 와 rm 명령어는 별개의 명령어이므로, find의 옵션 중 -exec 옵션을 사용한다. -exec 옵션은 find 로 찾은 결과 값을 실행할 명령어의 파라미터로 넘겨주는 옵션이다.


find /home/junwrap/smbroot/ -mtime +3 -exec rm {} \;


위의 명령을 사용하면 3일 이전에 생성된 파일들은 삭제가 될 것이다. 일 단위 기준이기 때문에 해당 명령을 crontab에는 하루에 한번 씩 작동하도록 등록한다. 필자는 매일 22시에 7일 전 데이터를 삭제하도록 crontab에 등록할 것이다.

위에서 했던 것 처럼 crontab -e 명령어로 crontab을 수정한다.


[그림11] crontab에 오래된 영상 삭제 스크립트 추가[그림11] crontab에 오래된 영상 삭제 스크립트 추가

[그림11]과 같이 crontab에 find와 rm 명령어의 조합을 추가하였다.





05. 마무리



본 편에서는 DVR 의 기본 기능에 대해 구현하는 방법을 소개하였다. 기본적으로 1분단위 파일 저장 방법, 날짜로 파일 명을 만드는 방법, 특정 시간이 지난 파일을 자동으로 삭제하는 방법 등을 가능한한 쉽게 설명을 하였다. 이젠 어느정도 DVR의 모습을 갖춰가고 있다. 하지만 아직 아쉬운 부분이 남아있다. 바로 영상에 삽입되는 시간정보인데, 아무리 파일명에 시간정보를 넣는다고 하더라도, 파일명은 쉽게 바꿀 수 있어 정확한 녹화의 날짜를 잃어버릴 위험이 있다. 따라서 다음 편에서는 ffmpeg 의 특정 옵션을 통해, 시스템 시간을 영상에 넣는 방법을 소개할 예정이다.


1편 링크 : ([DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #1)

2편 링크 : ([DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #2 - V4L2로 스트리밍 하기)

3편 링크 : ([DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #3 - RTSP 클라이언트)

4편 링크 : ([DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #4 - CVLC 자동실행)

5편 링크 : ([DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #5 - DDNS와 Port Forwarding 설정)

7편 링크 : ([DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #7 - 녹화 영상에 시간 넣기)



2018년 12월 5일
Kunttang




반응형
블로그 이미지

매깡

- 각종 문의는 메일로 해주세요. 메일: soriel01@nate.com

,
반응형


00. 링크


[DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #1

[DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #2 - V4L2로 스트리밍 하기 <= (현재글)

[DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #3 - RTSP 클라이언트

[DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #4 - CVLC 자동실행

[DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #5 - DDNS와 Port Forwarding 설정

[DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #6 - ffmpeg와 crontab을 이용한 녹화 기능 구현

[DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #7 - 녹화 영상에 시간 넣기




01. 아날로그 영상의 스트리밍을 위한 설계



[그림1] 아날로그 CCTV 카메라[그림1] 아날로그 CCTV 카메라


1편에서 DVR을 위한 H/W 준비를 모두 마쳤다. V4L2(Video 4 Linux Version 2)를 통하여 아날로그 영상을 입력받아 VLC 플레이어로 영상을 출력하는 것 까지 확인이 되었으니, 다음 단계는 언제 어디서든지 영상을 실시간으로 확인할 수 있도록 스트리밍 서버를 구축하는 것이다.

[그림1]은 실제 JunWrap(http://www.junwrap.co.kr) 매장의 밖에 설치할 외부용 CCTV 카메라이다.

[그림2] JunWrap 네트워크 구성도[그림2] JunWrap 네트워크 구성도


[그림2]의 구성도에서 빨간색 원으로 표시한 카메라가 아날로그 카메라이다. ipCAM1 과 ipCAM2 인경우 RTSP 를 지원기 때문에 별도의 스트리밍을 구현할 필요가 없지만, 아날로그 카메라인 경우 서버에서 V4L2 로 영상의 디지털 변환 과정을 진행하고, 변환된 디지털 영상 파일을 스트리밍 할 수 있도록 구현해야 한다.

 

[그림3] 스트리밍 서버의 구성도[그림3] 스트리밍 서버의 구성도


[그림3]은 Analog CAM으로 부터 입력된 영상을 디지털화하여 Streaming 하는 Server의 구조를 그린 것이다. /dev/video0(V4L2)로 부터 입력된 영상을 VLC 플레이어를 통해 Streaming 하는 아주 간단한 아이디어이다. 다만, 스크립트로 스트리밍이 실행되어야 하기 때문에 GUI 기반의 VLC 플레이어가 아닌 콘솔 기반의 CVLC 를 사용하게 된다.

CVLC는 콘솔에서 Command로 실행해야 하는 구조이기 때문에 파라미터를 구해야 한다. 파라미터는 VLC에서 구할 수 있다.




02. CVLC를 위한 파라미터 추출



이미 본 포스팅의 1편에서 V4L2를 이용하여 /dev/video0의 영상을 VLC 플레이어를 통해 확인했었다. 그럼 이 영상을 CVLC에서 입력받아 스트리밍 할 수있도록 Command를 완성하면 된다. 참고로 VLC에는 미디어 스트리밍 기능이 포함되어 있다.

[그림4] VLC 디버그 메시지창 실행 #1[그림4] VLC 디버그 메시지창 실행 #1


[그림5] VLC 디버그 메시지창 실행 #2[그림5] VLC 디버그 메시지창 실행 #2


[그림4]와 [그림5]를 통해 VLC 실행과정의 디버그 메시지를 실시간으로 확인할 수 있다. [그림5]의 상세출력 부분을 2(디버그) 로 설정해야만 실행 커맨드를 확인할 수 있다.

메시지 창을 그대로 둔 채, VLC 창에서 Streaming 을 위한 설정을 진행해 본다.


[그림6] VLC의 스트림 방법 #1[그림6] VLC의 스트림 방법 #1


[그림7] VLC의 스트림 방법 #2[그림7] VLC의 스트림 방법 #2


[그림6]과 [그림7]의 과정을 통해, V4L2 영상의 입력부를 설정한다. 이 과정에서 입력에 대한 파라미터를 구할 수 있다. 

[그림7]에서 비디오 장치 이름을 /dev/video0(장치에 따라 달라질 수 있음)으로 설정하고, 카메라에 맞게 비디오 표준부를 설정한다.

[그림7]의 미디어열기 창에서 "추가 옵션 보기(M)"을 체크하게 되면 하단에 MRL옵션수정 항목이 표시되어진다. MRL 부분을 복사해 놓는다. 영상의 세부 설정을 위해서는 옵션수정항목도 필요로 하지만, MRL 만으로도 스트리밍을 위한 입력부 기본 준비가 끝난다.


[그림8] VLC의 스트림 방법 #3[그림8] VLC의 스트림 방법 #3


[그림7]에서 하단의 스트림 버튼을 누르게 되면, [그림8]과 같이 다음 화면으로 넘어가게 된다. 다음 버튼을 클릭하여 넘어간다.

[그림9] VLC의 스트림 방법 #4[그림9] VLC의 스트림 방법 #4




[그림9] 부터는 스트리밍을 위한 설정을 하는 화면이다. [그림7]과 [그림8]이 영상의 입력부이고, [그림9]부터는 영상 출력부를 설정하는 것이다.

새 목적지를 RTSP로 설정한다. RTSP(Real-Time Streaming Protocol)는 1편에서 간단히 소개가 되어있다. 참고하기 바란다. RTSP를 선택하고, 꼭 오른쪽의 추가 버튼을 클릭해야 한다.

[그림10] VLC의 스트림 방법 #5[그림10] VLC의 스트림 방법 #5


[그림10]은 RTSP를 위한 포트설정과 경로 설정을 하는 화면이다. 이 화면에서 잘 설정을 해야만, RTSP 의 URL을 완성시킬 수 있다.

필자는 포트를 8554로 설정하고, 경로를 /test.sdp 로 설정하였다. 외부에서 접속할 때, Router 단의 Port Forwarding 을 설정할 예정이기 때문에 RTSP의 표준 포트인 8554를 기본을 사용했다.

[그림11] VLC의 스트림 방법 #6[그림11] VLC의 스트림 방법 #6


[그림11]은 스트리밍 데이터의 영상코덱을 설정하는 화면이다. 필자는 H.264를 선택하였다.


[그림12] VLC의 스트림 방법 #7[그림12] VLC의 스트림 방법 #7


[그림12]와 같이 최종 스트림 문자열이 표시가 되어진다. "생성된 스트림 출력 문자열" 의 내용을 잘 복사해 놓는다. 스트림 버튼을 눌러 스트리밍을 시작해 본다.

[그림13] VLC의 스트림 방법 #8[그림13] VLC의 스트림 방법 #8


메시지 창을 살펴보게 되면, 각종 디버그 메시지들이 출력된다. [그림7]과 [그림12]에서 추출한 문자열이 메시지창에 잘 표시되고, 스트리밍이 잘 시작 되었는지를 확인한다. 문제 없이 스트리밍이 시작되었다면, CVLC를 위한 Command를 작성해 본다. 하기 Command는 필자가 완성한 cvlc command이다.





cvlc "v4l2:///dev/video0" --v4l2-input=0 --v4l2-standard=MN --live-caching=300 --sout=#transcode'{vcodec=h264,scale=자동,acodec=mpga,ab=128,channels=2,samplerate=44100}:rtp{sdp=rtsp://:8554/test.sdp}' --sout-keep


위의 커맨드를 콘솔에서 실행시켜 본다.

[그림14] CVLC 실행[그림14] CVLC 실행


[그림14]와 같이 빨간색 스트링 없이 실행이 되면 정상적으로 스트림이 시작 된 것이다.


03. 마무리



Analog 영상을 V4L2 를 통해 입력받고, CVLC를 통해 스트리밍 하는 방법까지 작성을 하였다. 다음 포스팅에서는 스트리밍 영상을 휴대폰에서 확인하는 방법에 대해서 작성할 예정이다.


1편 링크 : ([DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #1)

3편 링크 : ([DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #3 - RTSP 클라이언트)

4편 링크 : ([DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #4 - CVLC 자동실행)

5편 링크 : ([DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #5 - DDNS와 Port Forwarding 설정)

6편 링크 : ([DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #6 - ffmpeg와 crontab을 이용한 녹화 기능 구현)

7편 링크 : ([DVR] 집에서 놀고 있는 컴퓨터로 DVR을 만들어보자 #7 - 녹화 영상에 시간 넣기)





2018년 11월 27일
Kunttang

반응형
블로그 이미지

매깡

- 각종 문의는 메일로 해주세요. 메일: soriel01@nate.com

,