toro
toro copied to clipboard
Mute / Unmute Audio
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) {
}
}
}
@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.
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); } }
@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.
Wow. Let me try this. thanks @eneim :)
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);
}
}