제조업체는 Android 미디어 라우터 프레임워크를 통해 기기에서 재생을 사용 설정할 수 있습니다.
MediaRouteProvider
라는 표준화된 인터페이스를 통해 구현됩니다.
경로 제공자는 수신 기기에서 미디어를 재생하기 위한 공통 인터페이스를 정의하여
미디어를 지원하는 모든 Android 애플리케이션을 통해 장비에서 미디어를 재생할 수 있음
경로.
이 가이드에서는 수신 기기의 미디어 경로 제공자를 만들고 이를 만드는 방법을 설명합니다.
Android에서 실행되는 다른 미디어 재생 애플리케이션에서 사용할 수 있습니다. 이 API를 사용하려면
머신러닝 모델의
MediaRouteProvider
님,
MediaRouteProviderDescriptor
및
RouteController
:
개요
Android 미디어 라우터 프레임워크는 미디어 앱 개발자와 미디어 재생 기기를 지원합니다.
공통 API와 공통 사용자 인터페이스를 통해 연결할 수 있습니다. 앱을 개발하는
MediaRouter
인터페이스를 구현하여
콘텐츠를 재생할 수 있습니다. 미디어
재생 기기 제조업체는 다른 애플리케이션이 네트워크에 연결하여 보고하도록 허용하는 MediaRouteProvider
를 게시하여 프레임워크에 참여할 수 있습니다.
수신 기기에서 미디어를 재생합니다. 그림 1은 앱이 수신 전화에 연결하는 방법을 보여줍니다.
미디어 라우터 프레임워크로 전달할 수 있습니다.
수신 기기의 미디어 경로 제공자를 빌드하면 제공자는 다음과 같은 목적으로 사용됩니다.
- 다른 앱이 발견할 수 있도록 수신 기기의 기능을 설명하고 게시 재생 기능을 사용할 수 있습니다.
- 수신 기기의 프로그래밍 인터페이스 및 통신 래핑 장치가 미디어 라우터 프레임워크와 호환되도록 합니다.
경로 제공자 배포
미디어 경로 제공자는 Android 앱의 일부로 배포됩니다. 경로 제공자는
다른 앱에서 사용할 수 있도록 확장함으로써
MediaRouteProviderService
또는 구현 래핑
자체 서비스로 MediaRouteProvider
하고 인텐트 선언하기
미디어 경로 제공자의 필터입니다. 이러한 단계를 통해 다른 앱에서
선택합니다.
참고: 미디어 경로 제공자가 포함된 앱은 다음을 포함할 수도 있습니다. MediaRouter 인터페이스를 경로 제공자를 지정할 수 있지만 필수는 아닙니다.
MediaRouter 지원 라이브러리
미디어 라우터 API는 AndroidX MediaRouter 라이브러리 이 라이브러리를 앱 개발 프로젝트에 추가해야 합니다. 지원 라이브러리를 지원 라이브러리 설정을 참고하세요.
주의: AndroidX
미디어 라우터 프레임워크입니다.
이전 android.media
패키지를 사용하지 마세요.
제공자 서비스 만들기
미디어 라우터 프레임워크는 미디어 경로 제공자를 검색하고 연결할 수 있어야 합니다.
다른 애플리케이션이 해당 경로를 사용하도록 허용합니다. 이를 위해 미디어 라우터 프레임워크는
미디어 경로 제공자 인텐트 작업을 선언하는 앱을 찾습니다. 다른 앱에서
프레임워크가 제공자를 호출하고 연결할 수 있어야 합니다. 따라서 제공자는
Service
에 캡슐화되어야 합니다.
다음 코드 예는 미디어 경로 제공자 서비스 및 미디어 라우터에서 검색하고 사용할 수 있도록 하는 매니페스트의 인텐트 필터 프레임워크:
<service android:name=".provider.SampleMediaRouteProviderService" android:label="@string/sample_media_route_provider_service" android:process=":mrp"> <intent-filter> <action android:name="android.media.MediaRouteProviderService" /> </intent-filter> </service>
이 manifest 예는 실제 미디어 경로 제공자 클래스를 래핑하는 서비스를 선언합니다.
Android 미디어 라우터 프레임워크는
서비스 래퍼로 사용할 MediaRouteProviderService
클래스
미디어 경로 제공자. 다음 코드 예는 이 래퍼를 사용하는 방법을 보여줍니다.
클래스:
Kotlin
class SampleMediaRouteProviderService : MediaRouteProviderService() { override fun onCreateMediaRouteProvider(): MediaRouteProvider { return SampleMediaRouteProvider(this) } }
자바
public class SampleMediaRouteProviderService extends MediaRouteProviderService { @Override public MediaRouteProvider onCreateMediaRouteProvider() { return new SampleMediaRouteProvider(this); } }
경로 기능 지정
미디어 라우터 프레임워크에 연결하는 앱은 앱의 매니페스트 선언을 지원하지만 개발자가 지정하는 미디어 경로의 기능도 알아야 합니다. 확인할 수 있습니다 미디어 경로는 다양한 유형일 수 있으며 다양한 기능과 기타 앱을 포함할 수 있습니다. 해당 정보가 경로와 호환되는지 확인하려면 이러한 세부정보를 탐색할 수 있어야 합니다.
미디어 라우터 프레임워크를 사용하면 미디어의 기능을 정의하고 게시할 수 있습니다.
IntentFilter
객체, MediaRouteDescriptor
객체, MediaRouteProviderDescriptor
를 통해 라우팅합니다. 이 섹션에서는
클래스를 사용하여 다른 앱에 대한 미디어 경로의 세부정보를 게시합니다.
경로 카테고리
미디어 경로 제공자의 프로그래매틱 설명의 일부로 제공자가 원격 재생, 보조 출력 또는 둘 다를 지원하는지를 알 수 있습니다. 다음은 경로입니다. 미디어 라우터 프레임워크에서 제공하는 카테고리입니다.
CATEGORY_LIVE_AUDIO
— 무선 지원 음악 시스템과 같은 보조 출력 장치의 오디오 출력CATEGORY_LIVE_VIDEO
— 무선 디스플레이 장치와 같은 보조 출력 장치에 대한 비디오 출력입니다.CATEGORY_REMOTE_PLAYBACK
- 미디어를 처리하는 별도의 기기에서 동영상 또는 오디오 재생 검색, 디코딩 및 재생(예: Chromecast 기기.
미디어 경로의 설명에 이러한 설정을 포함하려면
IntentFilter
객체(나중에
MediaRouteDescriptor
객체:
Kotlin
class SampleMediaRouteProvider(context: Context) : MediaRouteProvider(context) { companion object { private val CONTROL_FILTERS_BASIC: ArrayList<IntentFilter> = IntentFilter().run { addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK) arrayListOf(this) } } }
자바
public final class SampleMediaRouteProvider extends MediaRouteProvider { private static final ArrayList<IntentFilter> CONTROL_FILTERS_BASIC; static { IntentFilter videoPlayback = new IntentFilter(); videoPlayback.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); CONTROL_FILTERS_BASIC = new ArrayList<IntentFilter>(); CONTROL_FILTERS_BASIC.add(videoPlayback); } }
CATEGORY_REMOTE_PLAYBACK
인텐트를 지정하는 경우 미디어 유형과 미디어의 유형도 정의해야 합니다.
미디어 경로 제공자가 재생 컨트롤을 지원합니다. 다음 섹션에서는
기기에서 이 설정을 지정할 수 있습니다.
미디어 유형 및 프로토콜
원격 재생 기기의 미디어 경로 제공자는 미디어 유형과 전송을 지정해야 합니다.
지원하는 프로토콜입니다 IntentFilter
를 사용하여 이러한 설정을 지정합니다.
클래스와 addDataScheme()
및
addDataType()
메서드를 호출합니다. 이
다음 코드 스니펫은 원격 동영상 지원을 위한 인텐트 필터를 정의하는 방법을 보여줍니다.
http, https 및 RTSP (실시간 스트리밍 프로토콜)를 사용하여 동영상을 재생할 수 있습니다.
Kotlin
class SampleMediaRouteProvider(context: Context) : MediaRouteProvider(context) { companion object { private fun IntentFilter.addDataTypeUnchecked(type: String) { try { addDataType(type) } catch (ex: IntentFilter.MalformedMimeTypeException) { throw RuntimeException(ex) } } private val CONTROL_FILTERS_BASIC: ArrayList<IntentFilter> = IntentFilter().run { addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK) addAction(MediaControlIntent.ACTION_PLAY) addDataScheme("http") addDataScheme("https") addDataScheme("rtsp") addDataTypeUnchecked("video/*") arrayListOf(this) } } ... }
자바
public final class SampleMediaRouteProvider extends MediaRouteProvider { private static final ArrayList<IntentFilter> CONTROL_FILTERS_BASIC; static { IntentFilter videoPlayback = new IntentFilter(); videoPlayback.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); videoPlayback.addAction(MediaControlIntent.ACTION_PLAY); videoPlayback.addDataScheme("http"); videoPlayback.addDataScheme("https"); videoPlayback.addDataScheme("rtsp"); addDataTypeUnchecked(videoPlayback, "video/*"); CONTROL_FILTERS_BASIC = new ArrayList<IntentFilter>(); CONTROL_FILTERS_BASIC.add(videoPlayback); } ... private static void addDataTypeUnchecked(IntentFilter filter, String type) { try { filter.addDataType(type); } catch (MalformedMimeTypeException ex) { throw new RuntimeException(ex); } } }
재생 컨트롤
원격 재생을 제공하는 미디어 경로 제공자는 미디어 컨트롤 유형을 지정해야 합니다. 살펴보겠습니다 다음은 미디어 경로에서 제공할 수 있는 일반적인 컨트롤 유형입니다.
- 재생 컨트롤. 예: 재생, 일시중지, 되감기, 빨리 감기
- 현재 재생목록 기능: 전송 앱에서 항목을 추가 및 삭제할 수 있음 수신 장치가 유지관리하는 재생목록으로부터 재생되도록 해야 합니다.
- 세션 기능 - 전송 앱이 각 세션을 방해하지 않도록 방지 다른 하나는 수신 기기가 요청하는 앱에 세션 ID를 제공하도록 한 다음 각 후속 재생 컨트롤 요청에서 해당 ID를 호출합니다.
다음 코드 예는 다음을 지원하기 위한 인텐트 필터를 구성하는 방법을 보여줍니다. 기본 미디어 경로 재생 컨트롤:
Kotlin
class SampleMediaRouteProvider(context: Context) : MediaRouteProvider(context) { companion object { ... private val CONTROL_FILTERS_BASIC: ArrayList<IntentFilter> = run { val videoPlayback: IntentFilter = ... ... val playControls = IntentFilter().apply { addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK) addAction(MediaControlIntent.ACTION_SEEK) addAction(MediaControlIntent.ACTION_GET_STATUS) addAction(MediaControlIntent.ACTION_PAUSE) addAction(MediaControlIntent.ACTION_RESUME) addAction(MediaControlIntent.ACTION_STOP) } arrayListOf(videoPlayback, playControls) } } ... }
자바
public final class SampleMediaRouteProvider extends MediaRouteProvider { private static final ArrayList<IntentFilter> CONTROL_FILTERS_BASIC; static { ... IntentFilter playControls = new IntentFilter(); playControls.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); playControls.addAction(MediaControlIntent.ACTION_SEEK); playControls.addAction(MediaControlIntent.ACTION_GET_STATUS); playControls.addAction(MediaControlIntent.ACTION_PAUSE); playControls.addAction(MediaControlIntent.ACTION_RESUME); playControls.addAction(MediaControlIntent.ACTION_STOP); CONTROL_FILTERS_BASIC = new ArrayList<IntentFilter>(); CONTROL_FILTERS_BASIC.add(videoPlayback); CONTROL_FILTERS_BASIC.add(playControls); } ... }
사용 가능한 재생 컨트롤 인텐트에 관한 자세한 내용은
MediaControlIntent
클래스.
MediaRouteProviderDescriptor
IntentFilter
객체를 사용하여 미디어 경로의 기능을 정의한 후에는 다음에 게시할 설명자 객체를 생성할 수 있습니다.
미디어 라우터 프레임워크입니다. 이 설명자 객체에는 미디어의 세부사항이 포함됩니다.
경로의 기능을 사용하여 다른 애플리케이션이 미디어와 상호 작용하는 방법을 결정할 수 있도록 합니다.
있습니다.
다음 코드 예는 이전에 만든 인텐트 필터를
MediaRouteProviderDescriptor
하고 다음에서 사용할 설명어를 설정합니다.
미디어 라우터 프레임워크입니다.
Kotlin
class SampleMediaRouteProvider(context: Context) : MediaRouteProvider(context) { init { publishRoutes() } private fun publishRoutes() { val resources = context.resources val routeName: String = resources.getString(R.string.variable_volume_basic_route_name) val routeDescription: String = resources.getString(R.string.sample_route_description) // Create a route descriptor using previously created IntentFilters val routeDescriptor: MediaRouteDescriptor = MediaRouteDescriptor.Builder(VARIABLE_VOLUME_BASIC_ROUTE_ID, routeName) .setDescription(routeDescription) .addControlFilters(CONTROL_FILTERS_BASIC) .setPlaybackStream(AudioManager.STREAM_MUSIC) .setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE) .setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE) .setVolumeMax(VOLUME_MAX) .setVolume(mVolume) .build() // Add the route descriptor to the provider descriptor val providerDescriptor: MediaRouteProviderDescriptor = MediaRouteProviderDescriptor.Builder() .addRoute(routeDescriptor) .build() // Publish the descriptor to the framework descriptor = providerDescriptor } ... }
자바
public SampleMediaRouteProvider(Context context) { super(context); publishRoutes(); } private void publishRoutes() { Resources r = getContext().getResources(); // Create a route descriptor using previously created IntentFilters MediaRouteDescriptor routeDescriptor = new MediaRouteDescriptor.Builder( VARIABLE_VOLUME_BASIC_ROUTE_ID, r.getString(R.string.variable_volume_basic_route_name)) .setDescription(r.getString(R.string.sample_route_description)) .addControlFilters(CONTROL_FILTERS_BASIC) .setPlaybackStream(AudioManager.STREAM_MUSIC) .setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE) .setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE) .setVolumeMax(VOLUME_MAX) .setVolume(mVolume) .build(); // Add the route descriptor to the provider descriptor MediaRouteProviderDescriptor providerDescriptor = new MediaRouteProviderDescriptor.Builder() .addRoute(routeDescriptor) .build(); // Publish the descriptor to the framework setDescriptor(providerDescriptor); }
사용 가능한 설명어 설정에 관한 자세한 내용은 참조 문서를 확인하세요.
MediaRouteDescriptor
및 MediaRouteProviderDescriptor
경로 제어
애플리케이션이 미디어 경로 제공자에 연결되면 제공자가 재생을 수신합니다.
명령어에 대한 액세스를 제한할 수 있습니다. 이러한 문제를
요청을 처리하려면 명령어를 처리하는 MediaRouteProvider.RouteController
클래스의 구현을 제공해야 합니다.
수신 장치에 대한 실제 통신을 처리합니다.
미디어 라우터 프레임워크는 onCreateRouteController()
를 호출합니다.
메서드를 사용하여 이 클래스의 인스턴스를 가져온 다음 요청을 이 인스턴스로 라우팅합니다.
다음은 MediaRouteProvider.RouteController
클래스의 주요 메서드이며 다음을 위해 구현해야 합니다.
미디어 경로 제공자:
onSelect()
— 애플리케이션이 재생을 위해 경로를 선택할 때 호출됩니다. 이 메서드를 사용하여 미디어 재생이 시작되기 전에 필요할 수 있는 모든 준비 작업이 포함됩니다.onControlRequest()
- 특정 재생 명령어를 수신 기기로 전송합니다.onSetVolume()
- 수신 기기에 요청을 전송하여 재생 볼륨을 알 수 있습니다.onUpdateVolume()
- 수신 기기에 요청을 전송하여 재생을 수정합니다. 자동으로 조정합니다.onUnselect()
- 애플리케이션이 경로를 선택 해제할 때 호출됩니다.onRelease()
— 프레임워크에서 경로가 더 이상 필요하지 않을 때 호출되어 리소스를 배포합니다
볼륨 변경을 제외한 모든 재생 컨트롤 요청은 onControlRequest()
로 전달됩니다.
메서드를 사용하여 축소하도록 요청합니다. 이 메서드의 구현은 제어 요청을 파싱하여 응답해야 합니다.
적절하게 조정할 수 있습니다 다음은
원격 재생 미디어 경로:
Kotlin
private class SampleRouteController : MediaRouteProvider.RouteController() { ... override fun onControlRequest( intent: Intent, callback: MediaRouter.ControlRequestCallback? ): Boolean { return if (intent.hasCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) { val action = intent.action when (action) { MediaControlIntent.ACTION_PLAY -> handlePlay(intent, callback) MediaControlIntent.ACTION_ENQUEUE -> handleEnqueue(intent, callback) MediaControlIntent.ACTION_REMOVE -> handleRemove(intent, callback) MediaControlIntent.ACTION_SEEK -> handleSeek(intent, callback) MediaControlIntent.ACTION_GET_STATUS -> handleGetStatus(intent, callback) MediaControlIntent.ACTION_PAUSE -> handlePause(intent, callback) MediaControlIntent.ACTION_RESUME -> handleResume(intent, callback) MediaControlIntent.ACTION_STOP -> handleStop(intent, callback) MediaControlIntent.ACTION_START_SESSION -> handleStartSession(intent, callback) MediaControlIntent.ACTION_GET_SESSION_STATUS -> handleGetSessionStatus(intent, callback) MediaControlIntent.ACTION_END_SESSION -> handleEndSession(intent, callback) else -> false }.also { Log.d(TAG, sessionManager.toString()) } } else { false } } ... }
자바
private final class SampleRouteController extends MediaRouteProvider.RouteController { ... @Override public boolean onControlRequest(Intent intent, ControlRequestCallback callback) { String action = intent.getAction(); if (intent.hasCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) { boolean success = false; if (action.equals(MediaControlIntent.ACTION_PLAY)) { success = handlePlay(intent, callback); } else if (action.equals(MediaControlIntent.ACTION_ENQUEUE)) { success = handleEnqueue(intent, callback); } else if (action.equals(MediaControlIntent.ACTION_REMOVE)) { success = handleRemove(intent, callback); } else if (action.equals(MediaControlIntent.ACTION_SEEK)) { success = handleSeek(intent, callback); } else if (action.equals(MediaControlIntent.ACTION_GET_STATUS)) { success = handleGetStatus(intent, callback); } else if (action.equals(MediaControlIntent.ACTION_PAUSE)) { success = handlePause(intent, callback); } else if (action.equals(MediaControlIntent.ACTION_RESUME)) { success = handleResume(intent, callback); } else if (action.equals(MediaControlIntent.ACTION_STOP)) { success = handleStop(intent, callback); } else if (action.equals(MediaControlIntent.ACTION_START_SESSION)) { success = handleStartSession(intent, callback); } else if (action.equals(MediaControlIntent.ACTION_GET_SESSION_STATUS)) { success = handleGetSessionStatus(intent, callback); } else if (action.equals(MediaControlIntent.ACTION_END_SESSION)) { success = handleEndSession(intent, callback); } Log.d(TAG, sessionManager.toString()); return success; } return false; } ... }
MediaRouteProvider.RouteController
클래스가 래퍼 역할을 하기 위한 것임을 알아야 합니다.
전송합니다. 이 클래스의 메서드 구현은
수신 기기에서 제공하는 프로그래매틱 인터페이스에 따라 완전히 달라집니다.
샘플 코드
MediaRouter 샘플은 커스텀 미디어 경로 제공자를 만드는 방법을 보여줍니다.