Hanbit the Developer

[Retrofit2] Video View와 HTTP Range Header에 대해 본문

Mobile/Android

[Retrofit2] Video View와 HTTP Range Header에 대해

hanbikan 2022. 1. 11. 13:24

 > VideoView에 영상을 넣는 방법

get request에 대해 video를 response하는 url이 있다고 해보자. 이 때 VideoView에 이 링크의 영상을 띄우고자 할 때, 두 옵션이 있다.

 

첫번째는 Retrofit2를 이용하여 url에 get request를 보내 response를 얻어온 뒤, 이것의 바이너리를 임시 파일로 만들고 이 파일의 uri(Uri.fromFile())를 setVideoURI의 인자로 전달해주는 방법이다.

두번째는 영상 url를 setVideoPath나 setVideoURI의 인자로 넣어주는 방법이다. 이 때 후자의 경우, Uri.parse()를 이용하여 url을 uri로 바꾸는 과정이 필요하다. 하지만 이 두 방법은 완전히 동일하다. 왜냐하면, VideoView.java의 setVideoPath 코드 내용이 다음과 같기 때문이다.

 

 > 두 방법에 대한 분석

아무튼, 이 두 경우에 대해 Profiler(View > Tool Windows > Profiler)의 네트워크 분석을 하면 다음과 같은 결과가 나온다.

이에 따라 일반적인 경우 VideoView에는 Retrofit2가 적합하지 않다는 결론을 내렸다. Retrofit2를 쓸 경우 구현도 복잡하고 response로 모든 데이터를 받고 난 뒤에 영상이 재생될 수 있기 때문에 성능(response time 기준)이 매우 안 좋았기 때문이다.

반대로, setVideoPath에 url을 넣는 방식은 range query도 자동으로 해주면서, 실제로 테스트를 할 때 성능(response time)이 월등하였다.

 

 > 여담

다만, header에 range를 넣어서 일일히 부분 작업을 해줄 수도 있지만, 이 경우 영상이 제대로 나오지 않았다(검은 화면). 이 경우에는 range별로 setVideo를 해줄 수 있는 새 함수(또는 이미 구현되어 있을 수도 있지만, 이미 깔끔하고 좋은 방법을 찾았기에 굳이 삽질을 하지 않았다.)가 있어야, 수동적인 방식의 range query의 구현이 가능하지 않은가 하는 생각이 든다. 왜냐하면 range로 잘려있는 데이터는 그 자체로 video가 아니기 때문이다.

매우 다행히도, 두번째 방식이 있기 때문에 직접 분할 작업을 구현하지 않아도 된다. 웹에서도 video 태그에 url만 달아줘도 자동으로 부분 쿼리가 진행된다. 이러한 점, 그리고 직접 구현을 위해 구글링을 했었을 때 자료의 양이 매우 적었었다는 점을 미루어 볼 때, 아무래도 range를 직접 나누는 작업은 일반적인 경우가 아닌 것 같다.

 

Profiler로 네트워크를 분석할 때, 처음에는 retrofit2 사용 여부와 상관없이, 모두 아래처럼 영상 초기에 영상을 모두 receive하는 것처럼 보였다.

하지만 이것은 테스트용 영상이 너무 짧았기 때문에 range를 나눌 필요 없이(혹은, range가 영상 전체의 byte를 초과한 것이었을 수도 있으나, 서버 로그에는 range query가 찍히지 않았다.) 한번에 받아온 것이었다.

 

영상의 내용을 충분히 크게 한 뒤에는 본문에서 작성한 바와 같이 두 방법 간의 차이가 명백히 드러나게 되었다.