이 섹션에서는 미디어 플레이어 앱을 미디어 컨트롤러(UI용)와 미디어 세션 (실제 플레이어용)으로 구분하는 방법을 설명합니다. 여기에서는 두 가지 미디어 앱 아키텍처, 즉 오디오 앱에 적합한 클라이언트/서버 디자인과 동영상 플레이어를 위한 단일 활동 디자인을 설명합니다. 또한 미디어 앱이 하드웨어 컨트롤에 응답하고 오디오 출력 스트림을 사용하는 다른 앱과 협력하게 하는 방법도 보여줍니다.
플레이어 및 UI
일반적으로 오디오 또는 동영상을 재생하는 멀티미디어 애플리케이션은 다음과 같은 두 부분으로 구성됩니다.
- 디지털 미디어를 가져와 동영상 또는 오디오로 렌더링하는 플레이어
- 플레이어를 실행하고 선택적으로 플레이어의 상태를 표시하는 전송 컨트롤이 있는 UI
Android에서 자체 플레이어를 처음부터 빌드하거나 다음 옵션 중에서 선택할 수 있습니다.
- MediaPlayer 클래스는 가장 일반적인 오디오/동영상 형식과 데이터 소스를 지원하는 베어본 플레이어를 위한 기본 기능을 제공합니다.
- ExoPlayer는
MediaCodec
및AudioTrack
와 같은 하위 미디어 프레임워크 구성요소를 기반으로 빌드된 오픈소스 라이브러리입니다. ExoPlayer는MediaPlayer
에서 사용할 수 없는 DASH와 같은 고성능 기능을 지원합니다. ExoPlayer 코드를 맞춤설정하여 새 구성요소를 쉽게 추가할 수 있습니다. ExoPlayer는 Android 버전 4.1 이상에서만 사용할 수 있습니다.
미디어 세션 및 미디어 컨트롤러
UI와 플레이어의 API는 임의적일 수 있지만 두 부분 간의 상호작용 특성은 기본적으로 모든 미디어 플레이어 앱에서 동일합니다. Android 프레임워크는 미디어 플레이어 앱 빌드를 위한 잘 정의된 구조를 적용하는 두 가지 클래스, 즉 미디어 세션과 미디어 컨트롤러를 정의합니다.
미디어 세션과 미디어 컨트롤러는 표준 플레이어 작업 (재생, 일시중지, 중지 등)에 상응하는 사전 정의된 콜백뿐 아니라 앱에 고유한 특수 동작을 정의하는 데 사용하는 확장 가능한 맞춤 호출을 사용하여 서로 통신합니다.
미디어 세션
미디어 세션은 플레이어와의 모든 통신을 담당하며, 앱의 나머지 부분에서 플레이어의 API를 숨깁니다. 플레이어는 플레이어를 제어하는 미디어 세션에서만 호출됩니다.
세션은 플레이어의 상태 (재생 중/일시중지됨)와 재생 중인 항목에 관한 정보를 유지합니다. 세션은 하나 이상의 미디어 컨트롤러에서 콜백을 수신할 수 있습니다. 이렇게 하면 앱의 UI는 물론 Wear OS 및 Android Auto를 실행하는 호환 기기로 플레이어를 제어할 수 있습니다. 콜백에 응답하는 로직은 일관성이 있어야 합니다. MediaSession
콜백에 대한 응답은 콜백을 시작한 클라이언트 앱과 관계없이 동일해야 합니다.
미디어 컨트롤러
미디어 컨트롤러는 UI를 분리합니다. UI 코드는 플레이어 자체가 아닌 미디어 컨트롤러와만 통신합니다. 미디어 컨트롤러는 전송 제어 작업을 미디어 세션의 콜백으로 변환합니다. 또한 세션 상태가 변경될 때마다 미디어 세션에서 콜백을 수신합니다. 이는 연결된 UI를 자동으로 업데이트하는 메커니즘을 제공합니다. 미디어 컨트롤러는 한 번에 하나의 미디어 세션에만 연결할 수 있습니다.
미디어 컨트롤러와 미디어 세션을 사용하면 런타임에 다양한 인터페이스 또는 플레이어를 배포할 수 있습니다. 앱을 실행하는 기기의 기능에 따라 앱의 모양 및/또는 성능을 독립적으로 변경할 수 있습니다.
동영상 앱과 오디오 앱 비교
동영상을 재생할 때는 눈과 귀가 모두 관여합니다. 오디오를 재생할 때는 들으면서 동시에 다른 앱을 사용할 수도 있습니다. 사용 사례마다 디자인이 다릅니다.
동영상 앱
동영상 앱에는 콘텐츠를 보기 위한 창이 필요합니다. 이러한 이유로 동영상 앱은 일반적으로 단일 Android 활동으로 구현됩니다. 동영상이 표시되는 화면은 활동의 일부입니다.
오디오 앱
오디오 플레이어는 항상 UI를 표시할 필요는 없습니다. 오디오 재생이 시작되면 플레이어는 백그라운드 작업으로 실행할 수 있습니다. 사용자는 청취를 계속하면서 다른 앱으로 전환하고 작업할 수 있습니다.
Android에서 이 디자인을 구현하려면 UI의 활동과 플레이어의 서비스라는 두 가지 구성요소를 사용하여 오디오 앱을 빌드하면 됩니다. 사용자가 다른 앱으로 전환하면 서비스가 백그라운드에서 실행될 수 있습니다. 오디오 앱의 두 부분을 별도의 구성요소로 분할하면 각 부분이 단독으로 더 효율적으로 실행될 수 있습니다. 일반적으로 UI는 플레이어에 비해 수명이 짧으며 UI 없이 오래 실행될 수 있습니다.
지원 라이브러리는 이러한 클라이언트/서버 접근 방식을 구현하는 두 가지 클래스, 즉 MediaBrowserService
및 MediaBrowser
를 제공합니다. 서비스 구성요소는 미디어 세션과 플레이어를 포함하는 MediaBrowserService
의 서브클래스로 구현됩니다. UI 및 미디어 컨트롤러가 포함된 활동에는 MediaBrowserService
와 통신하는 MediaBrowser
가 포함되어야 합니다.
MediaBrowserService
를 사용하면 앱의 UI 활동에 전혀 액세스하지 않고도 호환 기기 (예: Android Auto 및 Wear)에서 쉽게 앱을 검색하고, 앱에 연결하고, 콘텐츠를 탐색하고, 재생을 제어할 수 있습니다. 실제로 여러 앱이 동시에 동일한 MediaBrowserService
에 연결될 수 있으며 각 앱에는 자체 MediaController
가 있습니다. MediaBrowserService
를 제공하는 앱은 여러 개의 동시 연결을 처리할 수 있어야 합니다.
미디어 앱 및 Android 오디오 인프라
잘 디자인된 미디어 앱은 오디오를 재생하는 다른 앱과 '함께 잘 재생'되어야 합니다. 휴대전화를 공유하고 오디오를 사용하는 기기의 다른 앱과 협력할 준비가 되어 있어야 합니다. 또한 기기의 하드웨어 컨트롤에 응답해야 합니다.
이 모든 동작은 오디오 출력 제어에 설명되어 있습니다.
media-compat 라이브러리
media-compat 라이브러리에는 오디오 및 동영상을 재생하는 앱을 빌드하는 데 유용한 클래스가 포함되어 있습니다. 이 클래스는 Android 2.3 (API 수준 9) 이상을 실행하는 기기와 호환됩니다. 또한 다른 Android 기능과 함께 편안하고 친숙한 Android 환경을 만듭니다.
미디어 세션 및 미디어 컨트롤러의 권장되는 구현은 클래스 MediaSessionCompat
및 MediaControllerCompat
이며, 이 클래스는 media-compat 지원 라이브러리에 정의되어 있습니다. 이 클래스는 Android 5.0 (API 수준 21)에 도입된 MediaSession
및 MediaController
클래스의 이전 버전을 대체합니다. compat 클래스는 동일한 기능을 제공하지만 하나의 API에만 작성하면 되므로 앱을 더 쉽게 개발할 수 있습니다. 라이브러리는 미디어 세션 메서드를 이전 플랫폼 버전의 동등한 메서드로 변환하여 이전 버전과의 호환성을 처리합니다(가능한 경우).
이전 클래스를 사용하는 작동하는 앱이 이미 있는 경우 compat 클래스로 업데이트하는 것이 좋습니다. compat 버전을 사용하면 registerMediaButtonReceiver()
에 대한 모든 호출과 RemoteControlClient
의 모든 메서드를 삭제할 수 있습니다.
성능 측정
Android 8.0 (API 수준 26) 이상에서는 일부 미디어 클래스에서 getMetrics()
메서드를 사용할 수 있습니다. 이 메서드는 속성과 값의 맵으로 표현되는 구성 및 성능 정보가 포함된 PersistableBundle
객체를 반환합니다.
getMetrics()
메서드는 다음 미디어 클래스에 관해 정의됩니다.
MediaPlayer.getMetrics()
MediaRecorder.getMetrics()
MediaCodec.getMetrics()
MediaExtractor.getMetrics()
측정항목은 각 인스턴스에 대해 개별적으로 수집되며 인스턴스 수명 동안 지속됩니다. 사용할 수 있는 측정항목이 없으면 메서드는 null을 반환합니다. 반환되는 실제 측정항목은 클래스에 따라 다릅니다.