java - ExoPlayer 显示黑屏而不是加载视频(仅有时)

标签 java android firebase exoplayer

我的应用程序中有一个 recyclerView 可以加载视频和图像。我正在使用 ExoPlayer 库将视频加载到我的回收站 View 中。问题是有时 ExoPlayer 显示黑屏而不是加载视频。我尝试从 firebase 记录视频 url,但它不是 null 或类似的东西。

我正在使用这个库: https://github.com/HamidrezaAmz/MagicalExoPlayer

注意:当我使用 firebase 和 recyclerView 实现分页(滚动加载更多帖子)时出现此问题。

我的 HomeFragment:

public class HomeFragment extends Fragment {

    LoadingDialog progressDialog;
    final DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
    boolean isSearchOpen = false;
    private EditText searchView;
    ArrayList<PostModel> postModelArrayList;
    ArrayList<PostModel> loadedPostsArrayList;
    RecyclerView recyclerView;
    PostRecyclerAdapter recyclerAdapter;

    int lastLoadedIndex = 0;

    void loadMorePosts() {
        // Load 4 post's per time
        for (int i = 0; i < 3; i++) {
            if (lastLoadedIndex + 1 < postModelArrayList.size()) {
                PostModel postModel = postModelArrayList.get(lastLoadedIndex + 1);
                loadedPostsArrayList.add(postModel);
                recyclerAdapter.notifyDataSetChanged();
                lastLoadedIndex = lastLoadedIndex + 1;
            }
        }
    }

    void loadAllPosts(View fragmentView) {
        DatabaseReference postsRef = FirebaseDatabase.getInstance().getReference("posts");
        postsRef.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {

                new Handler().postDelayed(() -> {
                    fragmentView.findViewById(R.id.constraintLayout2).setVisibility(View.GONE);
                    HomeActivity.bottomNavBar.setVisibility(View.VISIBLE);
                    HomeActivity.showLoadingScreen = false;
                }, 1200);

                for (DataSnapshot postSnapshot : snapshot.getChildren()) {
                    PostModel postModel = postSnapshot.getValue(PostModel.class);

                    // Show post in recycler adapter only if the user is not blocked
                    if (!snapshot.child("users").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("blockedUsers").child(postSnapshot.child("name").getValue(String.class)).exists()) {
                        postModelArrayList.add(postModel);
                    }

                    recyclerAdapter.notifyDataSetChanged();
                }

                // Reverse elements inside postModelArrayList
                Collections.reverse(postModelArrayList);

                // Load first 3 post's
                for (int i = 0; i < 3; i++) {
                    loadedPostsArrayList.add(postModelArrayList.get(i));
                    lastLoadedIndex++;
                }

            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                Toast.makeText(getContext(), "Error: " + error.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_home, container, false);

        SwipeRefreshLayout swipeRefreshLayout = view.findViewById(R.id.root_view);
        TextView usernameLoadingScreen = view.findViewById(R.id.textView40);
        ImageButton searchUserBtn = view.findViewById(R.id.searchPersonButton);
        ImageButton notificationsBtn = view.findViewById(R.id.notificationsButton);
        ImageButton searchUserButton = view.findViewById(R.id.enter_search_button);
        View postsOfTheMonthBtn = view.findViewById(R.id.posts_of_the_month_btn);
        searchView = view.findViewById(R.id.search_view);

        recyclerView = view.findViewById(R.id.home_recycler_view);
        loadedPostsArrayList = new ArrayList<>();


        final LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
        recyclerAdapter = new PostRecyclerAdapter(loadedPostsArrayList, getContext(), getActivity());
        
        recyclerView.setAdapter(recyclerAdapter);
        recyclerView.setLayoutManager(layoutManager);

        progressDialog = LoadingDialog.Companion.get(getActivity());

        searchView.setVisibility(View.GONE);
        searchUserButton.setVisibility(View.GONE);

        if (HomeActivity.showWhatsNewMessage) {
            FirebaseInAppMessaging.getInstance().triggerEvent("new_version_open");
        }

        // Avoid data refresh on every swipe down
        recyclerView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) ->
                swipeRefreshLayout.setEnabled(scrollY <= 5));

        // Re-load data
        swipeRefreshLayout.setOnRefreshListener(() -> {
            swipeRefreshLayout.setRefreshing(true);
            loadAllPosts(view);
            swipeRefreshLayout.setRefreshing(false);
        });

        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                loadMorePosts();
            }
        });

        HomeActivity.bottomNavBar.setVisibility(View.GONE);
        loadAllPosts(view);

        return view;
    }

}

我的 PostRecyclerAdapter:

public class PostRecyclerAdapter extends RecyclerView.Adapter {

    List<PostModel> postList;
    Context context;
    Activity activity;

    @Override
    public int getItemViewType(int position) {
        if (postList.get(position).getPostType().equals("video")) {
            return 1;
        }
        return 0;
    }

    public void addAll(List<PostModel> newPosts) {
        int initSize = postList.size();
        postList.addAll(newPosts);
        notifyItemRangeChanged(initSize, postList.size());
    }

    public String getLastItemID() {
        return postList.get(postList.size() - 1).getId();
    }

    public PostRecyclerAdapter(ArrayList<PostModel> postModelArrayList, Context context, Activity activity) {
        this.postList = postModelArrayList;
        this.context = context;
        this.activity = activity;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (viewType == 1) {
            return new VideoViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.post_video_item, parent, false));
        }
        return new ImageViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.post_item, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

        DatabaseReference likeRef = FirebaseDatabase.getInstance().getReference("likes");
        FirebaseAuth mAuth = FirebaseAuth.getInstance();
        FirebaseUser user = mAuth.getCurrentUser();

        if (postList.get(position).getPostType().equals("video")) {
            // bind video view holder
            VideoViewHolder videoViewHolder = (VideoViewHolder) holder;
            videoViewHolder.setContext(context);

            // check if post is liked or not
            likeRef.addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull @NotNull DataSnapshot snapshot) {
                    if (!HomeActivity.anonymous) {

                        // check if current post is liked from this user
                        if (snapshot.child(videoViewHolder.id).hasChild(user.getUid())) {
                            // post is liked form this user
                            videoViewHolder.like_btn.setImageResource(R.drawable.ic_thumb_up_filled);

                        } else {
                            // post is not liked from this user
                            videoViewHolder.like_btn.setImageResource(R.drawable.ic_thump_up_outline);
                        }
                    } else {
                        // disable like button
                        videoViewHolder.like_btn.setEnabled(false);
                    }

                }

                @Override
                public void onCancelled(@NonNull @NotNull DatabaseError error) {
                    Toast.makeText(context, "error: " + error, Toast.LENGTH_SHORT).show();
                }
            });

            // Get current post id set username, authorID, profile picture URL, postType, likes and post image URL
            videoViewHolder.id = postList.get(position).getId();
            videoViewHolder.username.setText(postList.get(position).getName());
            videoViewHolder.userID = postList.get(position).getAuthorID();
            videoViewHolder.like_counter_tv.setText(postList.get(position).getLikes());
            videoViewHolder.videoURL = postList.get(position).getImgUrl();

            // Load video source
            HashMap<String, String> extraHeaders = new HashMap<>();
            extraHeaders.put("foo", "bar");
            videoViewHolder.andExoPlayerView.setSource(postList.get(position).getImgUrl(), extraHeaders);
            videoViewHolder.andExoPlayerView.setPlayWhenReady(false);
            videoViewHolder.andExoPlayerView.setAspectRatio(EnumAspectRatio.ASPECT_16_9);

            // Load profile picture
            String profilePictureUrl = postList.get(position).getProfileImgUrl();
            if (profilePictureUrl != null) {
                if (!profilePictureUrl.equals("none")) {
                    Glide.with(context).load(profilePictureUrl).into(videoViewHolder.profilePicture);
                }
            }


        } else {

            // bind image view holder
            ImageViewHolder imageViewHolder = (ImageViewHolder) holder;
            imageViewHolder.setContext(context);

            // check if post is liked or not
            likeRef.addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull @NotNull DataSnapshot snapshot) {
                    if (!HomeActivity.anonymous) {

                        // check if current post is liked from this user
                        if (snapshot.child(imageViewHolder.postID).hasChild(user.getUid())) {
                            // post is liked form this user
                            imageViewHolder.like_btn.setImageResource(R.drawable.ic_thumb_up_filled);

                        } else {
                            // post is not liked from this user
                            imageViewHolder.like_btn.setImageResource(R.drawable.ic_thump_up_outline);
                        }
                    } else {
                        // disable like button
                        imageViewHolder.like_btn.setEnabled(false);
                    }

                }

                @Override
                public void onCancelled(@NonNull @NotNull DatabaseError error) {
                    Toast.makeText(context, "error: " + error, Toast.LENGTH_SHORT).show();
                }
            });


            // Get current post id set username, authorID, profile picture URL, postType, likes and post image URL
            imageViewHolder.postID = postList.get(position).getId();
            imageViewHolder.username.setText(postList.get(position).getName());
            imageViewHolder.userID = postList.get(position).getAuthorID();
            imageViewHolder.like_counter_tv.setText(postList.get(position).getLikes());

            Picasso.get().load(postList.get(position).getImgUrl()).into(imageViewHolder.postImg);
            imageViewHolder.postImageURL = postList.get(position).getImgUrl();

            // Load profile picture
            String profilePictureUrl = postList.get(position).getProfileImgUrl();
            if (profilePictureUrl != null) {
                if (!profilePictureUrl.equals("none")) {
                    Glide.with(context).load(profilePictureUrl).into(imageViewHolder.profileImage);
                }
            }
        }

    }


    @Override
    public int getItemCount() {
        return postList.size();
    }

}

我的 video_post_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/video_container"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_margin="12dp"
    app:cardElevation="8dp"
    app:cardCornerRadius="10dp">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/sContainer"
        android:layout_width="match_parent"
        android:background="?attr/cardBackgroundColor"
        android:layout_height="wrap_content">

        <de.hdodenhof.circleimageview.CircleImageView
            android:id="@+id/circleImageView2"
            android:layout_width="35dp"
            android:layout_height="35dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="8dp"
            android:src="@drawable/user"
            app:layout_constraintEnd_toStartOf="@+id/textView27"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/textView27"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:text="username"
            android:textColor="?attr/titleTextColor"
            android:textSize="17sp"
            android:textStyle="bold"
            app:layout_constraintBottom_toBottomOf="@+id/circleImageView2"
            app:layout_constraintStart_toEndOf="@+id/circleImageView2"
            app:layout_constraintTop_toTopOf="@+id/circleImageView2" />

        <com.potyvideo.library.AndExoPlayerView
            android:id="@+id/andExoPlayerView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            app:andexo_show_full_screen="true"
            app:keep_content_on_player_reset="true"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/textView27"
            app:layout_constraintVertical_bias="1.0" />

        <ImageButton
            android:id="@+id/imageButton8"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="15dp"
            android:background="@null"
            app:layout_constraintBottom_toBottomOf="@+id/textView27"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="@+id/textView27"
            app:srcCompat="@drawable/ic_thumb_up" />

        <TextView
            android:id="@+id/textView36"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:text="0"
            android:textColor="?attr/titleTextColor"
            android:textSize="18sp"
            android:textStyle="bold"
            app:layout_constraintBottom_toBottomOf="@+id/imageButton8"
            app:layout_constraintEnd_toStartOf="@+id/imageButton8"
            app:layout_constraintTop_toTopOf="@+id/imageButton8" />

        <View
            android:id="@+id/view5"
            android:layout_width="200dp"
            android:layout_height="55dp"
            android:focusable="true"
            android:foreground="?selectableItemBackgroundBorderless"
            app:layout_constraintBottom_toTopOf="@+id/andExoPlayerView"
            app:layout_constraintEnd_toEndOf="@+id/textView27"
            app:layout_constraintStart_toStartOf="@+id/circleImageView2"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.cardview.widget.CardView>

最佳答案

将 addview 方法从 onScrollStateChanged 移动到 exoplayer 的 onPlayerStateChanged 方法。通过在 onscrollstatechanged 中添加 View ,它试图在每一分之一秒内添加 View 。

此外,添加一个处理程序,如果未添加 View ,它会不断检查变量的状态,然后添加 View ,这样,大部分时间通过 onPlayerStateChanged 方法或处理程序添加 View 。它在大多数情况下都解决了,但仍然不是 100%。

在这里我添加了一个对问题的引用 https://github.com/google/ExoPlayer/issues/7750

关于java - ExoPlayer 显示黑屏而不是加载视频(仅有时),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71243169/

相关文章:

javascript - 创建基本库firebase错误

java - 使用 java 和脚本启动 .class 文件

java stringbuilder添加额外字符新手问题

android - 小部件在 ICS 中显示 "App Isn' t Installed"Toast

ios - Swift 函数在应用程序中有效,但在 override func viewDidLoad() 中无效

firebase - 无法弄清楚如何使用 Gridsome-Plugin-Firestore

java - Eclipse:如何防止格式化多行连接字符串?

在 java 中从 Excel 中删除行时出现 java.util.ConcurrentModificationException

android - 使用 switch case 通过 ListView 从 fragment 打开 Activity 时出错

页面 fragment 之间的 Android ViewPager 填充/边距