2주 계획했던 일정이 하루하루 뒤로 밀리더니 결국 1주일을 더 넘겨서야 마무리되었다. 마지막에는 '더 이상 미뤄지면 큰일이다' 는 심정으로 3일을 밤샘 작업; 고요한 새벽, 끝내주는 집중력 덕분에 의외로 많은 버그를 찾아내어 고칠 수 있었다. 밤샘 작업을 선호하지는 않지만, 가끔은 해도 좋겠다는 생각마저 들었다.


이번 업데이트의 테마는 '네트워크를 이용한 외부 저장 장치에 대한 연결' 이다.







NAS - Network Attached Storage


무인코딩 재생을 지원한 이후로 NAS 연동을 지원해달라는 요청을 많이 받았다. 사실 이 때 난 NAS 가 뭔지도 몰랐다. NAS - Network Attached Storage 는 쉽게 보면 웹하드랑 비슷하다. 하드디스크에 랜선 하나 꽂아 놓은 모습을 하고 있다. 


외장 하드를 하나 살까 고민했던 터라 이 참에 NAS 를 한 대 마련했다. 설치는 굉장히 간단했고, 기능을 보아하니 그 흔한 FTP 서버부터 AFP, WebDAV 등 다양한 서버 기능을 제공하더라.


최근 들어 주로 사용하는 PC가 레니타 맥북 프로가 된 이후로 NAS 를 사용하는 일이 많아졌다. 맥북의 디스크 용량이 256 기가 밖에 되지 않으니, 용량 큰 동영상 파일들은 죄다 NAS 로 옮겨 버리게 되었다.


그리고 때가 왔다. 


NAS 에 연결해서 스트리밍으로 동영상을 볼 수 있게 되면 정말 편하겠구나! 하는 생각이 이제야 절실하게 느껴진 것이다. 




WebDAV 프로토콜


NAS 는 여러가지 서버 기능을 제공하는데 그 중 무엇을 지원할까 하다가- 많은 사람들이 요청한 WebDAV 프로토콜을 타겟으로 잡았다. WebDAV 프로토콜은 HTTP 위에서 구현되기 때문에 방화벽 등의 복잡한 문제를 경험하지 않아도 되는 것 같았다.


뭐, HTTP 위에서 동작하는거면 그리 어렵지 않겠지? - 이런 안일한 생각을 갖고서 이번 업데이트 계획을 2주 일정으로 세웠다. 2주면 되리라. 그리고 이 안일함으로 인해 얼마나 큰 스트레스를 받았는지;;


WebDAV 표준 문서를 읽고 나서 구현을 시작하려고 했는데 막상 문서를 펼치니 뭐가 이리도 복잡한건지... ;; 어느 세월에 이걸 다 읽을 수 있을까- 싶어서 도중에 문서 읽기를 그만 두었다. 필요한 기능만 구현하자! yaPlayer에서는 아주 단순하게 '특정 디렉토리의 파일 목록 보기', '파일 스트리밍/다운로드' 만 필요하다. 


그래서 거꾸로 시작했다. 일단 WebDAV 서버로 뭔가 날려본다. 그리고 응답이 오면 그 응답을 표준 문서를 보고 분석한다. '파일 목록 보기' 기능부터 시작! 요청 메시지는 의외로 간단했고, 응답 메시지는 조금 복잡했지만 어려운 수준은 아니었다. 표준 문서를 옆에 펼쳐놓고 분석을 시작했다. 응답 중 상당 부분은 yaPlayer에서 불필요하므로 스킵할 수 있었고, 필요한 부분만 추려보니 그리 많지 않더라. 응답은 XML 형식으로 오는데 Objective-C 에서 제공되는 XML 파서는 SAX 파서가 유일. 개인적으로 SAX 보다 DOM 파서를 편하게 생각하지만, 간단한 XML 문서의 경우라면 SAX 파서도 할 만 하다. 다행히 WebDAV 로부터의 응답 구조는 해석하기에 간단한 측에 속했고, 그래서 그리 어렵지 않게 파서를 구현할 수 있었다. 이렇게해서 목록 보기, 폴더 이동 기능은 쉽게 끝났다.


스트리밍과 다운로드. 특히 스트리밍에서 많이 해맸다. 바로 전 목록 보기 기능을 구현하면서 아이디/패스워드를 통한 인증 기능을 응답 처리 루틴 안에 구현해 넣었는데 스트리밍은 도대체 어떻게 해야 하나? 여기서 막혔다. HW 디코딩이 가능한 녀석은 AVAsset 을 생성해야 하고, SW 디코딩 해야 하는 녀석은 ffmpeg 으로 넘겨야 한다. 둘 다 응답 처리 루틴이 감추어져 있다. 도대체 어디에 인증 관련 코드를 넣어야 한단 말인가?


오랜 검색 끝에 (의외로 구글링이 안되서 많이 고생했다. 검색어를 잘못 잡았던건지;; ) 인증에 필요한 아이디/패스워드를 URL에 포함시킬 수 있다는 것을 알았다. 네트워크 프로그래밍 경력이 그리 많지 않은데다가, 여태 인증과 관련된 코드를 작성해 본 경험은 거의 없으니 고생할 수 밖에... 아래와 같은 형식의 URL을 작성하면 된다.


스키마://아이디:패스워드@호스트:포트/패스


그러면 코드 내부에서 인증 정보를 추출해 갖고 있다가 인증 절차 때 활용한다. AVAsset과 ffmpeg 모두 잘 동작하더라. 끝. 유후- 




내장 자막을 지원하려면 좀 제대로!


얼추 WebDAV 기능이 완성되어갈 무렵 (하지만 기능만 동작할 뿐 UI는 형편 없었다) NAS 에 연결해 이런 저런 동영상들을 테스트 하고 있는데 한 영상에서 앱이 반복해서 다운되는 문제를 발견했다. 왜지?


원인은 간단했지만, 미처 생각치 못했던 부분이라 당황했다. 내장 자막을 읽어서 메타 정보를 통해 어느나라 언어인지 확인하는 코드가 있다. 쉽게 말해 언어 코드를 넣으면 언어 이름을 뱉어내는 기능을 하는 코드 - 예를 들어 ko 를 넣으면 한국어라고 답한다. 그런데 여기서 일부 언어 코드에 대해 답을 내지 못하는게 문제였다. 루마니아어 코드를 넣으면 nil 을 반환하는게 아닌가! 이걸 NSDictionary에 넣으려 하니 뻗어버릴 수 밖에;;


그래서 일단 '언어 코드로부터 언어 이름을 찾지 못하면 언어 코드를 그대로 사용' 하게끔 고쳤다. 하지만 언어 코드만 덜렁 보여주면 그게 참 이쁘지 않단 말이지... 


결국 언어 코드-이름 표준을 찾아 일일이 입력해 넣었다. 어딘가 분명 이 기능을 구현한 오픈 소스가 있을텐데... 잠깐 찾아보다가 나오지 않길래 '그냥 몸이 좀 고생할 뿐, 어렵진 않겠다' 는 판단으로 직접 타이핑을 시도했다. 하아.. 뭔 언어가 이리도 많단 말인가! 몸이 고생할 뿐..? 하긴, 머리는 쓰지 않았으니... 하지만 몸이 좀 고생해야 말이지;; 두 시간에 걸친 생각 없는 타이핑으로 구현 완료. 끙.




대화가 겹치리란 생각은 왜 못한거냐!


테스트를 핑계로 보기 시작한 애니메이션 - '그래도 마을은 돌아간다'. 확인해보니 내장 자막이 있길래 오픈! 어라- 일부 대화가 누락되고 있는 것 같은데??


자막은 시간 순으로 저장되어 있다. 그래서 하나 하나 순서대로 보여주고 있었는데 이번에 시청한 동영상을 통해 대화가 시간 상 중첩될 수 있다는 사실을 깨달았다; 예를 들어 자막은 아래처럼 표현될 수 있다.


[1.0 - 5.0] 업데이트가 그리 쉬운 줄 알아!?

[1.5 - 2.0] 만만하게 

[1.8 - 3.5] 보면 안되지

[3.0 - 4.0] 너 자신을 알라!


시작 시간만 보면 순서대로 들어오는 건 맞다. 하지만 종료 시간을 함께 고려하면 문제가 생긴다. 대화가 중첩되는 것이다! yaPlayer의 자막 시스템은 그 구조상 대화를 한 번에 하나씩만 보여주고 있다. 아아... 어쩌지? 자막 시스템을 다 뜯어고쳐야 하나?


나는 대안을 찾아냈다. yaPlayer의 자막 시스템은 건드리지 말자. 대신 자막을 읽을 때 현재 시스템에 맞게끔 변환하자! 그리하여 위의 자막을 읽어서 아래와 같이 변환하는 코드를 작성했다.


[1.0 - 1.5] 업데이트가 그리 쉬운 줄 알아!?

[1.5 - 1.8] 업데이트가 그리 쉬운 줄 알아!?\n만만하게

[1.8 - 2.0] 업데이트가 그리 쉬운 줄 알아!?\n만만하게\n보면 안되지

[2.0 - 3.0] 업데이트가 그리 쉬운 줄 알아!?\n보면 안되지

[3.0 - 3.5] 업데이트가 그리 쉬운 줄 알아!?\n보면 안되지\n너 자신을 알라!

[3.5 - 4.0] 업데이트가 그리 쉬운 줄 알아!?\n너 자신을 알라!

[4.0 - 5.0] 업데이트가 그리 쉬운 줄 알아!?


이렇게 하니 기존의 자막 시스템을 수정하지 않고도 문제를 해결할 수 있었다. 좋아!




빠른 탐색 기능, 확인은 제대로 한거요?


지난 버전에서 제스처를 이용해 (터치휠에도 버튼이 표시된다) 일정 시간 앞/뒤로 탐색하는 기능을 추가했다. 그리고 몇 통의 문의 메일 - '동영상이 멈춰요, 소리가 안나요' 


소리가 안나는 문제는 앞서 언급은 안했지만 플레이어의 구조 개선을 하는 과정에서 수정되었고, 동영상이 멈춘다? 개선된 플레이어에서는 재현이 안되는데... 이것도 고쳐졌나보다- 하고 안심하던 찰나. 터무니 없게도 MP4 파일을 재생할 때 문제가 재현되었다. MP4는 ffmpeg을 거치지 않고 iOS SDK가 제공하는 플레이어 컴포넌트를 이용하기 때문에 꽤 신뢰하고 있었다. 그런데 왜? 왜 멈춰버리는 것이냐!


너무 신뢰한 나머지 테스트를 게을리 한 것이 문제였다. 한 번이라도 제대로 테스트 했다면 문제를 발견하고 바로 고쳤을텐데... 재생시간을 변경할 때 한 번 일시정지 시키고 난 다음 변경해주어야 제대로 동작했다. 이렇게 간단하게 끝날 일을... 으헝헝-




그 외에도 눈에 띄지 않는 작지 않은 변화들...


3일의 밤샘 작업에서, 놀라운 집중력 덕에 '눈에 거슬리는 사소한 UI/UX 문제' 들을 발견했다. 거의 눈에 띄지 않아 고치지 않아도 될 문제인데, 일단 발견된 이상 거슬려서 이대로 둘 순 없었다. 어떤 문제는 아주 간단하게 고칠 수 있었고, 어떤 문제는 아주 고생해서 해결했다.


아주 고생해서 해결해야 할 때는 고민을 많이 하는 편이다. 고치지 않아도 큰 문제가 없는데 굳이 고치느라 오랜 시간과 노력을 소비해야 하는가? 바로 비용 대비 효과의 효율성 문제.


비용 대비 효과를 이유로 고치지 않아도 된다. 하지만 yaPlayer는 내 개인의 작품. 상품 이전에 작품이라는 의미를 부여하고 있기 때문에 고치지 않을 수 없다. 효율성 측면에서 최악일진 몰라도, 문제를 해결하면 내 스스로의 만족감은 배가 된다. 굳이 효율성을 따질 필요가 없다. 나만 좀 고생하면 된다.


하지만 이런 일이 비일비재하다면 그것은 문제가 된다. 자주 이런 문제가 발생한다면 아키텍처를 점검할 필요가 있다. 잠시 손을 멈추고, 백업해 놓고, 연습장을 꺼내어 현재의 구조를 자세히 그려놓고 고민해보자. 분명 어딘가 어색한 연결, 의아한 그룹이 있을 것이다. 처음에는 완벽했던 아키텍처도 업데이트나 버그 수정을 통해 몇 번이나 수정되다 보면 아키텍처는 흔들리기 마련이다. 꼼꼼히 따져서 제대로 된 아키텍처를 새로 그린 후 (이 과정이 여러 차례 반복되면 어느 순간 완전히 새로 그리기 보다는 몇 개의 연결선과 그룹을 수정하는 정도로 일의 크기가 작아진다) 심호흡 세 번 정도 하고 나서 코드를 고치자. 


아키텍처의 유지보수는 반드시 필요한 과정이지만, 사실 많은 위험을 갖고 있다. 변경된 아키텍처로 인해 새로운 문제가 발생할 수 있다. 최대한 시간을 들여 꼼꼼히 확인하고 또 확인하자. 그럼에도 불구하고 발견하지 못한 문제들은... 어쩔 수 없다. 다음 업데이트를 통해 고칠 수 밖에; 나는 아직 여기에 대한 적절한 프로세스를 발견하지 못했다. 머릿속으로는 '테스트 해야 할 것들을 체크 리스트로 만들어서 코드 변경 때마다 모두 검증하자' 라고는 하는데 그게 좀처럼 쉽게 되지 않았다. (테스트 항목이 너무 많은게 문제) 그러다보니 이번에도 어김없이 '의심 되는 부분만 테스트'. 다음 번에는 꼭 체크 리스트를 만들어 검증해보고 그 과정을 공유할 생각이다. 




앱 개발을 지속하게 하는 세 가지 원동력


돌비(Dolby) 라이센스 문제로 코덱이 빠진 지금, 수 많은 악성 리뷰에도 불구하고 끝까지 yaPlayer는 놓을 수는 없었다. 자식 같은 앱이다. 내 작품이다. 그리고 나는 앱을 만드는 일을, 그 과정을 정말 좋아한다. 첫 번째 원동력은 바로 나 자신이다.


가끔 개발자를 응원하는 이메일을 받는데 그럴 땐 정말 눈물이 핑 돈다. 새로운 기능을 요청하거나 버그를 찾아 친절하게 스크린샷까지 동봉한 메일을 받아도 기분이 너무 좋다. 두 번째 원동력은 피드백이다.


세 번째 원동력은 당연히 판매 수익이다. 수익이 발생하지 않으면 새로운 앱을 만들거나, 기존 앱을 업데이트하는데 큰 차질이 생긴다. 차질 정도가 아니라 불가능하게 된다. 먹고 살 수 없는데 어떻게 이 일을 계속할 수 있겠는가?


앱을 잘 만드는 능력은 구글링과 경험으로 향상시킬 수 있다. 다양한 사용자 취향 덕분에 피드백도 꾸준한 편이다. 하지만 판매를 늘리는 것은, 나는 아직 잘 못하는 미지의 영역이다. 어떻게 마케팅을 해야 하는지 아직도 전혀 모르겠다. 하루에도 수십-수백여개의 앱이 쏟아지는 지금, 마케팅 없이 앱의 판매를 늘리는 것은 거의 불가능한 것 같은데, 그래서 마케팅이 절실한대도 여전히 뭐부터 어떻게 해야 할지 모르겠다.


앞으로도 한동안은 마케팅으로 끙끙 앓 듯 하다. 뭐라도 해보고 '잘 안되네-' 를 겪으면 '다음엔 이렇게 해보자!' 라는 계획을 세울텐데 지금껏 뭐하나 제대로 된 마케팅을 시도해 본 적 조차 없는 것 같다. 반성하고 있다. 시도라도 해보자!




신고

CATEGORIES

티스토리 툴바