eneim / toro

Video list auto playback made simple, specially built for RecyclerView
Apache License 2.0
1.42k stars 253 forks source link

if the first item of recycler view photo then all others video not play #311

Open yateeshkota opened 6 years ago

yateeshkota commented 6 years ago

hi eneim, I am using toro library with streaming on Amazon API. I am facing an issue when my recycler view has the first item is a photo then other videos of recycler view are always paused but when the first item of recycler view is video it will be working good and also play and pause on scrolling. please help me.

my view holder

 public static class VideoPost extends ToroVideoViewHolder implements LastMomentCallback,View.OnClickListener {

        static final int LAYOUT_RES = R.layout.vh_fb_feed_post_video;
        ...

        public VideoPost(View itemView) {
            super(itemView);

            ...
            mVideoView.setLastMomentCallback(this);
            mInfo.setOnClickListener(this);
            icon_for_click.setOnClickListener(this);
            rel_11.getLayoutParams().height = width;
            mThumbnail.getLayoutParams().height = width;
            videoView.getLayoutParams().height = width;           
        }

        @Override
        protected ToroVideoView findVideoView(View itemView) {
            return (ToroVideoView) itemView.findViewById(R.id.video);
        }

        @Override
        public void setOnItemClickListener(View.OnClickListener listener) {
            super.setOnItemClickListener(listener);

        }

        public void setContructor(Context mContext) {
            this.mContext = mContext;
            DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
            width = displayMetrics.widthPixels;
        }

        @Override
        public void bind(RecyclerView.Adapter adapter, Object item) {

            if (!(item instanceof SimpleVideoObject)) {
                throw new IllegalStateException("Unexpected object: " + item.toString());
            }

            rel_11.getLayoutParams().height = width;
            mThumbnail.getLayoutParams().height = width;
            videoView.getLayoutParams().height = width;

            mItem = (SimpleVideoObject) item;

            Glide.with(mContext)
                    .load(mItem.getThumbnail())
                    .placeholder(R.drawable.ic_menu_gallery)
                    .error(R.drawable.ic_menu_gallery)
                    .fitCenter()
                    .diskCacheStrategy(DiskCacheStrategy.ALL)
                    .into(mThumbnail);
            mVideoView.setMedia(Uri.parse(mItem.getUrl()));

            txt_user_name.setText(mItem.getOwner_name());
            txt_time.setText(Utils.timeCalculation(mItem.getPost_ti

            txt_user_name.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (((HomeActivity) mContext).fragmentManager != null) {
                        OtherProfileFragment fragment = OtherProfileFragment.newInstance(String.valueOf(mItem.getOwner_id()));
                        ((HomeActivity) mContext).fragmentManager.beginTransaction()
                                .replace(R.id.main_frame,
                                        fragment,
                                        "OTHERPROFILEFRAGMENT")
                                .addToBackStack("OtherProfile_123")
                                .commit();
                    }
                }
            });
            usericon.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (((HomeActivity) mContext).fragmentManager != null) {
                        OtherProfileFragment fragment = OtherProfileFragment.newInstance(String.valueOf(mItem.getOwner_id()));
                        ((HomeActivity) mContext).fragmentManager.beginTransaction()
                                .replace(R.id.main_frame,
                                        fragment,
                                        "OTHERPROFILEFRAGMENT")
                                .addToBackStack("OtherProfile_123")
                                .commit();
                    }
                }
            });

            Utils.setTypeface(mContext, txt_user_name, Config.QUICKSAND, Config.BOLD);
            Utils.setTypeface(mContext, txt_description, Config.QUICKSAND, Config.BOLD);
            Utils.setTypeface(mContext, txt_comment, Config.QUICKSAND, Config.REGULAR);
            Utils.setTypeface(mContext, txt_num_comment, Config.QUICKSAND, Config.REGULAR);
            Utils.setTypeface(mContext, txt_loves, Config.QUICKSAND, Config.REGULAR);
            Utils.setTypeface(mContext, txt_num_loves, Config.QUICKSAND, Config.REGULAR);
            Utils.setTypeface(mContext, txt_time, Config.QUICKSAND, Config.REGULAR);
        }

        @Override
        public boolean wantsToPlay() {

            return   isPlayable && visibleAreaOffset() >= 0.85;
        }

        @Nullable
        @Override
        public String getMediaId() {
            return mItem.toString() + "@" + getAdapterPosition();
        }

        @Override
        public void onVideoPreparing() {
            super.onVideoPreparing();
            Log.d("inside", "onVideoPreparing");
            mInfo.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
            mInfo.setText("Preparing");

        }

        @Override
        public void onVideoPrepared(Cineer mp) {
            super.onVideoPrepared(mp);
            Log.d("inside", "onVideoPrepared");
            isPlayable = true;
            mInfo.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
            mInfo.setText("Buffering...");
            latestPosition = 0;
            mThumbnail.setVisibility(View.GONE);

            if (wantsToPlay()) {

                mVideoView.start();
                onPlaybackStarted();
            } else {
                Log.d("inside", "play  not");
            }

        }

        @Override
        public void onViewHolderBound() {
            super.onViewHolderBound();
            mInfo.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
            mInfo.setText("Bound");
        }

        @Override
        public void onPlaybackStarted() {

            mThumbnail.animate().alpha(0.f).setDuration(250).setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    VideoPost.super.onPlaybackStarted();
                }

            }).start();
            if (mInfo.getText().toString().equalsIgnoreCase("Started in volume Format")) {

                Drawable img = mContext.getResources().getDrawable(R.drawable.ic_volume_up_white_48dp);
                img.setBounds(0, 0, 35, 35);
                mInfo.setCompoundDrawables(img, null, null, null);
                mInfo.setText("Started in volume Format");
                mVideoView.setVolume(1);
                icon_use_int = 1;
                icon_for_click.setBackgroundResource(R.drawable.ic_volume_up_white_48dp);
            } else {
                mVideoView.setVolume(0);
                Drawable img = mContext.getResources().getDrawable(R.drawable.ic_volume_off_white_48dp);
                img.setBounds(0, 0, 35, 35);
                mInfo.setCompoundDrawables(img, null, null, null);
                mInfo.setText("Started in muted Format");
                icon_use_int = 0;
                icon_for_click.setBackgroundResource(R.drawable.ic_volume_off_white_48dp);
            }

        }

        @Override
        public void onPlaybackPaused() {

            mThumbnail.animate().alpha(1.f).setDuration(250).setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    VideoPost.super.onPlaybackPaused();
                }
            }).start();
            mInfo.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
            mInfo.setText("paused");
            icon_for_click.setBackgroundResource(R.drawable.ic_pause_circle_filled_white_48dp);
        }

        @Override
        public void onPlaybackCompleted() {
            isPlayable = false;
            mThumbnail.animate().alpha(1.f).setDuration(250).setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    VideoPost.super.onPlaybackCompleted();
                }
            }).start();
            mInfo.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
            mInfo.setText("complete");
            icon_for_click.setBackgroundResource(R.drawable.stop_2);
        }

        @Override
        public boolean onPlaybackError(Cineer mp, PlaybackException error) {
            isPlayable = false;
            mThumbnail.animate().alpha(1.f).setDuration(250).setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    VideoPost.super.onPlaybackCompleted();
                }
            }).start();
            mInfo.setText("Error: videoId = " + getMediaId());
            return super.onPlaybackError(mp, error);
        }

        @Override
        public boolean isLoopAble() {
            return true;
        }

        @Override
        public String toString() {
            return "Video: " + getMediaId();
        }

        @Override
        public long getCurrentPosition() {
            if (!isReleased) {
                latestPosition = super.getCurrentPosition();
            }
            return latestPosition;
        }

        @Override
        public void onLastMoment(Cineer player) {
            isReleased = true;
            latestPosition = player.getCurrentPosition();
        }

        @Override
        protected boolean allowLongPressSupport() {
            return true;
        }

        public void stop_volume() {
            mInfo.setText("Started in muted Format");
            mVideoView.setVolume(0);
            icon_for_click.setBackgroundResource(R.drawable.ic_volume_off_white_48dp);
        }

        @Override
        public void onClick(View v) {

            if (mInfo.getText().toString().equalsIgnoreCase("Paused")) {
                mVideoView.start();
                onPlaybackStarted();
            }

            else if (mInfo.getText().toString().equalsIgnoreCase("Started in muted Format")) {         

                Drawable img = mContext.getResources().getDrawable(R.drawable.ic_volume_up_white_48dp);
                img.setBounds(0, 0, 35, 35);
                mVideoView.setVolume(1);
                mInfo.setCompoundDrawables(img, null, null, null);
                mInfo.setText("Started in volume Format");
                icon_use_int = 1;
                icon_for_click.setBackgroundResource(R.drawable.ic_volume_up_white_48dp);
            } else if (mInfo.getText().toString().equalsIgnoreCase("Started in volume Format")) {        
                Drawable img = mContext.getResources().getDrawable(R.drawable.ic_volume_off_white_48dp);
                img.setBounds(0, 0, 35, 35);
                mVideoView.setVolume(0);
                mInfo.setCompoundDrawables(img, null, null, null);
                mInfo.setText("Started in muted Format");
                icon_use_int = 0;
                icon_for_click.setBackgroundResource(R.drawable.ic_volume_off_white_48dp);
            }
        }

    }   `

my fragment

`

    public class FeedFragment extends BaseFragment {

    private OnItemClickListener listener = new OnItemClickListener() {
        @Override
        public void onItemClick(RecyclerView.Adapter adapter, RecyclerView.ViewHolder viewHolder,
                                View view, int adapterPosition, long itemId) {
            SimpleVideoObject initItem = null;
            long initPosition = 0;
            long initDuration = 0;
            final ToroPlayer player;
            if (adapter instanceof GeneralFeedAdapter) {
                player = ((GeneralFeedAdapter) adapter).getPlayer();
                initItem = (SimpleVideoObject) ((GeneralFeedAdapter) adapter).getItem(adapterPosition);
                if (player != null) {
                    initPosition = player.getCurrentPosition();
                    initDuration = player.getDuration();
                }
            }

            if (initItem != null) {
                Bundle extras = new Bundle();
                extras.putLong(FbPLayerDialogFragment.ARGS_INIT_DURATION, initDuration);
                extras.putLong(FbPLayerDialogFragment.ARGS_INIT_POSITION, initPosition);
                extras.putParcelable(FbPLayerDialogFragment.ARGS_INIT_VIDEO, initItem);

                FbPLayerDialogFragment playlist =
                        FbPLayerDialogFragment.newInstance(initItem, initPosition, initDuration);
                playlist.setTargetFragment(GeneralFeedFragment.this, RESUME_REQUEST_CODE);
                playlist.show(getChildFragmentManager(), FbPLayerDialogFragment.TAG);
            }
        }
    };

    public static GeneralFeedFragment newInstance() {
        return new GeneralFeedFragment();
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        final ToroStrategy oldStrategy = Toro.getStrategy();
        Toro.setStrategy(new ToroStrategy() {
            boolean isFirstPlayerDone = false;
            @Override
            public String getDescription() {
                return "First video plays first";
            }
            @Override
            public ToroPlayer findBestPlayer(List<ToroPlayer> candidates) {
                return oldStrategy.findBestPlayer(candidates);
            }

            @Override
            public boolean allowsToPlay(ToroPlayer player, ViewParent parent) {
                boolean allowToPlay = (isFirstPlayerDone || player.getPlayOrder() == firstVideoPosition)  //
                        && oldStrategy.allowsToPlay(player, parent);
                // A work-around to keep track of first video on top.
                if (player.getPlayOrder() == firstVideoPosition) {
                    isFirstPlayerDone = true;
                }
                return allowToPlay;
            }
        });
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mactivity = getActivity();
        DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
        width = displayMetrics.widthPixels;

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.generic_recycler_view, container, false);

        return view;
    }

    @Override
    public void onClick(View v) {
        super.onClick(v);
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    @Override
    public void onViewCreated(final View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
       ...
        mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
        linearLayoutManager = new LinearLayoutManager(getActivity());
        mRecyclerView.setLayoutManager(linearLayoutManager);
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());
        mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));
        mRecyclerView.setHasFixedSize(false);

        if (Utils.isNetworkConnected(getContext(), true)) {
            callServiceForGeneralFeed(..);
        }
      ...
    }

    public void callServiceForFeed(..) {

       ....
    }

    @Override
    public void onResume() {
        Toro.register(mRecyclerView);
        super.onResume();
    }

    @Override
    public void onPause() {
        Toro.unregister(mRecyclerView);
        super.onPause();

    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == RESUME_REQUEST_CODE) {
            Toro.rest(true);
            VideoPlayerManager manager = ((VideoPlayerManager) mAdapter);
            if (manager.getPlayer() != null) {
                long latestPosition = data.getLongExtra(FbPLayerFragment.ARGS_LATEST_TIMESTAMP, 0);
                manager.saveVideoState(manager.getPlayer().getMediaId(), latestPosition,
                        manager.getPlayer().getDuration());
            }
            Toro.rest(false);
        }

    }

    @Override
    public void onDestroy() {
        Toro.detach(mactivity);
        super.onDestroy();     
    }
}
eneim commented 6 years ago

@yateeshkota Which version of Toro you are using? It looks like v2 or even v1 ....

yateeshkota commented 6 years ago

it is version v2

eneim commented 6 years ago

@yateeshkota By any chance it can be changed to v3?

yateeshkota commented 6 years ago

I have not much more time to change in v3

yateeshkota commented 6 years ago

@eneim I am not able to upload my XML code here

yateeshkota commented 6 years ago

I am new in android and Github

eneim commented 6 years ago

@yateeshkota Just open the xml file in android studio, copy paste it into the comment, remove the part you need.

yateeshkota commented 6 years ago

`<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <View
        android:layout_width="match_parent"
        android:layout_height="@dimen/activity_vertical_margin"
        android:background="#e5e5e5"
        android:visibility="gone" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#f5f5f5"
        android:lineSpacingMultiplier="1.2"
        android:padding="8dp"
        android:text="@string/sample"
        android:textAppearance="@style/TextAppearance.AppCompat.Body1"
        android:visibility="gone" />

    <include layout="@layout/vh_fb_feed_user" />

    <include layout="@layout/vh_toro_video_simple" />

    <View
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:layout_marginLeft="24dp"
        android:layout_marginRight="24dp"
        android:background="#e5e5e5" />

    <include layout="@layout/vh_fb_feed_bottom" />
</LinearLayout>

`