【问题标题】:ExoPlayer how to show loading first frame during loading of videoExoPlayer如何在加载视频期间显示加载第一帧
【发布时间】:2020-10-27 15:45:38
【问题描述】:

我有一个提供视频 URI 和(预加载!)第一帧 URI 的 API。如何使用已经可用的第一帧初始化 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")
    }
}

我还询问了 Google 团队: https://github.com/google/ExoPlayer/issues/8139

【问题讨论】:

    标签: android kotlin exoplayer


    【解决方案1】:

    我也找不到任何解决此问题的方法。但是,可以通过使用额外的 ImageView 来解决。 我通过在视频的 SurfaceView 上重叠 ImageView 解决了 MediaPlayer 中的相同问题。

    1. 在 ImageView 中加载视频的第一帧。确保 ImageView 的大小和位置隐藏了 Video/SurfaceView。
    2. 视频的第一帧渲染完毕后,立即隐藏 ImageView。

    步骤2可以通过:

    媒体播放器

    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()
    

    在设置表面后第一次渲染帧时调用,或者因为渲染器被重置,或者因为正在渲染的流被更改。

    https://exoplayer.dev/doc/reference/com/google/android/exoplayer2/video/VideoListener.html#onRenderedFirstFrame--

    【讨论】:

      【解决方案2】:

      我使用 imageView 覆盖视频并使用 Glide 在 1s 加载第一帧

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

      【讨论】:

        猜你喜欢
        • 2021-02-05
        • 1970-01-01
        • 1970-01-01
        • 2016-04-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多