반응형
동영상 스트리밍을 위해 최초에 선택한 방법은 다음과 같았다.
- PC 웹 브라우저: RTMP 프로토콜 이용 스트리밍/플래시 플레이어 이용.
- 안드로이드: RTSP 프로토콜 이용 스트리밍, 안드로이드 MediaPlayer 이용.
미디어 서버로는 Wowza를 선택했는데, 그 이유는 위 두 가지 프로토콜을 모두 지원하기 때문이었다.
안드로이드와 RTSP의 나쁜 궁합
그런데, 기능 구현을 진행하다보니 안드로이드에서 다음의 문제점들이 드러났다.
- 스트리밍 품질
- seeking 기능의 문제
우선, 스트리밍 자체의 품질이 좋지 않았다. RTSP 자체가 데이터 송수신에 UDP를 사용하는 것에서 비롯되는 것도 있겠지만, 안드로이드 2.2 기반 폰, 3.2 기반 태블릿, 4.0 기반 폰, 4.1 기반 넥서스 7에서 화면이 일부 깨지거나 하는 등의 현상이 발생했다.
특히 문제되는 부분은 시간바의 이동, 즉 seeking 기능에 있었다. seek bar를 이동하는 동안 플레이어가 해당 시점으로 이동하고 버퍼링을 하는 등의 작업을 하는데, RTSP의 경우 시간 이동과 버퍼링 등이 신속하게/원활하게 동작하지 않는 경우가 많았다. 특히, 허니콤 기반의 갤럭시 탭은 시간 이동이 안 될 정도로 문제가 심각했다. (갤럭시 탭을 아이스크림으로 업그레이드 해야 그나마 seek bar 이동이 동작했다.)
안드로이드의 MediaPlayer와 RTSP와의 궁합이 그닥 좋지 않다는 점, 특히 RTSP를 사용할 때 seeking이 부드럽게 되지 않는다는 점 때문에 스트리밍 방식을 교체하기로 결정했다.
HTTP 기반 스트리밍으로의 전환
여러 방법을 고민하다가 HTTP 기반의 스트리밍으로 처리하기로 결정했다. 필요한 건 다음과 같은 것들이다.
- HTTP range 헤더를 지원하는 웹 서버. 아파치 httpd는 당연히 지원하므로, 아파치 웹 서버를 사용 (seeking과 관련)
- 힌팅(hinting)된 MP4 파일 (비디오는 H.264, 오디오는 AAC로 인코딩 된 버전)
안드로이드의 MediaPlayer는 힌팅된 MP4 파일을 HTTP 기반으로 스트리밍으로 플레이 할 수 있는 기능을 제공하고 있다. 따라서, 아파치 웹 서버의 문서 디렉토리에 MP4 파일을 업로드 하고, MediaPlayer의 데이터 소스로 다음과 같이 MP4 파일에 대한 URL을 지정하면 해당 MP4를 플레이할 수 있게 된다.
path = "http://mediaserver/starwords_1.mp4";
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(path);
...
MediaPlayer의 Seeking 기능을 사용할 경우 HTTP의 range 헤더를 이용해서 원하는 위치로 빠르게 이동할 수 있게 된다. 즉, 프로그레시브 다운로드Progressive Download 방식의 비디오 플레이와 달리 원하는 위치로 빠르게 이동할 수 있게 된다.
안드로이드 앱에서 동영상 미디어를 스트리밍으로 플레이하는 기능이 필요하다면, 현재 수준에서는 폼질/안정성 측면을 고려한다면 여러모로 불안한 RTSP 보다는 HTTP 기반 스트리밍을 사용하는 것이 현명할 것이다.
참고:
- MP4 파일을 힌팅(hinting) 도구 MP4Box.
- http://gpac.wp.mines-telecom.fr/mp4box/
- CentOS에서의 MP4Box 설치: http://yes.imhappyo.com/401