androidexoplayerexoplayer2.xandroid-music-player

Volume control for Casting with CastPlayer and custom notification


I want to use my own notification for casting in Player Service. I use:

public class CastOptionsProvider implements OptionsProvider {

    @Override
    public CastOptions getCastOptions(Context context) {

        CastMediaOptions mediaOptions = new CastMediaOptions.Builder().setNotificationOptions(null).build();
        return new CastOptions.Builder().setReceiverApplicationId(context.getString(R.string.app_id)).setCastMediaOptions(mediaOptions).build();
    }

    @Override
    public List<SessionProvider> getAdditionalSessionProviders(Context context) {
        return null;
    }
}

But with that code I lose ability to control Chromecast volume with physical buttons. With default options I have 2 notifications (one from foreground service and one from OptionsProvider). Do you have any solutions?


Solution

  • I have solved this with:

    player.setOnCastAvailabilityChangeListener(isAvailable -> {
        if(isAvailable){
            final int MAX_VOLUME = 20; //Steps of volume
    
            CastContext castContext = CastContext.getSharedInstance(URLPlayerService.this);
            SessionManager sessionManager = castContext.getSessionManager();
            CastSession castSession = sessionManager.getCurrentCastSession();
    
            if (castSession != null) {
                int initialVolume = (int) (castSession.getVolume() * MAX_VOLUME);
    
                mediaSessionCompat.setPlaybackToRemote(new VolumeProviderCompat(
                        VOLUME_CONTROL_RELATIVE, MAX_VOLUME, initialVolume) {
    
                    @Override
                    public void onAdjustVolume(int direction) {
                        super.onAdjustVolume(direction);
    
                        if (castSession.isConnected()) {
                            int currentVolume = getCurrentVolume();
                            int newVolume = Math.max(0, Math.min(currentVolume + direction, MAX_VOLUME)); // Clamp within range
    
                            try {
                                castSession.setVolume((double) newVolume / MAX_VOLUME);
                                setCurrentVolume(newVolume);
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
    
                            Timber.tag("Cast").d("Volume changed from %s to %s (Max: %s)", currentVolume, newVolume, MAX_VOLUME);
                        } else {
                            Timber.tag("Cast").e("No active Cast session");
                        }
                    }
                });
            }
        }
    });