toro icon indicating copy to clipboard operation
toro copied to clipboard

Mute / Unmute Audio

Open ksi3321 opened this issue 6 years ago • 5 comments

Hi eneim Thanks for your wonderful library. I am currently using version 3.4.2

I have declared these on my app gradle

implementation "im.ene.toro3:toro:3.4.2"
implementation "im.ene.toro3:toro-ext-exoplayer:3.4.2"

I am able to play videos on the recyclerview which works fine. But I have been trying another requirement which is to mute the audio of the video view. I tried doing the following:

if (!ImageviewModel.mute.get()) {
                ImageviewModel.mute.set(false);
                helper.getVolumeInfo().setVolume(1.0f);
} else {
                ImageviewModel.mute.set(true);
                helper.getVolumeInfo().setVolume(0.0f);
}

and also this:

if (!ImageviewModel.mute.get()) {
                ImageviewModel.mute.set(false);
                helper.getVolumeInfo().setMute(false);
} else {
                ImageviewModel.mute.set(true);
                 helper.getVolumeInfo().setMute(true); 
}

I see that the audio is still heard and is not muted. Can you tell me why this is happening? I would like play videos by muting or unmuting the audio. Here is my adapter code:

public class RecyclerViewItemAdapter extends RecyclerView.Adapter<BaseViewHolder> {
   public static final int VIEW_STORY_HEADER = 0;
   public static final int VIEW_IMAGE_ITEM = 1;

    private List<ImageItem> mItemsList;
    private List<Integer> sampleBanners = new ArrayList<>();

    HeaderItemAdapter mAdapter;

    public void setHeaderItemAdapter(HeaderItemAdapter mAdapter) {
        this.mAdapter = mAdapter;
    }

    LinearLayoutManager mLayoutManager;

    FragmentManager manager;

    int[] sampleImages = {R.drawable.image1,
                          R.drawable.image2,
                          R.drawable.image3};

    Context context;

    public void setContext(Context context, FragmentManager manager) {
        this.context = context;
        this.manager = manager;
    }


    public RecyclerViewItemAdapter(List<ImageItem> mItemsList) {
        this.mItemsList = mItemsList;

        this.mLayoutManager = new LinearLayoutManager(context);
    }

    @NonNull
    @Override
    public BaseViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
               ItemImageBinding ItemImageBinding =
                       ItemImageBinding.inflate(LayoutInflater.from(parent.getContext()),
                                parent, false);

                return newItemViewHolderr(itemImageItemImageBinding);
    }

    @Override
    public void onBindViewHolder(@NonNull BaseViewHolder holder, int position) {
        holder.onBind(position);
    }



    @Override
    public int getItemCount() {
        if (mItemsList != null && mItemsList.size() > 0) {
            return mItemsList.size();
        } else {
            return 0;
        }
    }

    public void clearAll() {
        mItemsList.clear();
    }


    public void addItems(List<ImageItem> feedsList) {
        mItemsList.addAll(feedsList);
        notifyDataSetChanged();
    }


    public class ItemViewHolder extends BaseViewHolder
            implements ImageviewModel.ImageItemItemListener, ImageListener,ToroPlayer {

        final ItemImageBinding mBinding;

        ImageviewModel ImageviewModel;
        @Nullable
        ExoPlayerViewHelper helper;
        @Nullable private Uri mediaUri;


    private Playable.EventListener listener = new Playable.EventListener(){


    @Override
    public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {

    }

    @Override
    public void onRenderedFirstFrame() {

        helper.pause();
      
    }

    @Override
    public void onCues(List<Cue> cues) {

    }

    @Override
    public void onMetadata(Metadata metadata) {

    }

    @Override
    public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {

    }

    @Override
    public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {

    }

    @Override
    public void onLoadingChanged(boolean isLoading) {

    }

    @Override
    public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {

    }

    @Override
    public void onRepeatModeChanged(int repeatMode) {

    }

    @Override
    public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {

    }

    @Override
    public void onPlayerError(ExoPlaybackException error) {

    }

    @Override
    public void onPositionDiscontinuity(int reason) {

    }

    @Override
    public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {

    }

    @Override
    public void onSeekProcessed() {

    }

};

        public ItemViewHolder(ItemImageItemImageBinding mBinding) {
            super(mBinding.getRoot());
            this.mBinding = mBinding;

        }

        @Override
        public void onBind(int position) {

            final ImageItem feed = mItemsList.get(position);

            ImageviewModel = new ImageviewModel(feed, this);

            mBinding.setViewModel(ImageviewModel);

        
                mediaUri = Uri.parse("my url");
                mBinding.executePendingBindings();

        }

        @Override
        public void onVideoPlayClicked()
        {


            if(helper.isPlaying())
            {
                helper.pause();
            }
            else
            {
                helper.play();

            }
            ImageviewModel.play.set(helper.isPlaying());
        }

        @Override
        public void onMuteClicked()
        {
            if(!ImageviewModel.mute.get())
            {
                ImageviewModel.mute.set(false);
                helper.getVolumeInfo().setVolume(1.0f);
            }
            else
            {
                ImageviewModel.mute.set(true);
                helper.getVolumeInfo().setVolume(0.0f);

            }
        }

        @NonNull
        @Override
        public View getPlayerView() {
            return  mBinding.fbVideoPlayer;
        }

        @NonNull
        @Override
        public PlaybackInfo getCurrentPlaybackInfo() {
            return helper != null ? helper.getLatestPlaybackInfo() : new PlaybackInfo();
        }

        @Override
        public void initialize(@NonNull Container container, @Nullable PlaybackInfo playbackInfo) {

            if (mediaUri == null) throw new IllegalStateException("mediaUri is null.");
            if (helper == null) {
                helper = new ExoPlayerViewHelper(this, mediaUri);
                helper.addEventListener(listener);
            }
            helper.initialize(container, playbackInfo);
            helper.getVolumeInfo().setMute(false);
        }

        @Override public void play() {
            if (helper != null) helper.play();
        }

        @Override public void pause() {
            if (helper != null) helper.pause();
        }

        @Override public boolean isPlaying() {
            return helper != null && helper.isPlaying();
        }

        @Override public void release() {
            if (helper != null) {
                helper.removeEventListener(listener);
                helper.release();
                helper = null;
            }
        }

        @Override
        public boolean wantsToPlay() {
            return ToroUtil.visibleAreaOffset(this, itemView.getParent()) >= 0.85;
        }

        @Override
        public int getPlayerOrder() {
            return getAdapterPosition();
        }

        @Override
        public void onSettled(Container container) {

        }

    }

}

ksi3321 avatar Apr 27 '18 08:04 ksi3321

@maximus9600 Thanks for using Toro. I understand the requirement around setting volume. Next version will comes with demo and guideline as well. At the mean time, I will double check your question later and give some advice, please stay tune.

eneim avatar Apr 27 '18 12:04 eneim

Thank you for your reply @eneim . Since i had to figure out soon due to lack of time , i implemented my requirement in the following way:

@Override public void onMuteClicked() { if(!ImageViewModel.mute.get()) { ImageViewModel.mute.set(false); helper.setVolumeInfo(new VolumeInfo(false, 1.0f); } else { ImageViewModel.mute.set(true); helper.setVolumeInfo(new VolumeInfo(true, 0.0f); } }

ksi3321 avatar Apr 27 '18 12:04 ksi3321

@maximus9600 Got the situation. This link is how I implement to include volume update for mopub extension (mopub uses an older version of ExoPlayer, therefore requires a separated extension).

Long story short: this work requires to have PlayerView and ControllerView to be updated as well. But the core idea is as below:

[1] Allow your user to change the Volume from UI (click button to mute/un-mute, and drag the seekbar to change volume).

[2] In your listener, other than update the UI to match the Volume condition, you should update the PlaybackInfo's volume info by using OnVolumeChangeListener. By default, PlaybackInfo doesn't have anything about volume, so you need to extend it to include VolumeInfo value (see my demo above, and related classes as well). Also, VolumeAwareHelper shows you how to use the helper with OnVolumeChangeListener to get volume update.

[3] Deal with save/restore the PlaybackInfo on config change or ViewHolder detach/attach. The class VolumeAwareHelper and VideoViewHolder in demo above are how I'm doing it.

You can take a look and see if it can help you. In sort: extend PlaybackInfo to VolumeAwarePlaybackInfo (see source code), implement VolumeAwareHelper and register OnVolumeChangeListener (see source code), implement your ViewHolder's ToroPlayer to use the VolumeInfo. This should not be too complicated, but still, and can be less painful in near future :D.

eneim avatar Apr 29 '18 02:04 eneim

Wow. Let me try this. thanks @eneim :)

ksi3321 avatar Apr 29 '18 03:04 ksi3321

Guys, I did it in the below way and its working:

if (videoHolder.helper != null) {
     if (videoHolder.helper.getVolume() == 0) {
           videoHolder.helper.setVolume(1);
     } else {
          videoHolder.helper.setVolume(0);
     }
}

ritesh94 avatar Apr 30 '18 05:04 ritesh94