RecyclerView 和 Firebase Storage 快速滚动 ExoPlayer 异常
Posted
技术标签:
【中文标题】RecyclerView 和 Firebase Storage 快速滚动 ExoPlayer 异常【英文标题】:RecyclerView and Firebase Storage fast scrolling ExoPlayer exception 【发布时间】:2020-09-26 17:59:01 【问题描述】:所以我有一个 android 应用程序,它读取存储在 Firebase 实时数据库中的一些 Firebase Storage 下载 URL。我还使用 RecyclerView 来渲染一些播放这些视频的 ExoPlayers。 问题是,如果我滚动得非常快,则没有足够的时间来渲染所有内容,并且程序会引发异常。 我想我有太多的 ExoPlayers 被保留,当我需要移除它们时,我需要继续前进。我该怎么做?
E/ExoPlayerImplInternal: Renderer error: index=0, type=video, format=Format(1, null, null, video/avc, null, -1, null, [640, 480, 29.997072], [-1, -1]), rendererSupport=YES
com.google.android.exoplayer2.ExoPlaybackException: com.google.android.exoplayer2.mediacodec.MediaCodecRenderer$DecoderInitializationException: Decoder init failed: OMX.Exynos.avc.dec, Format(1, null, null, video/avc, null, -1, null, [640, 480, 29.997072], [-1, -1])
at com.google.android.exoplayer2.BaseRenderer.createRendererException(BaseRenderer.java:359)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodec(MediaCodecRenderer.java:563)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.onInputFormatChanged(MediaCodecRenderer.java:1254)
at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.onInputFormatChanged(MediaCodecVideoRenderer.java:756)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.readToFlagsOnlyBuffer(MediaCodecRenderer.java:814)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:712)
at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:599)
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:329)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:237)
at android.os.HandlerThread.run(HandlerThread.java:67)
这是 RecyclerView 代码:
FirebaseRecyclerOptions<MediaObject> options =
new FirebaseRecyclerOptions.Builder<MediaObject>()
.setQuery(databaseReference.orderByChild("title"), MediaObject.class)
.build();
FirebaseRecyclerAdapter<MediaObject, ViewHolder> firebaseRecyclerAdapter =
new FirebaseRecyclerAdapter<MediaObject, ViewHolder>(options)
@Override
protected void onBindViewHolder(@NonNull ViewHolder viewHolder, int i, @NonNull MediaObject mediaObject)
viewHolder.setVideo(getApplication(), mediaObject.getTitle().replace(".mp4", ""), mediaObject.getMedia_url());
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.activity_view_extended_videolist, parent, false);
return new ViewHolder(view);
;
firebaseRecyclerAdapter.startListening();
recycleView.setAdapter(firebaseRecyclerAdapter);
ViewHolder 代码:
public class ViewHolder extends RecyclerView.ViewHolder
private View mView;
private SimpleExoPlayer exoPlayer;
private PlayerView mExoPlayerView;
public ViewHolder(@NonNull View itemView)
super(itemView);
mView = itemView;
public void setVideo(final Application ctx, String title, String url)
TextView mTextView = mView.findViewById(R.id.titleTv);
mExoPlayerView = mView.findViewById(R.id.exoplayer_view);
mTextView.setText(title);
try
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter.Builder(ctx).build();
TrackSelector trackSelector = new DefaultTrackSelector(new AdaptiveTrackSelection.Factory(bandwidthMeter));
exoPlayer = ExoPlayerFactory.newSimpleInstance(ctx);
Uri video = Uri.parse(url);
DefaultHttpDataSourceFactory dataSourceFactory = new DefaultHttpDataSourceFactory("2020-04-12");
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
MediaSource mediaSource = new ExtractorMediaSource(video, dataSourceFactory, extractorsFactory, null, null);
mExoPlayerView.setPlayer(exoPlayer);
exoPlayer.prepare(mediaSource);
exoPlayer.setPlayWhenReady(false);
catch (Exception e)
Log.d("ViewHolder", "exoplayer error " + e.toString());
【问题讨论】:
【参考方案1】:我最终只使用 exoPlayer.release()
【讨论】:
成功了吗?我在向上滚动屏幕时遇到同样的问题 是的,它正在工作。虽然它可能不是最好的解决方案。我读到一个好的解决方案是拥有一个大约 5 个 ExoPlayers 的池。我真的不知道这样更有效率。如果 ExoPlayer 超出滚动窗口,则每次用户返回时都必须重新加载。但我被时间所逼,做了这件事,不管是否有效。就我的情况来说,这已经足够好了。 是的,当我滚动多达 10 到 13 个视频时,它会因您提到的错误而变黑 @Alex 请使用 release() 发布新代码。发布有什么作用?现在我需要为 onBindViewHolder 中的每个视图重新创建播放器?以上是关于RecyclerView 和 Firebase Storage 快速滚动 ExoPlayer 异常的主要内容,如果未能解决你的问题,请参考以下文章
Firebase:Recyclerview 没有附加适配器,跳过布局
Firebase:Recyclerview 没有附加适配器,跳过布局
使用 Firebase 实时数据库参考填充 RecyclerView
在使用 Firebase 和 ChildEventListener 时,如何在方向更改后保留 RecyclerView 的位置?