여러 개의 영상을 Exoplayer로 순차 재생하기

hongbeom
hongbeomi dev
Published in
4 min readSep 27, 2020
Photo by Jakob Owens on Unsplash

What is ExoPlayer?

ExoPlayer는 Google의 오픈 소스 라이브러리로 Android의 MediaPlayer보다 더 많은 기능을 지원해주는 미디어 재생 라이브러리입니다. 로컬 파일은 물론 인터넷에서 가져오는 오디오 및 비디오를 재생할 수 있으며 쉽게 사용할 수 있고 커스텀이 가능합니다. 자세한 설명은 아래 공식 홈페이지를 참조해보시면 됩니다.

제가 구현해야 하는 기능은 하나의 화면에 여러 개의 영상이 있고, 그 중 사용자가 재생 버튼을 눌렀을 때 영상이 재생되도록 하는 것이었습니다. 마치 페이스북의 비디오 타임라인처럼 만드는 것이 목표였는데 이를 구현하기 위해 ExoPlayer를 이용했습니다. 이를 위해 XML 파일로 exo_player_control_viewexo_player_view를 만들어 id를 각 PlayerView의 id와 매핑해주어 사용했습니다. (이렇게 사용하면 자동으로 PlayerView가 XML을 인식하여 뷰를 inflate하지 않아도 사용이 가능합니다.)

⚠️ 문제점

저는 ExoPlayer를 사용하여 영상을 재생시키기 위해 PlayerView를 상속받은 커스텀 뷰를 구현하였고 커스텀 뷰 안에서는 SimpleExoPlayer 인스턴스를 init 블록에서 생성해주었습니다.

생성한 인스턴스를 PlayerViewplayer에 넣어주고 재생하는 식으로 사용했는데 이 때 문제가 발생했습니다. ExoPlayer 공식 홈페이지를 보면 player를 사용한 후 반드시 release() 메소드를 통해 리소스를 해제해주라고 설명되어 있습니다. 하지만 어떤 이유에서인지 리소스가 제대로 해제되지 않았고 핸드폰 기종에 따라 1~7개의 영상을 재생한 후 다음 영상을 재생하려 할 때 영상을 재생할 수 없었습니다. 해당 이슈에 대한 해결책을 구하기 위해 ExoPlayer 깃허브에서 관련 이슈를 찾아보았으나 확실한 솔루션을 구하지 못했습니다.😭

덕분에 일주일 동안 삽질을..🙀

✨ 해결책

위 문제는 핸드폰의 기종에 따라 최대 인스턴스의 생성 갯수가 제한되어 있었기때문(메모리 문제) 이었습니다. 그래서 저는 따로 player를 관리해주는 클래스(VideoManager)를 만들어 SimpleExoPlayer 인스턴스를 싱글톤으로 하나만 만들어 사용해주도록 하였습니다. 원리는 간단합니다. 커스텀 뷰의 init 블록에서 VideoManager에 커스텀 뷰의 해시코드와 뷰를 넘기고 VideoManager에 해시맵 변수를 하나 두어 전달받은 해시코드와 뷰를 관리하도록 하게 하였습니다. 그리고 exo_player_viewexo_sutter 를 id로 가진 FrameLayout에 가짜 재생 버튼을 하나 만들어서 넣고 이 버튼을 클릭할 경우 VideoManagercurrentHashCode 변수와 현재 재생 중인 뷰의 해시코드를 비교하여 다를 경우 PlayerView.switchTargetView() 메소드를 사용하여 싱글톤으로 만든 SimpleExoPlayer 인스턴스와 해시맵에 저장된 뷰를 사용하여 플레이어를 사용할 뷰를 교체해주면 됩니다. 가짜 재생 버튼을 exo_sutter 를 id로 가진 FrameLayout 안에 만들어준 이유는 FrameLayout은 현재 PlayerViewplayernull인 경우에 보여지는 레이아웃이기 때문에 여기에 가짜 재생 버튼을 만들어 이 버튼을 눌렀을 경우 SimpleExoPlayer 인스턴스를 교체해준 후 재생시키도록 하기 위함입니다.

결론

해결책에는 여러가지 방법이 있을 수 있지만 저는 인스턴스를 싱글톤으로 관리하는 방법을 적용하여 페이스북과 비슷한 비디오 타임라인을 구현하였습니다. 구글에서 좋은 해결책을 던져주길 바라며 혹시나 더 좋은 해결책이 있다면 댓글로 남겨주시면 감사드리겠습니다.

읽어주셔서 감사합니다!🙌

--

--