6월 3일의 ⁠#Android11: 베타 버전 출시 행사에 참여하세요.

미디어 앱 아키텍처 개요

이 섹션에서는 미디어 플레이어 앱을 미디어 컨트롤러(UI 용)와 미디어 세션(실제 플레이어용)으로 구분하는 방법을 설명합니다. 또한 미디어 앱 아키텍처, 즉 오디오 앱에 적합한 클라이언트/서버 디자인 및 동영상 플레이어용 단일 활동 디자인에 관해 설명합니다. 미디어 앱이 하드웨어 컨트롤에 응답하고 오디오 출력 스트림을 사용하는 다른 앱과 협업하는 방법도 보여줍니다.

플레이어 및 UI

일반적으로 오디오 또는 동영상을 재생하는 멀티미디어 애플리케이션은 다음과 같은 두 부분으로 구성됩니다.

  • 디지털 미디어를 가져와서 동영상 및/또는 오디오로 렌더링하는 플레이어
  • 플레이어를 실행하고 선택적으로 플레이어의 상태를 표시하는 전송 컨트롤이 있는 UI

UI 및 플레이어

Android에서 처음부터 직접 플레이어를 빌드하거나 다음 옵션 중에서 선택할 수 있습니다.

  • MediaPlayer 클래스는 가장 일반적인 오디오/동영상 형식과 데이터 소스를 지원하는 베어 본(bare-bones) 플레이어의 기본 기능을 제공합니다.
  • ExoPlayer는 하위 수준의 Android 오디오 API를 공개하는 오픈소스 라이브러리입니다. ExoPlayer는 MediaPlayer에서 사용할 수 없는 DASH 및 HLS 스트리밍과 같은 고성능 기능을 지원합니다. ExoPlayer 코드를 맞춤설정하여 새 구성요소를 쉽게 추가할 수 있습니다. ExoPlayer는 Android 버전 4.1 이상에서만 사용할 수 있습니다.

미디어 세션 및 미디어 컨트롤러

UI용 및 플레이어용 API는 임의로 설정할 수 있지만 둘 간의 상호작용 특성은 기본적으로 모든 미디어 플레이어 앱에서 동일합니다. Android 프레임워크는 미디어 플레이어 앱을 빌드하기 위한 잘 정의된 구조를 제공하는 두 클래스인 미디어 세션미디어 컨트롤러를 정의합니다.

미디어 세션과 미디어 컨트롤러는 표준 플레이어 작업(재생, 일시중지, 중지 등)에 해당하는 사전 정의된 콜백과 앱 고유의 특수한 동작을 정의하는 확장 가능한 맞춤 호출을 사용하여 서로 통신합니다.

컨트롤러 및 세션

미디어 세션

미디어 세션은 플레이어와의 모든 통신을 담당하며, 앱의 나머지 부분에서 플레이어의 API를 숨깁니다. 플레이어를 제어하는 미디어 세션에서만 플레이어가 호출됩니다.

세션은 플레이어 상태(재생 중/일시중지됨) 및 재생 중인 항목에 관한 정보를 유지 관리합니다. 세션은 하나 이상의 미디어 컨트롤러에서 콜백을 수신할 수 있습니다. 이렇게 하면 앱의 UI는 물론 Wear OS 및 Android Auto를 실행하는 호환 기기로도 플레이어를 제어할 수 있습니다. 콜백에 응답하는 로직은 일관성이 있어야 합니다. MediaSession 콜백에의 응답은 콜백을 시작한 클라이언트 앱과 상관없이 동일해야 합니다.

미디어 컨트롤러

미디어 컨트롤러는 UI를 분리합니다. UI 코드는 플레이어 자체가 아닌 미디어 컨트롤러와만 통신합니다. 미디어 컨트롤러는 전송 제어 작업을 미디어 세션의 콜백으로 변환합니다. 또한 세션 상태가 변경될 때마다 미디어 세션에서 콜백을 수신하며, 연결된 UI를 자동으로 업데이트하는 메커니즘을 제공합니다. 미디어 컨트롤러는 한 번에 하나의 미디어 세션에만 연결할 수 있습니다.

미디어 컨트롤러와 미디어 세션을 사용할 때 런타임에 다른 인터페이스 및 플레이어를 배포할 수 있습니다. 실행 중인 기기의 기능에 따라 앱의 모양 및/또는 성능을 독립적으로 변경할 수 있습니다.

동영상 앱과 오디오 앱 비교

동영상을 재생할 때는 눈과 귀가 모두 관여합니다. 오디오를 재생할 때는 들으면서 다른 앱을 동시에 사용할 수도 있습니다. 사용 사례마다 디자인이 다릅니다.

동영상 앱

동영상 앱에는 콘텐츠를 보기 위한 창이 필요합니다. 따라서 동영상 앱은 일반적으로 단일 Android 활동으로 구현됩니다. 동영상이 표시되는 화면이 활동의 일부입니다.

동영상 플레이어 활동

오디오 앱

오디오 플레이어는 항상 UI를 표시할 필요는 없습니다. 오디오 재생이 시작되면 플레이어를 백그라운드 작업으로 실행할 수 있습니다. 사용자는 다른 앱으로 전환하여 계속 청취할 수 있습니다.

이 디자인을 Android에서 구현하려면 두 가지 구성요소, 즉 UI용 활동 및 플레이어용 서비스를 사용하여 오디오 앱을 빌드하면 됩니다. 사용자가 다른 앱으로 전환하면 서비스를 백그라운드에서 실행할 수 있습니다. 오디오 앱의 두 부분을 별도의 구성요소로 나누면 각각을 더 효율적으로 따로 실행할 수 있습니다. 일반적으로 UI는 플레이어에 비해 수명이 짧으며, 플레이어는 UI 없이 오래 실행할 수 있습니다.

오디오 활동 및 BrowserService

지원 라이브러리는 이러한 클라이언트/서버 접근 방식을 구현하는 두 가지 클래스, 즉 MediaBrowserServiceMediaBrowser를 제공합니다. 서비스 구성요소는 미디어 세션과 플레이어를 포함하는 MediaBrowserService의 서브클래스로 구현됩니다. UI 및 미디어 컨트롤러를 사용한 활동에는 MediaBrowserService와 통신하는 MediaBrowser를 포함해야 합니다.

MediaBrowserService를 사용하면 앱의 UI 활동에 전혀 액세스하지 않아도 Android Auto 및 Wear와 같은 호환 기기가 앱을 검색하고, 앱에 연결하고, 콘텐츠를 탐색하고, 재생을 제어할 수 있습니다. 실제로 동일한 MediaBrowserService에 여러 앱을 동시에 연결할 수 있으며 이때 각 앱에는 자체 MediaController가 있습니다. MediaBrowserService를 제공하는 앱은 여러 개의 동시 연결을 처리할 수 있어야 합니다.

미디어 앱 및 Android 오디오 인프라

잘 디자인된 미디어 앱은 오디오를 재생하는 다른 앱과 '원활하게 작동'해야 합니다. 스마트폰을 공유하고 오디오를 사용하는 기기의 다른 앱과 협업할 준비가 되어 있어야 합니다. 또한 기기의 하드웨어 컨트롤에 응답해야 합니다.

상호 협업

이 모든 동작은 오디오 출력 제어에 설명되어 있습니다.

media-compat 라이브러리

media-compat 라이브러리에는 오디오 및 동영상을 재생하는 앱을 빌드하는 데 유용한 클래스가 포함되어 있습니다. 이러한 클래스는 Android 2.3(API 레벨 9) 이상을 실행하는 기기와 호환됩니다. 또한 Android의 다른 기능과 작동하여 편안하고 친숙한 Android 환경을 만듭니다.

미디어 세션 및 미디어 컨트롤러의 권장 구현은 media-compat 지원 라이브러리에 정의된 MediaSessionCompatMediaControllerCompat 클래스입니다. 이 둘은 Android 5.0(API 레벨 21)에 도입된 MediaSessionMediaController 클래스의 이전 버전을 대체합니다. Compat 클래스는 동일한 기능을 제공하지만, 하나의 API에만 작성하면 되므로 앱을 더 쉽게 개발할 수 있습니다. 라이브러리는 미디어 세션 메서드를 이전 플랫폼 버전의 동등한 메서드(사용 가능한 경우)로 변환하여 이전 버전과의 호환성을 처리합니다.

이전 클래스를 사용하는 작동 중인 앱이 이미 있는 경우 compat 클래스로 업데이트하는 것이 좋습니다. Compat 버전을 사용하면 registerMediaButtonReceiver()의 모든 호출과 RemoteControlClient의 모든 메서드를 삭제할 수 있습니다.

성능 측정

Android 8.0(API 레벨 26) 이상에서는 일부 미디어 클래스에서 getMetrics() 메서드를 사용할 수 있습니다. 이 메서드는 속성과 값의 맵으로 표현되는 구성 및 성능 정보를 포함하는 PersistableBundle 객체를 반환합니다. getMetrics() 메서드는 다음 미디어 클래스에 관해 정의됩니다.

측정항목은 각 인스턴스에 관해 개별적으로 수집되며 인스턴스 수명 동안 유지됩니다. 측정항목을 사용할 수 없는 경우 메서드는 null을 반환합니다. 반환되는 실제 측정항목은 클래스에 따라 다릅니다.