2016-07-08 3 views
1

Je travaille sur une application qui contrôle le Chromecast et tout ce qui y joue.Android: permet de lire les contenus multimédias en cours sur Chromecast?

Je ne veux pas une application d'expéditeur, je ne veux rien enregistrer pour obtenir une clé d'api, rien de tout cela. J'utilise jusqu'à présent MediaRouter pour contrôler le volume et voir s'il est connecté à quoi que ce soit.

Mais je veux quelque chose comme l'application Google Cast:

Google Cast android

qui sait ce qui se joue et (ou tout au moins) l'état de lecture.

Idéalement, je ne voudrais pas utiliser les services google play, mais si c'est le seul moyen, c'est la vie.

Répondre

3

J'ai finalement compris. J'ai dû utiliser les services google play et google cast sdk v2 mais sans enregistrer l'application.

bibliothèques incluses dans le projet:

compile 'com.android.support:mediarouter-v7:24.0.0' 
compile 'com.google.android.gms:play-services-cast-framework:9.2.0' 

dans le Garde-toi du code ci-dessous onCreate() et OnDestroy() ne sont pas des méthodes dans une activité, Fragment ou service, alors ne pas copier/coller le code et attendez que cela fonctionne. Le code dans ces méthodes doit être copié/collé dans vos propres méthodes.

Voici les étapes de ce qui se passe:

  1. Vous sélectionnez un itinéraire soit via le bouton moulé soit en appelant getActiveMediaRoute() qui vérifie que Chromecast est actif (il ne fonctionnera pas si personne est connecté au Chromecast). Remplacer la méthode ou getActiveChromecastRoute() pour sélectionner en fonction de vos préférences
  2. Lorsque onRouteSelected() est appelée une nouvelle distribution GoogleApiClient est instancié avec des options pour le Chromecast sélectionné
  3. Lorsque onApplicationMetadataChanged() est appelé le code reliera au courant l'application en cours d'exécution sur le Chromecast
  4. après l'application est connectée avec succès une nouvelle RemoteMediaPlayer est instancié et l'mediaStatus est demandé
  5. vous devriez obtenir un rappel dans onStatusUpdated() et après que vous pouvez appeler mRemoteMediaPlayer.getMediaStatus() et il sera contient les données sur ce qui est lu sur le Chromecast.

public static final String CHROMECAST_SIGNATURE = "cast.media.CastMediaRouteProviderService"; 

private final MediaRouteSelector mSelector; 
private final MediaRouter mMediaRouter; 
private CastDevice mSelectedDevice; 
private Cast.Listener mCastClientListener; 
private RemoteMediaPlayer mRemoteMediaPlayer; 

@Override 
public void onCreate() { 
    mMediaRouter = MediaRouter.getInstance(context); 

    mSelector = new MediaRouteSelector.Builder() 
      // These are the framework-supported intents 
      .addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO) 
      .addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO) 
      .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK) 
      .build(); 

    mMediaRouter.addCallback(mSelector, mMediaRouterCallback, MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY | MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS); 
} 

@Override 
public void onDestroy() { 
    mMediaRouter.removeCallback(mMediaRouterCallback); 
} 

@UiThread 
private boolean isChromecastActive() { 
    return getActiveChromecastRoute() != null; 
} 

@UiThread 
private Boolean isChromecastPlaying() { 
    if (mRemoteMediaPlayer == null || mRemoteMediaPlayer.getMediaStatus() == null) { 
     return null; 
    } 

    // Here you can get the playback status and the metadata for what's playing 
    // But only after the onStatusUpdated() method is called in the mRemoteMediaPlayer callback 
    int state = mRemoteMediaPlayer.getMediaStatus().getPlayerState(); 
    return (state == MediaStatus.PLAYER_STATE_BUFFERING || state == MediaStatus.PLAYER_STATE_PLAYING); 
} 

@UiThread 
private MediaRouter.RouteInfo getActiveChromecastRoute() { 
    for (MediaRouter.RouteInfo route : mMediaRouter.getRoutes()) { 
     if (isCastDevice(route)) { 
      if (route.getConnectionState() == MediaRouter.RouteInfo.CONNECTION_STATE_CONNECTED) { 
       return route; 
      } 
     } 
    } 

    return null; 
} 

private int getMediaRouteVolume(@NonNull MediaRouter.RouteInfo route) { 
    return route.getVolume(); 
} 

private void setMediaRouteVolume(@NonNull MediaRouter.RouteInfo route, int volume) { 
    route.requestSetVolume(volume); 
} 

private int getMediaRouteMaxVolume(@NonNull MediaRouter.RouteInfo route) { 
    return route.getVolumeMax(); 
} 

@UiThread 
private MediaRouter.RouteInfo getActiveMediaRoute() { 
    if (isChromecastActive()) { 
     MediaRouter.RouteInfo route = getActiveChromecastRoute(); 

     if (route != null) { 
      if (!route.isSelected()) { 
       mMediaRouter.selectRoute(route); 
      } 
     } 
     else if (mSelectedDevice != null) { 
      mSelectedDevice = null; 
     } 

     return route; 
    } 

    return null; 
} 

private boolean isCastDevice(MediaRouter.RouteInfo routeInfo) { 
    return routeInfo.getId().contains(CHROMECAST_SIGNATURE); 
} 

private MediaRouter.Callback mMediaRouterCallback = new MediaRouter.Callback() { 
    @Override 
    public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo route) { 
     if (isCastDevice(route)) { 
      Log.i("MediaRouter", "Chromecast found: " + route); 
     } 
    } 

    @Override 
    public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo route) { 
     if (isCastDevice(route)) { 
      Log.i("MediaRouter", "Chromecast changed: " + route); 
     } 
    } 

    @Override 
    public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo route) { 
     if (mSelectedDevice == null && isCastDevice(route)) { 
      Log.i("MediaRouter", "Chromecast selected: " + route); 

      mSelectedDevice = CastDevice.getFromBundle(route.getExtras()); 
      mCastClientListener = new Cast.Listener() { 
       @Override 
       public void onApplicationStatusChanged() { 
        Log.i("MediaRouter", "Cast.Listener.onApplicationStatusChanged()"); 
       } 

       @Override 
       public void onApplicationMetadataChanged(ApplicationMetadata applicationMetadata) { 
        Log.i("MediaRouter", "Cast.Listener.onApplicationMetadataChanged(" + applicationMetadata + ")"); 

        if (applicationMetadata != null) { 
         LaunchOptions launchOptions = new LaunchOptions.Builder().setRelaunchIfRunning(false).build(); 
         Cast.CastApi.launchApplication(mApiClient, applicationMetadata.getApplicationId(), launchOptions).setResultCallback(new ResultCallback<Cast.ApplicationConnectionResult>() { 
          @Override 
          public void onResult(@NonNull Cast.ApplicationConnectionResult applicationConnectionResult) { 
           Log.i("MediaRouter", "Cast.CastApi.joinApplication.onResult() " + applicationConnectionResult.getSessionId()); 

           mRemoteMediaPlayer = new RemoteMediaPlayer(); 
           mRemoteMediaPlayer.setOnStatusUpdatedListener(new RemoteMediaPlayer.OnStatusUpdatedListener() { 
            @Override 
            public void onStatusUpdated() { 
             MediaStatus mediaStatus = mRemoteMediaPlayer.getMediaStatus(); 
             Log.i("MediaRouter", "Remote media player status " + mediaStatus.getPlayerState()); 
             // TODO: you can call isChromecastPlaying() now 
            } 
           }); 

           try { 
            Cast.CastApi.setMessageReceivedCallbacks(mApiClient, mRemoteMediaPlayer.getNamespace(), mRemoteMediaPlayer); 
           } catch(IOException e) { 
            Log.e("MediaRouter", "Exception while creating media channel ", e); 
           } catch(NullPointerException e) { 
            Log.e("MediaRouter", "Something wasn't reinitialized for reconnectChannels", e); 
           } 


           mRemoteMediaPlayer.requestStatus(mApiClient).setResultCallback(new ResultCallback<RemoteMediaPlayer.MediaChannelResult>() { 
            @Override 
            public void onResult(@NonNull RemoteMediaPlayer.MediaChannelResult mediaChannelResult) { 
             Log.i("MediaRouter", "requestStatus() " + mediaChannelResult); 
            } 
           }); 

           try { 
            Cast.CastApi.requestStatus(mApiClient); 
           } catch (IOException e) { 
            Log.e("MediaRouter", "Couldn't request status", e); 
           } 
          } 
         }); 
        } 
       } 

       @Override 
       public void onApplicationDisconnected(int i) { 
        Log.i("MediaRouter", "Cast.Listener.onApplicationDisconnected(" + i + ")"); 
       } 

       @Override 
       public void onActiveInputStateChanged(int i) { 
        Log.i("MediaRouter", "Cast.Listener.onActiveInputStateChanged(" + i + ")"); 
       } 

       @Override 
       public void onStandbyStateChanged(int i) { 
        Log.i("MediaRouter", "Cast.Listener.onStandbyStateChanged(" + i + ")"); 
       } 

       @Override 
       public void onVolumeChanged() { 
        Log.i("MediaRouter", "Cast.Listener.onVolumeChanged()"); 
       } 
      }; 

      Cast.CastOptions.Builder apiOptionsBuilder = new Cast.CastOptions.Builder(mSelectedDevice, mCastClientListener); 

      mApiClient = new GoogleApiClient.Builder(getContext()) 
        .addApi(Cast.API, apiOptionsBuilder.build()) 
        .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() { 
         @Override 
         public void onConnected(@Nullable Bundle bundle) { 
          Log.i("MediaRouter", "GoogleApiClient.onConnected()"); 
          Log.i("MediaRouter", "Bundle " + bundle); 
         } 

         @Override 
         public void onConnectionSuspended(int i) { 
          Log.i("MediaRouter", "GoogleApiClient.onConnectionSuspended(" + i + ")"); 
         } 
        }) 
        .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() { 
         @Override 
         public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { 
          Log.i("MediaRouter", "GoogleApiClient.onConnectionFailed()"); 
         } 
        }) 
        .build(); 

      mApiClient.connect(); 
     } 
     else { 
      mSelectedDevice = null; 
      mRemoteMediaPlayer = null; 
     } 
    } 

    @Override 
    public void onRouteRemoved(MediaRouter router, MediaRouter.RouteInfo route) { 
     if (isCastDevice(route)) { 
      if (mSelectedDevice != null && mSelectedDevice.isSameDevice(CastDevice.getFromBundle(route.getExtras()))) { 
       mSelectedDevice = null; 
      } 
      Log.i("MediaRouter", "Chromecast lost: " + route); 
     } 
    } 
}; 
+0

Ce code a été inspiré par https://www.binpress.com/tutorial/building-an-android-google-cast-sender-app/161 mais au lieu de lancer la vidéo I a dû appeler mRemoteMediaPlayer.requestStatus (mApiClient) – Auras