radio-recorder 프로젝트 설명
2년전쯤에 한국 라디오를 혼자 듣고 싶었었다. 하지만 시차가 많이 나는 지역에 살았었다. (8시간 정도 느림)
그래서 한국 인터넷 라디오를 녹음해서 개인적으로 들을 수 있다면 좋겠다는 아이디어로 작업했던 프로젝트 소스코드를 공개한다.
https://github.com/ageldama/radio-recorder
방송사의 인터넷 라디오를 녹음 하는 스크립트는 커밋에서 제외하고 공개한다. 이는 방송사에게 문제가 될 수 있으므로 개인적으로 알아내서 사용하고 타인과 공유하지 않기를 바란다.
프로그램 구성
cron 서버
- 지정된 시간에 녹음/인코딩 스크립트를 실행하는 스케쥴을 담당한다.
- 오래된 임시 파일 정리 등등도.
-
한국의 시간대와 내가 있는 시간대가 달라서 다른 cron scheduler을 쓰지 않고 그냥 짰었던거 같다.
- 그럼에도 결국 그냥 KST 시간대로 사용자 계정에 설정해서 돌린거 같은데? ㅋ
-
https://github.com/ageldama/radio-recorder/blob/master/cron.pl
webapp 서버
- 녹음한 파일과 녹음 목록을 RSS feed을 생성해서 팟캐스트 프로그램이 접근할 수 있도록 해주는 웹애플리케이션.
-
https://github.com/ageldama/radio-recorder/blob/master/webapp.pl
-
https://metacpan.org/pod/Mojolicious::Lite : 웹프레임웍으로 가볍게 써봤다.
- https://perldoc.perl.org/perldata.html#Special-Literals
__DATA__
리터럴 문자열을 템플릿으로 사용해서, 별도 템플릿 파일 없이 그냥 스크립트 안에 모든걸 때려넣었다.
- https://perldoc.perl.org/perldata.html#Special-Literals
- ..등등의 모듈을 사용했다.
-
필요한 프로그램, 의존성 등
- mplayer, sox, lame, gnu grep, gnu sed, gnu xargs 등을 사용해서 적절하게 쉘스크립팅을 활용. 대부분은 어차피 Perl에서 실행을 제어하지만.
- 그리고 파일시스템에 인코딩한 파일을 저장해놓고, 메타데이터는 PostgreSQL에 저장했다.
- 특정 웹프레임웍, 개발프레임웍보다 마이그레이션, DB접근, 객체시스템 등등 모두 MetaCPAN에서 검색하고 하나씩 찾아서 돌려봤던거 같다.
Mplayer으로 Wave파일으로 덤프 내리기
-
mplayer에서
-ao pcm
으로 실행 옵션을 지정하면 지정한 wave파일으로 저장해준다. -
녹음을 마치고 mplayer의 gracefully한 종료를 위해서, slave mode으로 실행하고, pipe file으로 키보드 커맨드를 보내 종료.
- http://www.mplayerhq.hu/DOCS/tech/slave.txt :
mplayer -slave -input file=</tmp/fifofile> <movie>
- 그렇게도 안 종료하면
SIGINT
보내서 종료.
- http://www.mplayerhq.hu/DOCS/tech/slave.txt :
-
IO::Async (MetaCPAN) 모듈을 사용해서,
- mplayer 프로세스를 PID으로 모니터링하고 필요하면 재시작하거나, 종료 시그널을 보냈다.
IO::Async::Timer::Countdown
이용해서 녹음 시간이 끝나면 종료하도록 만들었다.- https://github.com/ageldama/radio-recorder/blob/master/lib/Proc/RestartAndTimeout.pm
-
프로세스 관리에 시작할 때 처음엔 조금 신경을 많이 써서 작성했다.
IO::Async
프레임웍이 펄에서 비동기 입출력을 잘 지원해줘서 편안했다. 조금 달라서 익숙해지는데 연습이 필요했었지만.
-
https://github.com/ageldama/radio-recorder/blob/master/lib/RadioGaga/Steps.pm#L110 여기에 작성했듯이,
- 외부 프로세스 관리를 패턴화하고,
- 상태를 체크하거나,
- 단계별로 종료를 하는 부분을 분리해서
sub
을 지정했다. - Busy polling을 간단히 구현했다. https://github.com/ageldama/radio-recorder/blob/master/lib/Timeout/Wait.pm
Database Migration: Sqitch
- Sqitch: DB Migrator
- https://github.com/ageldama/radio-recorder/tree/master/sqitch/pg
-
테이블이 복잡하지도, 많지도 않다. 그냥 하나.
- 그럼에도 그냥 공부하는셈치고, 적용해봤다.
- 다른 언어로, 다른 프로젝트를 할 때도 다시 사용하고 싶은 생각이다.
RSS XML 생성
Podcast::Rss::Generator 마음에 드는게 MetaCPAN에 없어서 간단히 만들었다.
Perl 5스럽게 인라인 HEREDOC 문자열 + Template::Toolkit (MetaCPAN) 사용.
DB <-> Object Mapping
좋았던 점:
-
객체시스템, 펄이라 가능한 유연함.
DBIx-Class
이든, 직접 내가 package +bless
으로 만든 객체든, 다같이 섞어서 쓰기 좋아서 편안했다.- Moose, Moo, Mouse등등 다양한 OO-framework이 CPAN에 있지만 다들 대부분은 잘 호환되고 하니까.
-
CPAN에 방대한 모듈들.
-
IO::Async, Mojolicious, Sqitch..등등
- 그냥 언어 자체가 변하지 않아도, 펄5 자체가 유연해서 IO::Async와 같이 확장이 가능한걸 보면 마음이 편안하다.
- ..이외에도 별별 잡다한 기능들을 생각할 때마다 검색해보면 항상 있어서 편안했다.
-
아쉬운 점: 테스팅과 큰 메인 스크립트
- 이 스크립트 에 왠만한 로직을 다 넣었던게 조금 후회스럽다.
-
테스트 코드를 착실하게 작성하고 작업해 나갔었다면 작업이 더 쉬웠었을거 같다.
- 더군다나 펄에는 좋은 Mocking, Testing 라이브러리, 프레임웍이 많은데도 그런걸 잘 활용하지 못했어서 아쉽다.
깜빡하고 Twitter API 키 커밋했다.
- 하지만 방금 지웠다. 휴우…