MediaRouteProvider – Übersicht

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.

Abbildung 1: Übersicht über die Kommunikation zwischen Mediaroute Provider-Klassen von einer Medien-App auf ein Empfängergerät übertragen.

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.