Как добавить пользовательский SessionProvider с помощью Google Cast SDK 3
Недавно мы обновили Google Cast SDK до версии 3. С помощью этого SDK должна быть возможность добавить поддержку устройств, не являющихся приведенными, путем реализации getAdditionalSessionProviders() в OptionsProvider. Мы создали пользовательский SessionProvider для возврата методом getAdditionalSessionProviders().
Однако этот SessionProvider никогда не используется, и, вероятно, он будет использоваться только тогда, когда устройство было обнаружено и выбрано в списке выбора, когда нажата кнопка MediaRouteButton, как описано в документации по сеансу. Но мы не можем найти способ добавить наше обнаруженное не приведенное устройство в этот список. Мы искали API, документацию и примеры, доступные в Интернете, но не смогли найти, как это сделать. Мы нашли только примеры старых версий SDK, но они абсолютно разные и не могут быть использованы.
Мы хотели бы использовать эту функцию для добавления телевизоров Samsung в список Google Cast с помощью Samsung SmartView SDK, как это делают приложения YouTube и Netflix.
3 ответа
Создайте пользовательский провайдер медиа-маршрутов. Вот фиктивный Media RouteProvider для пользовательского медиа-маршрута. Этот класс не делает ничего, кроме публикации поддельного пользовательского Media Route, чтобы его можно было увидеть и выбрать с помощью Cast SDK из MediaRouter.
import android.content.Context;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.os.Bundle;
import android.support.v7.media.MediaRouteDescriptor;
import android.support.v7.media.MediaRouteDiscoveryRequest;
import android.support.v7.media.MediaRouteProvider;
import android.support.v7.media.MediaRouteProvider.RouteController;
import android.support.v7.media.MediaRouteProviderDescriptor;
import android.support.v7.media.MediaRouter;
import java.util.ArrayList;
public final class CustomMediaRouteProvider extends MediaRouteProvider {
private static final ArrayList<IntentFilter> CONTROL_FILTERS_BASIC;
private static MediaRouteDescriptor DEFAULT_MEDIA_ROUTE_DESCRIPTOR;
static {
// This filter will be used by Cast SDK to match the session category.
IntentFilter customControls = new IntentFilter();
customControls.addCategory(CustomSessionProvider.CUSTOM_CATEGORY);
CONTROL_FILTERS_BASIC = new ArrayList<IntentFilter>();
CONTROL_FILTERS_BASIC.add(customControls);
Bundle extras = new Bundle();
extras.putCharSequence("ROUTE_URL", "http://abcdef.cyz");
DEFAULT_MEDIA_ROUTE_DESCRIPTOR =
new MediaRouteDescriptor.Builder("fake-custom-route-id", "fake custom route")
.setDescription("Foo description")
.addControlFilters(CONTROL_FILTERS_BASIC)
.setPlaybackStream(AudioManager.STREAM_MUSIC)
.setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE)
.setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE)
.setVolumeMax(100)
.setVolume(10)
.setExtras(extras)
.build();
}
public CustomMediaRouteProvider(Context context) {
super(context);
}
@Override
public void onDiscoveryRequestChanged(MediaRouteDiscoveryRequest request) {
if (request == null || request.getSelector() == null) {
return;
}
publishRoutes();
}
@Override
public RouteController onCreateRouteController(String routeId) {
return null;
}
private void publishRoutes() {
MediaRouteProviderDescriptor providerDescriptor =
new MediaRouteProviderDescriptor.Builder().addRoute(DEFAULT_MEDIA_ROUTE_DESCRIPTOR).build();
setDescriptor(providerDescriptor);
}
}
Вам нужна реализация SessionProvider для вашей пользовательской сессии:
import android.content.Context;
import com.google.android.gms.cast.framework.Session;
import com.google.android.gms.cast.framework.SessionProvider;
public class CustomSessionProvider extends SessionProvider {
public static final String CUSTOM_CATEGORY = "CUSTOM";
public CustomSessionProvider(Context applicationContext) {
super(applicationContext, CUSTOM_CATEGORY);
}
@Override
public Session createSession(String sessionId) {
return new CustomSession(getContext(), getCategory(), sessionId);
}
@Override
public boolean isSessionRecoverable() {
return true;
}
}
И реализация Session: вот фиктивная реализация Session для пользовательского типа медиа-маршрута. Это всегда успешно на начало / возобновление / конец.
import android.content.Context;
import android.os.Bundle;
import com.google.android.gms.cast.framework.Session;
public class CustomSession extends Session {
private static final String FAKE_SESSION_ID = "custom.session.id.12345";
CustomSession(Context applicationContext, String category, String sessionId) {
super(applicationContext, category, sessionId);
}
@Override
protected void start(Bundle routeInfoExtra) {
notifySessionStarted(FAKE_SESSION_ID);
}
@Override
protected void resume(Bundle routeInfoExtra) {
notifySessionResumed(false);
}
@Override
protected void end(boolean stopCasting) {
notifySessionEnded(0);
}
}
В приложении отправителя Cast V3 укажите дополнительного поставщика сеанса:
public class CastOptionsProvider implements OptionsProvider {
@Override
public List<SessionProvider> getAdditionalSessionProviders(Context appContext) {
List<SessionProvider> additionalProviders = new ArrayList<>();
additionalProviders.add(new CustomSessionProvider(appContext));
return additionalProviders;
}
}
В вашем приложении добавьте провайдера Media Router:
public class CastVideosApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
MediaRouter mediaRouter = MediaRouter.getInstance(this);
mediaRouter.addProvider(new CustomMediaRouteProvider(this));
}
}
Это раздражает... Я все еще работаю над решением - но я только что нашел несколько обучающих программ по Google Video по этому поводу: https://www.youtube.com/watch?v=_NGB10uN6OI
Итак, у меня была та же проблема, что и у вас, и я нашел какой-то способ заставить ее работать, но, как вы заметили, поскольку по этому вопросу ничего не задокументировано, я не уверен, что это "правильный способ сделать это".
Вот в основном то, что я делаю:
- Создайте провайдера медиа-маршрутов (руководство разработчика здесь)
- Расширить Session и SessionProvider
- Реализуйте OptionsProvider и верните свой SessionProvider в методе getAdditionalSessionProviders.
Поставщик медиа-маршрута отвечает за управление вашим устройством и всеми связанными с ним командами / связью. Вы можете проверить это с очень простым приложением, используя Media Router API. В Media Router есть github из googlesample: Android BasicMediaRouter Sample.
В вашем пользовательском классе Session вы можете получить доступ к MediaRouter (вы получили контекст, переданный в конструктор) и получить текущий маршрут:
MediaRouter mediaRouter = MediaRouter.getInstance(context);
if (mediaRouter != null && mediaRouter.getSelectedRoute() != null)
Log.d("Cast", "Selected route name is " + mediaRouter.getSelectedRoute().getName());
При этом вы сможете получить ваше устройство, если оно выбрано в настоящий момент (вы будете уведомлены в методе start() Session), и передавать команды от объекта Session вашему провайдеру медиа-маршрутов, как это сделано в образец медиа-маршрута.