Android ExoPlayer如何在加载视频期间显示加载的第一帧

Android ExoPlayer如何在加载视频期间显示加载的第一帧,android,kotlin,exoplayer,Android,Kotlin,Exoplayer,我有一个API服务于视频URI和一个(预加载的!)第一帧URI。如何使用已经可用的第一帧初始化ExoPlayer @Singleton class MediaPlayer @Inject constructor(private val context: Context) { companion object { var exoPlayer: SimpleExoPlayer? = null var pauseItem = false }

我有一个API服务于视频URI和一个(预加载的!)第一帧URI。如何使用已经可用的第一帧初始化ExoPlayer

@Singleton
class MediaPlayer @Inject constructor(private val context: Context) {

    companion object {
        var exoPlayer: SimpleExoPlayer? = null
        var pauseItem = false
    }

    fun initializeExoplayer(uri: Uri): SimpleExoPlayer {
        if (exoPlayer != null) {
            resetPlayer()
        }

        val trackSelector = DefaultTrackSelector()

        trackSelector.setParameters(
            DefaultTrackSelector.ParametersBuilder()
                .setForceLowestBitrate(true)
                .setMaxAudioBitrate(128_000)
        )

        exoPlayer = ExoPlayerFactory.newSimpleInstance(context, trackSelector)

        val mediaSource = createMediaSource(uri)
        val loopingSource = LoopingMediaSource(mediaSource)

        exoPlayer?.prepare(loopingSource)
        exoPlayer?.volume = 1f

        return exoPlayer!!
    }

    fun resetPlayer() {
        exoPlayer?.playWhenReady = false
        exoPlayer?.stop()
        exoPlayer?.release()
        exoPlayer = null
    }

    private fun createMediaSource(uri: Uri): MediaSource {
        val userAgent = Util.getUserAgent(context, "ExoPlayerIntro")
        val dataSourceFactory = DefaultDataSourceFactory(context, userAgent)

        val mediaSource =
            ProgressiveMediaSource.Factory(dataSourceFactory, DefaultExtractorsFactory())
                .createMediaSource(uri)

        return Objects.requireNonNull(mediaSource, "MediaSource cannot be null")
    }
}
我也问过谷歌团队:
我也找不到解决这个问题的办法。但是,可以通过使用附加的ImageView来解决此问题。 我在MediaPlayer中通过在视频的SurfaceView上重叠ImageView解决了同样的问题

  • 在ImageView中加载视频的第一帧。确保ImageView的大小和位置隐藏视频/表面视图
  • 渲染视频的第一帧后,立即隐藏ImageView
  • 步骤2可通过以下方式实现:

    MediaPlayer

    val onInfoListener = object : MediaPlayer.OnInfoListener {
        override fun onInfo(mp: MediaPlayer?, what: Int, extra: Int): Boolean {
            if (what == MediaPlayer.MEDIA_INFO_BUFFERING_START) {
                imageView.visibility = View.GONE
            }
            return false
        }
    }
    mediaPlayer.setOnInfoListener(onInfoListener)
    
    ExoPlayer: 您可以在VideoListener中使用onRenderedFirstFrame回调,并以类似的方式隐藏ImageView

    文件:

    default void onRenderedFirstFrame()
    
    自设置曲面、重置渲染器或正在渲染的流发生更改后首次渲染帧时调用


    I使用图像视图覆盖视频并使用滑动加载以1s加载第一帧

    Glide.with(context).asBitmap()
                        .load(videoUri)
                        .apply(new RequestOptions().frame(1000))
                        .into(imageView);