Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

1.2K
Vistas
ExoPlayer muestra una pantalla negra en lugar de cargar el video (solo a veces)

Tengo un recyclerView dentro de mi aplicación que puede cargar videos e imágenes. Estoy usando la biblioteca ExoPlayer para cargar videos en mi vista de reciclador. El problema es que a veces ExoPlayer muestra una pantalla negra en lugar de cargar el video. Intenté registrar la URL del video desde firebase y no es nula o algo así.

Estoy usando esta biblioteca: https://github.com/HamidrezaAmz/MagicalExoPlayer

Nota: este problema apareció cuando implementé la paginación (cargar más publicaciones en el desplazamiento) con firebase y recyclerView .

Fragmento de mi hogar:

 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; } }

Mi 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(); } }

Mi 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>
over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Mueva el método addview de onScrollStateChanged al método onPlayerStateChanged de exoplayer. Al agregar la vista en onscrollstatechanged, estaba tratando de agregar la vista en cada fracción de segundo.

Además, agregue un controlador, que sigue verificando el estado de una variable si la vista no se agrega y luego agrega la vista, de esta manera, la vista se agrega la mayor parte del tiempo a través del método onPlayerStateChanged o por el controlador. Se resuelve en la mayoría de los casos pero aún no al 100%.

Aquí estoy agregando una referencia al problema https://github.com/google/ExoPlayer/issues/7750

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda