MediaRouteProvider'a genel bakış

Android medya yönlendirici çerçevesi, üreticilerin cihazlarında oynatmayı etkinleştirmesine olanak tanır. MediaRouteProvider adı verilen standartlaştırılmış bir arayüz üzerinden. Rota sağlayıcı, alıcı cihazda medya oynatmak için ortak bir arayüz tanımlar. medya destekleyen herhangi bir Android uygulamalarından ekipmanınızda medya oynatabilirsiniz gösterir.

Bu kılavuzda, alıcı cihaz için medya rota sağlayıcısı oluşturma ve bunu yapma Android üzerinde çalışan diğer medya oynatma uygulamaları tarafından kullanılabilir. Bu API'yi kullanmak için ve proje başlatma belgesinin MediaRouteProvider MediaRouteProviderDescriptor ve RouteController.

Genel Bakış

Android medya yönlendirici çerçevesi, medya uygulaması geliştiricilerinin ve medya oynatma cihazının üreticilerin ortak bir API ve ortak kullanıcı arayüzü üzerinden bağlantı kurmasını sağlar. Şu uygulama geliştiricileri: bir MediaRouter arayüzü uygulayın, ardından çerçevesini ve içeriği oynatarak, medya yönlendiricisine katılmalarını sağlar. Medya oynatma cihazı üreticileri, diğer uygulamaların bağlantı kurmasına izin veren bir MediaRouteProvider yayınlayarak çerçeveye katılabilir ve alıcı cihazlarda medya oynatma özelliği. Şekil 1'de bir uygulamanın alıcı ağına nasıl bağlandığı gösterilmektedir cihazındaki izleme kodu.

Şekil 1. Medya yönlendirme sağlayıcısı sınıflarının nasıl iletişim sağladığına genel bakış alıcı cihaza aktarabilirsiniz.

Alıcı cihazınız için bir medya rota sağlayıcısı oluşturduğunuzda, sağlayıcı amaçlar:

  • Diğer uygulamaların keşfedebilmesi için alıcı cihazın özelliklerini açıklayın ve yayınlayın. ve oynatma özelliklerini kullanın.
  • Alıcı cihazın ve iletişiminin programlama arayüzünü sarmalayın ve cihazı medya yönlendiricisinin çerçevesiyle uyumlu hale getirecek taşıma mekanizmaları kullanılmaktadır.

Rota sağlayıcıların dağıtımı

Bir Android uygulaması kapsamında bir medya rota sağlayıcısı dağıtılmıştır. Rota sağlayıcınız: diğer uygulamalara kullanılabilmesi için MediaRouteProviderService veya Kendi hizmetiniz ile MediaRouteProvider ve bir amaç beyan edin filtre ayarını seçin. Bu adımlar, diğer uygulamaların medya rotanız.

Not: Medya rota sağlayıcısını içeren uygulama, bir MediaRouter arayüzünü rota sağlayıcıdır, ancak bu zorunlu değildir.

MediaRouter destek kitaplığı

Medya yönlendirici API'leri AndroidX MediaRouter kitaplığı Bu kitaplığı uygulama geliştirme projenize eklemelisiniz. Destek Kitaplığı Kurulumu sayfasına bakın.

Dikkat: AndroidX özelliğini kullandığınızdan emin olun ve medya yönlendiricisi çerçevesinin uygulanmasını sağlar. Eski android.media paketini kullanmayın.

Sağlayıcı Hizmeti Oluşturma

Medya yönlendirici çerçevesinin, medya yönlendirme sağlayıcınızı bulup bağlanabilmesi gerekir ve diğer uygulamaların rotanızı kullanmasına izin verin. Bunu yapmak için de medya yönlendiricisinin çerçevesi medya yönlendirme sağlayıcısı amaç işlemi belirten uygulamaları arar. Başka bir uygulama sağlayıcınıza bağlanabiliyorsanız, çerçevenin onu çağırıp bağlanabilmesi gerekir. Böylece bir Service içine alınmalıdır.

Aşağıdaki örnek kod, bir medya rota sağlayıcı hizmetinin beyanını ve Manifest dosyasındaki intent filtresi. Bu filtre, medya yönlendiricisi tarafından keşfedilmesine ve kullanılmasına olanak tanır. çerçeve:

<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>

Bu manifest örneğinde, gerçek medya yönlendirme sağlayıcı sınıflarını sarmalayan bir hizmet bildirilmektedir. Android medya yönlendirici çerçevesi, Şunun için hizmet sarmalayıcı olarak kullanılacak MediaRouteProviderService sınıf: medya yönlendirme sağlayıcıları. Aşağıdaki örnek kod, bu sarmalayıcının nasıl kullanılacağını gösterir sınıf:

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);
    }
}

Rota Özelliklerini Belirtme

Medya yönlendirici çerçevesine bağlanan uygulamalar, izin vermelisiniz. Ayrıca kullanıcıların, kullandığınız medya yönlendirmelerinin özelliklerini de yardımcı olmaktır. Medya rotaları farklı türlerde olabilir, farklı özelliklere ve başka uygulamalara sahip olabilir. rotanızla uyumlu olup olmadığını belirlemek için bu ayrıntıları keşfedebilmelisiniz.

Medya yönlendirici çerçevesi, medyalarınızın özelliklerini tanımlamanıza ve yayınlamanıza olanak tanır. IntentFilter nesne, MediaRouteDescriptor nesne ve MediaRouteProviderDescriptor üzerinden rota oluştur. Bu bölümde, bu hedeflerin sınıfları inceleyin.

Rota kategorileri

Medya rotası sağlayıcınızın programatik açıklamasının bir parçası olarak şunları belirtmeniz gerekir: sağlayıcınızın uzaktan oynatmayı, ikincil çıkışı veya her ikisini de destekleyip desteklemediği. Rotalar bunlar medya yönlendirici çerçevesi tarafından sağlanan kategoriler:

  • CATEGORY_LIVE_AUDIO. — Kablosuz özellikli müzik sistemi gibi ikincil bir çıkış cihazına ses çıkışı.
  • CATEGORY_LIVE_VIDEO. : Videonun, kablosuz ekran cihazları gibi ikincil bir çıkış cihazına gönderilmesi.
  • CATEGORY_REMOTE_PLAYBACK — Videoyu veya sesi, medyayı işleyen ayrı bir cihazda oynatın oynatma, geri alma, kod çözme ve oynatma gibi Chromecast cihazlar.

Bu ayarları medya rotanızın açıklamasına eklemek için, onları IntentFilter nesnesini, daha sonra MediaRouteDescriptor nesne:

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);
    }
}

CATEGORY_REMOTE_PLAYBACK amacını belirtirseniz hangi medya türlerini ve oynatma kontrolleri medya rotası sağlayıcınız tarafından destekleniyor. Bir sonraki bölümde, bu ayarları cihazınız için belirleyin.

Medya türleri ve protokolleri

Uzaktan oynatma cihazının medya rota sağlayıcısı, medya türlerini ve aktarım protokolleri ekleyebilirsiniz. Bu ayarları, IntentFilter ve addDataScheme() ve addDataType() yöntemini çağırın. İlgili içeriği oluşturmak için kullanılan Aşağıdaki kod snippet'i, uzak videoyu desteklemek için bir intent filtresinin nasıl tanımlanacağını gösterir. http, https ve Gerçek Zamanlı Akış Protokolü (RTSP) kullanarak oynatma:

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);
        }
    }
}

Oynatma kontrolleri

Uzaktan oynatma sunan bir medya rota sağlayıcısı, medya denetimi türlerini belirtmelidir yardımcı olur. Medya rotalarının sağlayabileceği genel kontrol türleri şunlardır:

  • Oynat, duraklatma, geri sarma ve ileri sarma gibi oynatma kontrolleri.
  • Gönderen uygulamanın öğe ekleyip kaldırmasına olanak tanıyan sıralama özellikleri alıcı cihaz tarafından yönetilen bir oynatma listesinden.
  • Uygulamaların her bir içeriğe müdahale etmesini engelleyen oturum özellikleri Alıcı cihazın, istekte bulunan uygulamaya bir oturum kimliği sağlamasını ve daha sonra, isteğiyle birlikte tekrar gönderir.

Aşağıdaki kod örneğinde, DMAIC ve PDCA gibi temel medya rota oynatma kontrolleri:

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);
    }
    ...
}

Kullanılabilen oynatma kontrolü amaçları hakkında daha fazla bilgi için MediaControlIntent sınıf.

MediaRouteProviderDescriptor

IntentFilter nesnelerini kullanarak medya yönlendirmenizin özelliklerini tanımladıktan sonra, yayınlamak için bir tanımlayıcı nesne oluşturabilirsiniz çerçevesini kullanıyor. Bu tanımlayıcı nesne, medyanızın bilgilerini içerir diğer uygulamaların medyanızla nasıl etkileşimde bulunacağını belirleyebilmesi için yol gösterir.

Aşağıdaki örnek kod, önceden oluşturulan intent filtrelerinin MediaRouteProviderDescriptor ve tanımlayıcıyı şunun tarafından kullanılacak şekilde ayarlayın: medya yönlendiricisi çerçevesine bakalım:

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);
}

Mevcut tanımlayıcı ayarları hakkında daha fazla bilgi için referans belgelerine bakın MediaRouteDescriptor ve MediaRouteProviderDescriptor için.

Rotaları Denetleme

Bir uygulama medya rotası sağlayıcınıza bağlandığında sağlayıcı, oynatmayı alır başka uygulamalar tarafından rotanıza gönderilen medya yönlendirici çerçevesi aracılığıyla komutlar verir. Bunları ele almak için: komutları işleyen bir MediaRouteProvider.RouteController sınıfının uygulamasını sağlamanız gerekir. ve alıcı cihazınızla gerçek iletişimi sağlar.

Medya yönlendirici çerçevesi, onCreateRouteController() yöntemini kullanın. Bunlar, MediaRouteProvider.RouteController sınıfının temel yöntemleridir ve medya yönlendirme sağlayıcınız:

  • onSelect(). — Bir uygulama, oynatma için rotanızı seçtiğinde çağrılır. Bu yöntemi kullanarak medya oynatmaya başlamadan önce gerekli olabilecek tüm hazırlık çalışmaları.
  • onControlRequest() — Belirli oynatma komutlarını alıcı cihaza gönderir.
  • onSetVolume() — Alıcı cihaza, oynatma ses düzeyinin şu şekilde ayarlanması için istek gönderir: belirli bir değer.
  • onUpdateVolume() — Alıcı cihaza, oynatmayı değiştirmesi için istek gönderir. ses seviyesini belirli bir miktara ayarlayın.
  • onUnselect() — Uygulama, rota seçimini kaldırdığında çağrılır.
  • onRelease(). — Rota, çerçeve tarafından artık ihtiyaç duyulmadığında çağrılır ve rotanın serbest bırakılmasına olanak tanır. kaynaklar.

Ses seviyesi değişiklikleri hariç tüm oynatma kontrol istekleri onControlRequest() adresine yönlendirilir. yöntemidir. Bu yöntemi uygulamanız, kontrol isteklerini ayrıştırıp bunları yanıtlamalıdır sağlayabilir. Burada, uzaktan oynatma medya rotası:

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;
    }
    ...
}

MediaRouteProvider.RouteController sınıfının sarmalayıcı işlevi gördüğünü anlamak önemlidir. lisansınızı kullanabilirsiniz. Bu sınıftaki yöntemlerin uygulanması Bu, tamamen alıcı cihazınızın sağladığı programatik arayüze bağlıdır.

Örnek Kod

MediaRouter örneği, özel bir medya rotası sağlayıcısının nasıl oluşturulacağını gösterir.