Android medya yönlendiricisi çerçevesi, üreticilerin MediaRouteProvider
adı verilen standart bir arayüz aracılığıyla cihazlarında oynatmayı etkinleştirmelerini sağlar.
Rota sağlayıcı, alıcı cihazda medya oynatmak için ortak bir arayüz tanımlar. Bu sayede, medya yönlendirmelerini destekleyen herhangi bir Android uygulamasından ekipmanınızda medya oynatabilirsiniz.
Bu kılavuzda, alıcı cihaz için medya yönlendirmesi sağlayıcısının nasıl oluşturulacağı ve bu sağlayıcının Android'de
çalışan diğer medya oynatma uygulamalarının kullanımına nasıl sunulacağı anlatılmaktadır. Bu API'yi kullanmak için MediaRouteProvider
, MediaRouteProviderDescriptor
ve RouteController
anahtar sınıfları hakkında bilgi sahibi olmanız gerekir.
Genel bakış
Android medya yönlendiricisi çerçevesi, medya uygulaması geliştiricilerinin ve medya oynatma cihazı üreticilerinin ortak bir API ve ortak bir kullanıcı arayüzü üzerinden bağlantı kurmasını sağlar. Bir MediaRouter
arayüzü uygulayan uygulama geliştiriciler daha sonra çerçeveye bağlanabilir ve medya yönlendiricisi çerçevesine katılan cihazlarda içerik oynatabilir. Medya oynatma cihazının üreticileri, diğer uygulamaların alıcı cihazlara bağlanmasına ve medyaları oynatmasına izin veren bir MediaRouteProvider
yayınlayarak bu çerçeveye katılabilir. Şekil 1'de bir uygulamanın medya yönlendiricisi çerçevesi üzerinden bir alıcı cihaza nasıl bağlandığı gösterilmektedir.
![](https://developer.android.com/static/images/mediarouter/media-route-provider-framework.png?authuser=5&hl=tr)
Şekil 1. Medya yönlendirme sağlayıcısı sınıflarının, bir medya uygulamasından alıcı cihaza nasıl iletişim sağladığına genel bakış.
Alıcı cihazınız için bir medya rotası sağlayıcı oluşturduğunuzda, sağlayıcı aşağıdaki amaçlara hizmet eder:
- Diğer uygulamaların keşfedebilmesi ve oynatma özelliklerini kullanabilmesi için alıcı cihazın özelliklerini açıklayıp yayınlayın.
- Alıcı cihazın programlama arayüzünü ve iletişim aktarım mekanizmalarını paketleyerek cihazı medya yönlendiricisi çerçevesiyle uyumlu hale getirin.
Rota sağlayıcılarının dağılımı
Medya rotası sağlayıcısı, bir Android uygulamasının parçası olarak dağıtılır. Rota sağlayıcınız, MediaRouteProviderService
hizmetinin kapsamını genişleterek veya MediaRouteProvider
uygulamanızı kendi hizmetinize dahil ederek ve medya rotası sağlayıcı için intent filtresi bildirerek diğer uygulamaların kullanımına sunulabilir. Bu adımlar, diğer uygulamaların medya yönlendirmenizi keşfetmesine ve kullanmasına olanak tanır.
Not: Medya yönlendirme sağlayıcısını içeren uygulama, rota sağlayıcıya bir MediaRouter arayüzü de içerebilir, ancak bu gerekli değildir.
MediaRouter destek kitaplığı
Medya yönlendirici API'leri AndroidX MediaRouter kitaplığında tanımlanmıştır. Bu kitaplığı uygulama geliştirme projenize eklemeniz gerekir. Projenize destek kitaplıkları ekleme hakkında daha fazla bilgi edinmek için Destek Kitaplığı Kurulumu sayfasını inceleyin.
Dikkat: Medya yönlendiricisi çerçevesinin AndroidX
uygulamasını kullandığınızdan emin olun.
Eski android.media
paketini kullanmayın.
Sağlayıcı Hizmeti oluşturma
Medya yönlendiricisi çerçevesi, diğer uygulamaların rotanızı kullanmasına izin vermek için medya rotası sağlayıcınızı keşfedebilmeli ve ona bağlanabilmelidir. Medya yönlendiricisi çerçevesi bunu yapmak için medya yönlendirme sağlayıcısı intent işlemi tanımlayan uygulamaları arar. Başka bir uygulama sağlayıcınıza bağlanmak istediğinde çerçevenin onu çağırabilmesi ve ona bağlanabilmesi gerekir. Böylece sağlayıcınız bir Service
içine alınmalıdır.
Aşağıdaki örnek kod, bir manifest içindeki medya rotası sağlayıcı hizmetinin beyanını ve medya yönlendiricisi çerçevesi tarafından keşfedilip kullanılmasına izin veren intent filtresini göstermektedir:
<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ği gerçek medya rotası sağlayıcı sınıflarını sarmalayan bir hizmeti tanımlar.
Android medya yönlendiricisi çerçevesi, medya yönlendirmesi sağlayıcıları için hizmet sarmalayıcı olarak kullanılmak üzere MediaRouteProviderService
sınıfını sağlar. Aşağıdaki örnek kod, bu sarmalayıcı sınıfının nasıl kullanılacağını gösterir:
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, uygulamanızın manifest beyanları aracılığıyla medya rotanızı keşfedebilir ancak sağladığınız medya rotalarının özelliklerini de bilmelidir. Medya rotaları farklı türlerde olabilir ve farklı özelliklere sahip olabilir. Diğer uygulamaların, rotanızla uyumlu olup olmadıklarını belirlemek için bu ayrıntıları keşfedebilmesi gerekir.
Medya yönlendiricisi çerçevesi, medya rotanızın özelliklerini IntentFilter
nesneleri, MediaRouteDescriptor
nesneleri ve MediaRouteProviderDescriptor
aracılığıyla tanımlayıp yayınlamanıza olanak tanır. Bu bölümde, diğer uygulamalar için medya yönlendirmenizin ayrıntılarını yayınlamak amacıyla bu sınıfları nasıl kullanacağınız açıklanmaktadır.
Rota kategorileri
Medya yönlendirme sağlayıcınızın programatik açıklamasının bir parçası olarak, sağlayıcınızın uzaktan oynatmayı mı, ikincil çıkışı mı yoksa ikisini birden mi desteklediğini belirtmeniz gerekir. Bunlar, medya yönlendiricisi çerçevesi tarafından sağlanan rota kategorileridir:
CATEGORY_LIVE_AUDIO
— Kablosuz özellikli müzik sistemi gibi ikincil bir çıkış cihazına ses çıkışı.CATEGORY_LIVE_VIDEO
— Kablosuz Ekran cihazları gibi ikincil bir çıkış cihazına video çıkışı.CATEGORY_REMOTE_PLAYBACK
: Video veya ses içeriklerini Chromecast cihazlar gibi medya alma, kod çözme ve oynatma işlemlerini gerçekleştiren ayrı bir cihazda oynatın.
Bu ayarları medya rotanızın açıklamasına eklemek için IntentFilter
nesnesine eklersiniz. Daha sonra bu nesneleri MediaRouteDescriptor
nesnesine eklersiniz:
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 medya yönlendirme sağlayıcınız tarafından desteklenen medya türlerini ve oynatma kontrollerini de tanımlamanız gerekir. Sonraki bölümde, cihazınız için bu ayarları nasıl belirteceğiniz açıklanmaktadır.
Medya türleri ve protokoller
Uzaktan oynatma cihazının medya yönlendirmesi sağlayıcısı, desteklediği medya türlerini ve aktarım protokollerini belirtmelidir. Bu ayarları, söz konusu nesnenin IntentFilter
sınıfını ve addDataScheme()
ile addDataType()
yöntemlerini kullanarak belirtirsiniz. Aşağıdaki kod snippet'inde http, https ve Gerçek Zamanlı Akış Protokolü (RTSP) kullanarak uzaktan video oynatmayı desteklemek üzere nasıl niyet filtresi tanımlanacağı gösterilmektedir:
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 denetimleri
Uzaktan oynatma sunan medya yönlendirmesi sağlayıcısı, desteklediği medya denetimi türlerini belirtmelidir. Medya yollarının sağlayabileceği genel denetim türleri şunlardır:
- Oynatma, duraklatma, geri sarma ve ileri sarma gibi oynatma kontrolleri.
- Sıra özellikleri: Gönderen uygulamanın, alıcı cihaz tarafından korunan bir oynatma listesine öğe ekleyip kaldırmasına olanak tanır.
- Alıcı cihazın, istekte bulunan uygulamaya bir oturum kimliği sağlamasını ve ardından sonraki her oynatma kontrolü isteğinde bu kimliği kontrol etmesini sağlayarak uygulamaların gönderilmesinin birbirlerine müdahale etmesini engelleyen oturum özellikleri.
Aşağıdaki kod örneğinde, temel medya rotası oynatma kontrollerini desteklemek için intent filtresinin nasıl oluşturulacağı gösterilmektedir:
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ılabilir oynatma kontrolü amaçları hakkında daha fazla bilgi için MediaControlIntent
sınıfına bakın.
MediaRouteProviderAçıklayıcı
IntentFilter
nesnelerini kullanarak medya rotanızın özelliklerini tanımladıktan sonra, Android medya yönlendiricisi çerçevesine yayınlamak için bir tanımlayıcı nesne oluşturabilirsiniz. Bu açıklayıcı nesne, diğer uygulamaların medya rotanızla nasıl etkileşimde bulunacağını belirleyebilmesi için medya rotanızın özelliklerinin özelliklerini içerir.
Aşağıdaki örnek kod, önceden oluşturulan intent filtrelerinin bir MediaRouteProviderDescriptor
öğesine nasıl ekleneceğini ve açıklayıcının medya yönlendirici çerçevesi tarafından kullanılmak üzere nasıl ayarlanacağını gösterir:
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); }
Kullanılabilir açıklayıcı ayarları hakkında daha fazla bilgi için MediaRouteDescriptor
ve MediaRouteProviderDescriptor
referans belgelerine bakın.
Rotaları Denetleme
Bir uygulama medya yönlendirme sağlayıcınıza bağlandığında sağlayıcı, diğer uygulamalar tarafından rotanıza gönderilen medya
yönlendiricisi çerçevesi üzerinden oynatma komutlarını alır. Bu istekleri ele almak için, komutları işleyen ve alıcı cihazınızla gerçek iletişimi gerçekleştiren bir MediaRouteProvider.RouteController
sınıfı uygulaması sağlamanız gerekir.
Medya yönlendiricisi çerçevesi, bu sınıfın bir örneğini almak için rota sağlayıcınızın onCreateRouteController()
yöntemini çağırır ve ardından istekleri buna yönlendirir.
Medya yönlendirmesi sağlayıcınız için uygulamanız gereken MediaRouteProvider.RouteController
sınıfının temel yöntemleri şunlardır:
onSelect()
— Bir uygulama, oynatma için rotanızı seçtiğinde çağrılır. Bu yöntemi, medya oynatma başlamadan önce gerekli olabilecek hazırlık işlerini yapmak için kullanırsınız.onControlRequest()
: Belirli oynatma komutlarını alıcı cihaza gönderir.onSetVolume()
: Alıcı cihaza, oynatma ses düzeyini belirli bir değere ayarlama isteği gönderir.onUpdateVolume()
: Alıcı cihaza, oynatma ses düzeyini belirtilen miktarda değiştirme isteği gönderir.onUnselect()
: Bir uygulama, rotanın seçimini kaldırdığında çağrılır.onRelease()
— Çerçevenin rotaya artık ihtiyaç duymadığı durumlarda çağrılır ve böylece kaynakları serbest bırakabilir.
Ses seviyesi değişiklikleri hariç tüm oynatma kontrolü istekleri onControlRequest()
yöntemine yönlendirilir. Bu yöntemi kullanımınız, kontrol isteklerini ayrıştırmalı ve bunlara uygun şekilde yanıt vermelidir. Aşağıda, uzaktan oynatma medya yönlendirmesi komutlarını işleyen bu yöntemin
örneği verilmiştir:
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, medya oynatma ekipmanınıza API için sarmalayıcı olarak işlev göreceğini anlamanız önemlidir. Bu sınıftaki yöntemlerin uygulanması,
tamamen alıcı cihazınız tarafından sağlanan programatik arayüze bağlıdır.
Örnek Kod
MediaRouter örneği, özel bir medya yönlendirmesi sağlayıcısının nasıl oluşturulacağını gösterir.