Le framework du routeur multimédia Android permet aux fabricants d'activer la lecture sur leurs appareils.
via une interface standardisée appelée MediaRouteProvider
.
Un fournisseur de routes définit une interface commune pour lire des contenus multimédias sur un appareil récepteur, ce qui
possible de lire des contenus multimédias sur votre équipement à partir de n'importe quelle application Android compatible
routes.
Ce guide explique comment créer un fournisseur de routage multimédia pour un appareil récepteur et le rendre
pour les autres applications
de lecture de contenus multimédias fonctionnant sous Android. Pour utiliser cette API, vous devez
vous devez connaître les classes clés
MediaRouteProvider
,
MediaRouteProviderDescriptor
RouteController
Présentation
Le framework du routeur multimédia Android permet aux développeurs d'applications multimédias et aux appareils de lecture de contenus multimédias
aux fabricants de se connecter via une API et
une interface utilisateur communes. Les développeurs d'applications qui
implémenter une interface MediaRouter
peut alors se connecter
un framework et de lire du contenu
sur les appareils qui participent au cadre du routeur multimédia. Multimédia
Les fabricants d'appareils de lecture peuvent participer au framework en publiant un MediaRouteProvider
qui permet à d'autres applications de se connecter à
lire des contenus multimédias
sur les récepteurs. La figure 1 montre comment une application se connecte à un récepteur
via le framework de routeur multimédia.
Lorsque vous créez un fournisseur de routage multimédia pour votre appareil récepteur, le fournisseur diffuse le aux fins suivantes:
- Décrire et publier les fonctionnalités de l'appareil récepteur afin que d'autres applications puissent le découvrir et utiliser ses fonctionnalités de lecture.
- Encapsuler l'interface de programmation du dispositif récepteur et ses communications des mécanismes de transport pour rendre le périphérique compatible avec le cadre du routeur multimédia.
Répartition des fournisseurs d'itinéraires
Un fournisseur de routage multimédia est distribué dans le cadre d'une application Android. Votre fournisseur d'itinéraires peut être
à d'autres applications en étendant
MediaRouteProviderService
ou encapsuler votre implémentation de
MediaRouteProvider
avec votre propre service et déclarer un intent.
filtre pour le fournisseur de routage multimédia. Ces étapes permettent à d'autres applications de découvrir et d'utiliser
votre route multimédia.
Remarque:L'application contenant le fournisseur de routage multimédia peut également inclure un l'interface MediaRouter au via un fournisseur d'itinéraires, mais ce n'est pas obligatoire.
Bibliothèque Support MediaRouter
Les API de routeur multimédia sont définies dans Bibliothèque AndroidX MediaRouter Vous devez ajouter cette bibliothèque à votre projet de développement d'applications. Pour en savoir plus sur l'ajout de bibliothèques Support à votre consultez Configuration de la bibliothèque Support.
Attention:Veillez à utiliser l'AndroidX
la mise en œuvre du cadre
du routeur multimédia.
N'utilisez pas l'ancien package android.media
.
Créer un service de fournisseur
Le framework du routeur multimédia doit pouvoir détecter votre fournisseur de routage multimédia et s'y connecter
pour permettre à d’autres
applications d’utiliser votre route. Pour ce faire, le framework de routeur multimédia
recherche les applications qui déclarent une action d'intent du fournisseur de routage multimédia. Lorsqu'une autre application souhaite
se connecter à votre fournisseur, le framework doit pouvoir l'appeler et s'y connecter. Votre fournisseur
doit être encapsulé dans un Service
.
L'exemple de code suivant montre la déclaration d'un service de fournisseur d'itinéraires multimédias et un filtre d'intent dans un fichier manifeste, ce qui permet au routeur multimédia de le découvrir et de l'utiliser framework:
<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>
Cet exemple de fichier manifeste déclare un service qui encapsule les classes réelles du fournisseur de routage multimédia.
Le framework du routeur multimédia Android fournit
MediaRouteProviderService
à utiliser comme wrapper de service pour
et des fournisseurs d'itinéraires multimédias. L'exemple de code suivant montre comment utiliser ce wrapper
classe:
Kotlin
class SampleMediaRouteProviderService : MediaRouteProviderService() { override fun onCreateMediaRouteProvider(): MediaRouteProvider { return SampleMediaRouteProvider(this) } }
Java
public class SampleMediaRouteProviderService extends MediaRouteProviderService { @Override public MediaRouteProvider onCreateMediaRouteProvider() { return new SampleMediaRouteProvider(this); } }
Spécifier des fonctionnalités de routage
Les applications qui se connectent au routeur multimédia peuvent détecter votre routage multimédia via votre les déclarations du fichier manifeste de l'application, mais elles doivent également connaître les capacités des routages multimédias fournissent. Les routes multimédias peuvent être de différents types et avoir différentes fonctionnalités, ainsi que d'autres applications doivent pouvoir découvrir ces informations pour déterminer s'ils sont compatibles avec votre itinéraire.
Le framework de routeur multimédia vous permet de définir et de publier les fonctionnalités de votre contenu multimédia
via des objets IntentFilter
, des objets MediaRouteDescriptor
et un MediaRouteProviderDescriptor
. Cette section explique comment utiliser ces
pour publier les détails de votre route multimédia pour d'autres applications.
Catégories de routes
Dans la description programmatique de votre fournisseur de routage multimédia, vous devez spécifier si votre fournisseur prend en charge la lecture à distance, la sortie secondaire ou les deux. Voici l'itinéraire catégories fournies par le framework de routeur multimédia:
CATEGORY_LIVE_AUDIO
: sortie du contenu audio sur un périphérique de sortie secondaire, tel qu'un système de musique sans filCATEGORY_LIVE_VIDEO
— Sortie de la vidéo sur un périphérique de sortie secondaire, comme un appareil d'affichage sans filCATEGORY_REMOTE_PLAYBACK
: lit des vidéos ou des fichiers audio sur un appareil distinct qui gère les contenus multimédias de récupération, de décodage et de lecture, Appareils Chromecast.
Pour inclure ces paramètres dans la description de votre routage multimédia, vous devez les insérer dans
Un objet IntentFilter
, que vous ajouterez par la suite
Objet 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) } } }
Java
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); } }
Si vous spécifiez l'intent CATEGORY_REMOTE_PLAYBACK
, vous devez également définir quels types de médias et quels
les commandes de lecture sont compatibles avec votre fournisseur de routage multimédia. La section suivante explique comment
spécifiez ces paramètres pour votre appareil.
Types de médias et protocoles
Un fournisseur d'itinéraires multimédias pour un appareil de lecture à distance doit spécifier les types de contenus multimédias et le transfert
qu'il prend en charge. Vous spécifiez ces paramètres à l'aide de l'IntentFilter
ainsi que addDataScheme()
et
addDataType()
de cet objet. La
L'extrait de code suivant montre comment définir un filtre d'intent pour prendre en charge des vidéos distantes.
HTTP, HTTPS et RTSP (Real Time Streaming Protocol):
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) } } ... }
Java
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); } } }
Commandes de lecture
Un fournisseur d'itinéraires multimédias qui propose la lecture à distance doit spécifier les types de commandes multimédias qu'il prend en charge. Voici les principaux types de contrôle que les routes multimédias peuvent fournir:
- Commandes de lecture, comme lecture, pause, retour arrière et avance rapide
- Les fonctionnalités de mise en file d'attente, qui permettent à l'application émettrice d'ajouter et de supprimer des éléments à partir d'une liste de lecture gérée par le dispositif récepteur.
- Les fonctionnalités de session, qui empêchent l'envoi d'applications d'interférer avec chacune en demandant à l'appareil récepteur de fournir un identifiant de session à l'application à l'origine de la demande, puis en vérifiant lors de chaque nouvelle requête de commande de lecture.
L'exemple de code suivant montre comment créer un filtre d'intent pour prendre en charge commandes de lecture de l'itinéraire multimédia de base:
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) } } ... }
Java
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); } ... }
Pour en savoir plus sur les intents de commande de lecture disponibles, consultez les
MediaControlIntent
.
MediaRouteProviderDescriptor
Après avoir défini les fonctionnalités de votre routage multimédia à l'aide d'objets IntentFilter
, vous pouvez créer un objet descripteur à publier dans
le framework de routeur multimédia Android. Cet objet descripteur contient les caractéristiques de votre contenu multimédia.
pour permettre à d'autres applications de déterminer comment interagir avec votre contenu multimédia.
via un routage réseau.
L'exemple de code suivant montre comment ajouter les filtres d'intent créés précédemment à un
MediaRouteProviderDescriptor
et définir le descripteur à utiliser par
le framework du routeur multimédia:
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 } ... }
Java
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); }
Pour en savoir plus sur les paramètres de descripteur disponibles, consultez la documentation de référence.
pour MediaRouteDescriptor
et MediaRouteProviderDescriptor
.
Contrôler les routes
Lorsqu'une application se connecte à votre fournisseur de routage multimédia, celui-ci reçoit la lecture
via le framework de routeur multimédia
envoyées sur votre route par d'autres applications. Pour gérer ces
vous devez fournir une implémentation d'une classe MediaRouteProvider.RouteController
, qui traite les commandes
et gère la communication réelle
avec votre récepteur.
Le framework du routeur multimédia appelle onCreateRouteController()
de votre fournisseur d'itinéraires pour obtenir une instance de cette classe et y acheminer les requêtes.
Voici les principales méthodes de la classe MediaRouteProvider.RouteController
, que vous devez implémenter pour
votre fournisseur de routage multimédia:
onSelect()
: appelé lorsqu'une application sélectionne votre itinéraire pour la lecture. Cette méthode vous permet d'effectuer les éventuels travaux de préparation nécessaires avant le début de la lecture du contenu multimédia.onControlRequest()
: envoie des commandes de lecture spécifiques à l'appareil récepteur.onSetVolume()
: envoie une requête à l'appareil récepteur pour régler le volume de lecture sur un une valeur spécifique.onUpdateVolume()
: envoie une requête à l'appareil récepteur pour modifier la lecture. le volume d'un volume spécifié.onUnselect()
: appelé lorsqu'une application désélectionne une route.onRelease()
: appelé lorsque le framework n'a plus besoin de la route, ce qui lui permet de libérer son ressources.
Toutes les demandes de commandes de lecture, à l'exception des changements de volume, sont dirigées vers le onControlRequest()
. Votre mise en œuvre de cette méthode doit analyser les requêtes de contrôle et y répondre.
en conséquence. Voici un exemple d'implémentation de cette méthode, qui traite les commandes pour une
itinéraire multimédia de lecture à distance:
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 } } ... }
Java
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; } ... }
Il est important de comprendre que la classe MediaRouteProvider.RouteController
est destinée à agir comme un wrapper.
pour l'API à votre équipement
de lecture multimédia. L'implémentation des méthodes de cette classe est
dépend entièrement de l'interface de programmation
fournie par votre appareil récepteur.
Exemple de code
Le MediaRouter montre comment créer un fournisseur de routage multimédia personnalisé.