Mit dem Media Router-Framework von Android können Hersteller die Wiedergabe auf ihren Geräten aktivieren.
über eine standardisierte Schnittstelle namens MediaRouteProvider
an.
Ein Routenanbieter definiert eine gemeinsame Schnittstelle für die Wiedergabe von Medien auf einem Empfängergerät, sodass es
Medien von jeder Android-App, die Medien unterstützt,
Routen planen.
In diesem Leitfaden wird erläutert, wie Sie einen
Media Route Provider für ein Empfängergerät erstellen
für andere Android-Apps zur Medienwiedergabe verfügbar. Um diese API zu verwenden, müssen Sie
sollten mit den wichtigsten Klassen vertraut sein,
MediaRouteProvider
,
MediaRouteProviderDescriptor
und
RouteController
Übersicht
Das Media Router-Framework von Android ermöglicht Entwicklern von Medien-Apps und Geräten für die Medienwiedergabe.
über eine gemeinsame API und eine gemeinsame
Benutzeroberfläche zu verbinden. App-Entwickler, die
Implementieren einer MediaRouter
-Schnittstelle kann dann eine Verbindung zum
und Inhalte auf Geräten wiedergeben,
die Teil des Media Router-Frameworks sind. Medien
Hersteller von Wiedergabegeräten können an dem Framework teilnehmen, indem sie eine MediaRouteProvider
veröffentlichen, mit der andere Anwendungen eine Verbindung zu und
Medien auf den Empfängergeräten abzuspielen. In Abbildung 1 sehen Sie, wie sich eine App mit einem Empfangsgerät verbindet.
über das Media Router-Framework.
Wenn Sie einen Medienroutenanbieter für Ihr Empfangsgerät erstellen, stellt dieser folgenden Zwecken:
- Funktionen des Empfängergeräts beschreiben und veröffentlichen, damit andere Apps es finden können und die Wiedergabefunktionen nutzen.
- Programmierschnittstelle des Empfängergeräts und dessen Kommunikation verpacken Transportmechanismen, um das Gerät mit dem Media Router-Framework kompatibel zu machen.
Verteilung der Routenanbieter
Ein Medienroutenanbieter wird als Teil einer Android-App bereitgestellt. Ihr Routenanbieter kann
anderen Apps zur Verfügung gestellt werden,
MediaRouteProviderService
oder die Implementierung von
MediaRouteProvider
durch Ihren eigenen Dienst und die Deklaration eines Intents
Filter für den Anbieter der Medienroute. Mit diesen Schritten können andere Apps
Ihrer Medienroute.
Hinweis:Die App mit dem Medienroutenanbieter kann auch einen MediaRouter-Schnittstelle mit dem Routenanbieter, aber das ist nicht erforderlich.
MediaRouter-Supportbibliothek
Die Media Router APIs sind in der AndroidX-MediaRouter-Bibliothek Sie müssen diese Bibliothek Ihrem App-Entwicklungsprojekt hinzufügen. Weitere Informationen zum Hinzufügen von Supportbibliotheken zu Ihrem finden Sie unter Support Library Setup (Einrichtung der Supportbibliothek).
Achtung: Verwenden Sie auf jeden Fall die Methode AndroidX
.
Implementierung des Media Router-Frameworks.
Verwende nicht das ältere android.media
-Paket.
Anbieterdienst erstellen
Das Media Router-Framework muss Ihren Medienroutenanbieter erkennen und sich mit ihm verbinden können
damit andere Anwendungen Ihre Route nutzen können. Dazu muss das Media Router-Framework
sucht nach Apps, die eine Absichtsaktion des Anbieters von Medienrouten deklarieren. Wenn eine andere App
eine Verbindung zu Ihrem Anbieter herstellen, muss das Framework
in der Lage sein, diesen aufzurufen und eine Verbindung herzustellen.
muss in einer Service
gekapselt werden.
Der folgende Beispielcode zeigt die Deklaration eines Media Route Provider-Dienstes und Intent-Filter in einem Manifest, mit dem er vom Media Router erkannt und verwendet werden kann 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>
In diesem Manifestbeispiel wird ein Dienst deklariert, der die tatsächlichen Klassen des Anbieters von Medienrouten umschließt.
Das Media Router-Framework von Android bietet
Klasse MediaRouteProviderService
zur Verwendung als Dienst-Wrapper für
Anbieter von Medienrouten. Der folgende Beispielcode zeigt, wie dieser Wrapper verwendet wird.
Klasse:
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); } }
Routenfunktionen angeben
Apps, die eine Verbindung mit dem Media Router-Framework herstellen, können Ihre Medienroute über Ihr Manifestdeklarationen der App. Der Nutzer muss aber auch die Funktionen der Medienrouten kennen, die Sie bereitstellen. Medienrouten können verschiedene Typen und unterschiedliche Funktionen sowie andere Apps haben müssen diese Details erkennen können, um festzustellen, ob sie mit deiner Route kompatibel sind.
Mit dem Media Router-Framework können Sie die Funktionen Ihrer Medien definieren und veröffentlichen
IntentFilter
-Objekte, MediaRouteDescriptor
-Objekte und ein MediaRouteProviderDescriptor
-Objekt weiterleiten. In diesem Abschnitt wird erläutert, wie Sie diese
-Klassen, um die Details Ihrer Medienroute für andere Apps zu veröffentlichen.
Routenkategorien
Als Teil der programmatischen Beschreibung Ihres Medienroutenanbieters müssen Sie ob dein Anbieter Remote-Wiedergabe, sekundäre Ausgabe oder beides unterstützt. Das sind die Routen Kategorien bereitgestellt werden, die vom Media Router-Framework bereitgestellt werden:
CATEGORY_LIVE_AUDIO
– Ausgabe der Audiodaten an ein sekundäres Ausgabegerät, z. B. ein kabelloses Musiksystem.CATEGORY_LIVE_VIDEO
– Ausgabe des Videos auf einem sekundären Ausgabegerät, z. B. kabellose Anzeigegeräte.CATEGORY_REMOTE_PLAYBACK
: Spielt Video oder Audio auf einem separaten Gerät ab, das Medien verarbeitet. abrufen, decodieren und wiedergeben, z. B. Chromecast-Geräte
Um diese Einstellungen in eine Beschreibung Ihrer Medienroute aufzunehmen, fügen Sie sie in
Ein IntentFilter
-Objekt, das Sie später einem
MediaRouteDescriptor
-Objekt:
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); } }
Wenn Sie den Intent CATEGORY_REMOTE_PLAYBACK
angeben, müssen Sie auch festlegen, welche Medientypen und
Wiedergabesteuerung wird vom Anbieter Ihrer Medienroute unterstützt. Im nächsten Abschnitt wird beschrieben, wie Sie
legen Sie diese Einstellungen für Ihr Gerät fest.
Medientypen und Protokolle
Ein Medienroutenanbieter für ein Remote-Wiedergabegerät muss die Medientypen und die Übertragung angeben
unterstützten Protokollen. Diese Einstellungen legen Sie mithilfe der IntentFilter
fest
und den addDataScheme()
- und
addDataType()
-Methoden dieses Objekts. Die
Das folgende Code-Snippet zeigt, wie ein Intent-Filter zur Unterstützung von Remote-Videos definiert wird
Wiedergabe über HTTP, HTTPS und Real Time Streaming Protocol (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) } } ... }
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); } } }
Wiedergabesteuerung
Ein Anbieter von Medienrouten, der die Remote-Wiedergabe anbietet, muss die Typen der Mediensteuerung angeben unterstützt wird. Dies sind die allgemeinen Arten von Steuerelementen, die Medienrouten bieten:
- Steuerelemente für die Wiedergabe, z. B. Wiedergabe, Pause, Zurück- und Vorspulen
- Wiedergabelisten-Funktionen, mit denen die sendende App Elemente hinzufügen und entfernen kann aus einer Playlist stammen, die vom Empfängergerät verwaltet wird.
- Sitzungsfunktionen, die verhindern, dass Apps diese Dienste gegenseitig beeinträchtigen indem das Empfängergerät der anfragenden App eine Sitzungs-ID sendet und dann bei jeder nachfolgenden Wiedergabesteuerungsanfrage an diese ID.
Das folgende Codebeispiel zeigt, wie Sie einen Intent-Filter zur Unterstützung von einfache Wiedergabesteuerung für die Medienroute:
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); } ... }
Weitere Informationen zu den verfügbaren Intents für die Wiedergabesteuerung findest du in der
Klasse MediaControlIntent
.
MediaRouteProviderDescriptor
Nachdem Sie die Funktionen Ihrer Medienroute mithilfe von IntentFilter
-Objekten definiert haben, können Sie ein Deskriptorobjekt für die Veröffentlichung erstellen.
Media Router-Framework von Android. Dieses Deskriptorobjekt enthält die Details Ihrer Medien
Ihrer Route, sodass andere Anwendungen bestimmen können, wie sie mit Ihren Medien interagieren.
Route.
Der folgende Beispielcode zeigt, wie Sie die zuvor erstellten Intent-Filter einem
MediaRouteProviderDescriptor
und legen Sie den Deskriptor zur Verwendung durch
Media Router-Framework:
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); }
Weitere Informationen zu den verfügbaren Deskriptoreinstellungen finden Sie in der Referenzdokumentation.
für MediaRouteDescriptor
und MediaRouteProviderDescriptor
.
Routen steuern
Wenn eine Anwendung eine Verbindung zu Ihrem Medienroutenanbieter herstellt, empfängt der Anbieter die Wiedergabe
Befehle über das Media Router-Framework, das von anderen Apps an Ihre Route gesendet wird. Um diese Probleme zu verarbeiten,
-Anfragen, müssen Sie eine Implementierung einer MediaRouteProvider.RouteController
-Klasse bereitstellen, die die Befehle verarbeitet.
und übernimmt die eigentliche Kommunikation
mit dem Empfängergerät.
Das Media Router-Framework ruft die Funktion onCreateRouteController()
auf.
Ihres Routenanbieters, um eine Instanz dieser Klasse abzurufen, und leitet dann Anfragen an diese weiter.
Dies sind die Schlüsselmethoden der MediaRouteProvider.RouteController
-Klasse, die du für die
Ihrem Medienroutenanbieter:
onSelect()
– Wird aufgerufen, wenn eine Anwendung Ihre Route für die Wiedergabe auswählt. Sie verwenden diese Methode, um alle Vorbereitungsschritte, die vor Beginn der Medienwiedergabe erforderlich sind.onControlRequest()
: sendet bestimmte Wiedergabebefehle an das empfangende Gerät.onSetVolume()
: Sendet eine Anfrage an das empfangende Gerät, um die Wiedergabelautstärke auf einen -Wert angeben.onUpdateVolume()
: Sendet eine Anfrage zum Ändern der Wiedergabe an das empfangende Gerät. Lautstärke um einen bestimmten Wert ändern.onUnselect()
: Wird aufgerufen, wenn eine Anwendung die Auswahl einer Route aufhebt.onRelease()
– Wird aufgerufen, wenn die Route vom Framework nicht mehr benötigt wird. Ressourcen.
Alle Anfragen zur Wiedergabesteuerung, mit Ausnahme von Lautstärkeänderungen, werden an onControlRequest()
weitergeleitet
. Die Implementierung dieser Methode muss die Kontrollanfragen parsen und darauf antworten
angemessen. Hier ist eine beispielhafte Implementierung dieser Methode, mit der Befehle für ein
Medienroute für die Remote-Wiedergabe:
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; } ... }
Es ist wichtig zu verstehen, dass die Klasse MediaRouteProvider.RouteController
als Wrapper dienen soll
für die API zu Ihrer
Medienwiedergabegeräte. Die Implementierung der Methoden in dieser Klasse
die vollständig von der programmatischen Schnittstelle abhängen, die vom Empfängergerät bereitgestellt wird.
Beispielcode
MediaRouter Im Beispiel wird gezeigt, wie Sie einen benutzerdefinierten Medienroutenanbieter erstellen.