You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ExoPlayer播放高分辨率视频遇问题:解码失败、画面旋转异常求助

ExoPlayer 高分辨率播放解码失败与画面旋转异常解决方案

问题1:高分辨率视频解码失败

不设置自定义RenderersFactory时,默认工厂可能无法适配高分辨率视频的硬件解码需求,导致解码失败。解决方式是使用DefaultRenderersFactory并开启解码器 fallback、优先硬件加速:

// 替换原ExoPlayer初始化代码
DefaultRenderersFactory renderersFactory = new DefaultRenderersFactory(holder.mVideoView.getContext())
        .setEnableDecoderFallback(true) // 解码失败时自动切换备选解码器
        .setPreferredVideoDecoderType(C.DECODER_TYPE_HARDWARE); // 优先硬件解码

exoPlayer = new ExoPlayer.Builder(holder.mVideoView.getContext())
        .setLoadControl(loadControl)
        .setRenderersFactory(renderersFactory)
        .build();

问题2:画面旋转不稳定

默认RenderersFactory对视频旋转元数据的处理可能受RecyclerView复用、视频元数据不一致影响。可以通过监听视频尺寸变化事件,手动控制画面旋转:

  1. 添加Player监听,处理旋转逻辑:
exoPlayer.addListener(new Player.Listener() {
    @Override
    public void onVideoSizeChanged(VideoSize videoSize) {
        // 获取视频自带的旋转角度
        int rotation = videoSize.videoRotationDegrees;
        // 强制设置VideoView的旋转角度
        holder.mVideoView.setRotation(rotation);
    }

    @Override
    public void onPlaybackStateChanged(int playbackState) {
        // 播放状态闲置时重置旋转(防止RecyclerView复用残留状态)
        if (playbackState == Player.STATE_IDLE) {
            holder.mVideoView.setRotation(0);
        }
    }
});
  1. 配合RecyclerView复用逻辑,在onViewDetachedFromWindow中额外重置旋转状态:
@Override
public void onViewDetachedFromWindow(@NonNull ViewHolder holder) {
    super.onViewDetachedFromWindow(holder);
    // 释放播放器前重置旋转
    holder.mVideoView.setRotation(0);
    holder.player.stop();
    holder.player.release();
    holder.player = null;
}

修改后的完整初始化代码

// 初始化RenderFactory
DefaultRenderersFactory renderersFactory = new DefaultRenderersFactory(holder.mVideoView.getContext())
        .setEnableDecoderFallback(true)
        .setPreferredVideoDecoderType(C.DECODER_TYPE_HARDWARE);

// 创建ExoPlayer实例
exoPlayer = new ExoPlayer.Builder(holder.mVideoView.getContext())
        .setLoadControl(loadControl)
        .setRenderersFactory(renderersFactory)
        .build();

holder.mVideoView.setPlayer(exoPlayer);
holder.mVideoView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_ZOOM);
holder.mVideoView.setShutterBackgroundColor(Color.TRANSPARENT);
holder.mVideoView.setKeepContentOnPlayerReset(true);

// 添加旋转监听
exoPlayer.addListener(new Player.Listener() {
    @Override
    public void onVideoSizeChanged(VideoSize videoSize) {
        holder.mVideoView.setRotation(videoSize.videoRotationDegrees);
    }

    @Override
    public void onPlaybackStateChanged(int playbackState) {
        if (playbackState == Player.STATE_IDLE) {
            holder.mVideoView.setRotation(0);
        }
    }
});

exoPlayer.setRepeatMode(Player.REPEAT_MODE_ONE);

// 构建MediaSource
mediaSource = new ProgressiveMediaSource.Factory(
        new CacheDataSource.Factory()
                .setCache(SimpleMediaPlayer.getInstance(mContext))
                .setUpstreamDataSourceFactory(new DefaultHttpDataSource.Factory()
                        .setUserAgent(mContext.getString(R.string.app_name)))
                .setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR)
).createMediaSource(MediaItem.fromUri(videoItem.videoURL));

exoPlayer.addMediaSource(mediaSource);
exoPlayer.prepare();
exoPlayer.setPlayWhenReady(true);

内容的提问来源于stack exchange,提问作者Manali joshi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 15:10:34