使用exo播放器添加全屏视频按钮

Mes*_*Mes 10 android exoplayer

我正在使用exoPlayer将视频流式传输到我的应用程序,到目前为止工作正常.我现在要做的是添加一些额外的功能,例如右下角的按钮,作为"全屏按钮".

但是有两个问题.第一个是ExoPlayer似乎没有提供任何Control类,因此您可以简单地添加一个按钮并覆盖其功能.我想我必须在视频顶部显示该按钮,所以我可能必须将两者都包在一起FrameLayout并为按钮添加gravity = bottom或者是否有另一种方式?

第二个问题是:如果用户点击全屏按钮,我接下来该怎么办?Fragment全屏添加另一个视频视图?但是,如何从用户点击按钮开始播放视频,而不是从头开始播放?我无法在exoPlayer中找到与特定时间相关的任何内容.

dud*_*ino 9

如果您正在使用SimpleExoPlayerView,有一种方法可以自定义播放器的视图,尤其是Control的视图.查看以下文档SimpleExoPlayerView:

属性

SimpleExoPlayerView在布局XML文件中使用时,可以在a 上设置以下属性:...

controller_layout_id - 指定子项要膨胀的布局资源的ID PlaybackControlView.请参阅下面的更多细节.

  • 对应方法:无

  • 默认值:R.id.exo_playback_control_view

...

因此,基本上您可以为控制器提供自己的布局文件(您可以复制文档中提到的exo_playback_control_view布局,这是默认布局文件,并根据需要自定义.请注意,您需要提供相同的视图ID现有的控件(因此最好实际复制它),如以下文档中所述PlaybackControlView:

覆盖布局文件

要自定义PlaybackControlView整个应用程序的布局,或仅针对某些配置,您可以在应用程序res/layout*目录中定义exo_playback_control_view.xml布局文件.这些布局将覆盖ExoPlayer库提供的布局,并将被夸大以供使用PlaybackControlView.该视图通过查找以下ID来标识并绑定其子项:

  • exo_play - 播放按钮.

  • exo_pause - 暂停按钮.

  • exo_ffwd - 快进按钮.

  • exo_rew - 倒带按钮.

  • exo_prev - 上一曲目按钮.

  • exo_next - 下一个曲目按钮.

  • exo_position - 显示当前播放位置的文本视图.

  • exo_duration - 显示当前媒体持续时间的文本视图.

  • exo_progress - 寻找在播放期间更新的栏,并允许搜索.

所有子视图都是可选的,因此如果不需要则可以省略,但是在定义时它们必须是预期类型.

以下是带全屏按钮的自定义布局.您可以获得按钮的引用view.findViewById(R.id.exo_fullscreen_button)并将其附加OnClickListener到按钮.在里面onClick()你可以开始你的全屏活动(你可以在AndroidManifest.xml中或以编程方式定义它的全屏)或显示SimpleExoPlayerView占据整个屏幕的另一个片段.从第二点开始,您可以像这样获得播放位置:playbackPosition = player.getCurrentPosition()并将其作为Intent extra传递给新的全屏Activity/Fragment.然后,在全屏活动/片段中加载视频,提取该playbackPosition值并调用:

player.seekTo(playbackPosition);
player.setPlayWhenReady(true);
Run Code Online (Sandbox Code Playgroud)

这是控件布局文件:

  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:paddingTop="4dp"
    android:orientation="horizontal">

    <ImageButton android:id="@id/exo_prev"
      style="@style/ExoMediaButton.Previous"/>

    <ImageButton android:id="@id/exo_rew"
      style="@style/ExoMediaButton.Rewind"/>

    <ImageButton android:id="@id/exo_play"
      style="@style/ExoMediaButton.Play"/>

    <ImageButton android:id="@id/exo_pause"
      style="@style/ExoMediaButton.Pause"/>

    <ImageButton android:id="@id/exo_ffwd"
      style="@style/ExoMediaButton.FastForward"/>

    <ImageButton android:id="@id/exo_next"
      style="@style/ExoMediaButton.Next"/>

    // This is the custom button
    <ImageButton
        android:id="@+id/exo_fullscreen_button"
        style="@style/ExoMediaButton"
        android:src="@drawable/ic_fullscreen"/>
  </LinearLayout>

  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="4dp"
    android:gravity="center_vertical"
    android:orientation="horizontal">

    <TextView android:id="@id/exo_position"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:textSize="14sp"
      android:textStyle="bold"
      android:paddingLeft="4dp"
      android:paddingRight="4dp"
      android:includeFontPadding="false"
      android:textColor="#FFBEBEBE"/>

    <SeekBar android:id="@id/exo_progress"
      android:layout_width="0dp"
      android:layout_weight="1"
      android:layout_height="32dp"
      android:focusable="false"
      style="?android:attr/progressBarStyleHorizontal"/>

    <TextView android:id="@id/exo_duration"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:textSize="14sp"
      android:textStyle="bold"
      android:paddingLeft="4dp"
      android:paddingRight="4dp"
      android:includeFontPadding="false"
      android:textColor="#FFBEBEBE"/>

  </LinearLayout>

</LinearLayout>
Run Code Online (Sandbox Code Playgroud)


Alb*_*lvo 7

解决方案是在当前 Activity 之上创建一个新的全屏 Activity,并将播放位置传递给它

另一个答案很好,为您指明了正确的方向,但它相当理论化,我在编写代码时仍然需要填补一些空白并解决一些问题。我会尽力补充一下。

首先将布局exo_playback_control_view.xml从 ExoPlayer 库复制到res/layout. 文件链接:https://github.com/google/ExoPlayer/blob/release-v2/library/ui/src/main/res/layout/exo_playback_control_view.xml

修改布局以添加全屏按钮,可以是这样的:

<FrameLayout
    android:id="@+id/exo_fullscreen_button"
    android:layout_width="32dp"
    android:layout_height="32dp"
    android:layout_gravity="end">

    <ImageView
        android:layout_width="18dp"
        android:layout_height="18dp"
        android:layout_gravity="center"
        android:adjustViewBounds="true"
        android:scaleType="fitCenter"
        android:src="@drawable/ic_fullscreen_expand"
        android:focusable="true" />

</FrameLayout>
Run Code Online (Sandbox Code Playgroud)

PlayerView请注意,通过使用 属性,您可以为不同的 s 提供不同的布局app:controller_layout_id。如果您不需要播放器按钮,也可以将其删除。文档中对此进行了介绍:https://exoplayer.dev/ui-components.html#overriding-layout-files

一旦你有了全屏按钮,在OnClickListener上面设置一个:

findViewById<View>(R.id.exo_fullscreen_button).setOnClickListener {
    player.playWhenReady = false // pause current video if it's playing
    startActivity(
        FullScreenVideoActivity.newIntent(
            context,
            videoUrl,
            player.currentPosition
        )
    )
}
Run Code Online (Sandbox Code Playgroud)

添加FullScreenVideoActivity

private const val EXTRA_VIDEO_URL = "EXTRA_VIDEO_URL"
private const val EXTRA_PLAYBACK_POSITION_MS = "EXTRA_PLAYBACK_POSITION_MS"

private const val STATE_PLAYBACK_POSITION_MS = "STATE_PLAYBACK_POSITION_MS"

class FullScreenVideoActivity : AppCompatActivity() {

    companion object {
        fun newIntent(packageContext: Context, videoUrl: String, playbackPositionMs: Long): Intent {
            val intent =
                Intent(packageContext, FullScreenVideoActivity::class.java)
            intent.putExtra(EXTRA_VIDEO_URL, videoUrl)
            intent.putExtra(EXTRA_PLAYBACK_POSITION_MS, playbackPositionMs)
            return intent
        }
    }

    private lateinit var player: SimpleExoPlayer

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_full_screen_video)

        val videoUrl = intent.getStringExtra(EXTRA_VIDEO_URL)
        var playbackPositionMs = intent.getLongExtra(EXTRA_PLAYBACK_POSITION_MS, 0)

        if (savedInstanceState != null) {
            // The user rotated the screen
            playbackPositionMs = savedInstanceState.getLong(STATE_PLAYBACK_POSITION_MS)
        }

        findViewById<View>(R.id.exo_fullscreen_button).setOnClickListener {
            finish()
        }

        val playerView: PlayerView = findViewById(R.id.player_view)
        player = ExoPlayerFactory.newSimpleInstance(this)
        val userAgent = Util.getUserAgent(this, getString(R.string.app_name))
        val dataSourceFactory = DefaultDataSourceFactory(this, userAgent)
        val mediaSource: MediaSource =
            ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(videoUrl))
        player.prepare(mediaSource)
        player.seekTo(playbackPositionMs)
        player.playWhenReady = true
        playerView.player = player
    }

    override fun onPause() {
        super.onPause()
        player.playWhenReady = false
    }

    override fun onDestroy() {
        super.onDestroy()
        player.release()
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putLong(STATE_PLAYBACK_POSITION_MS, player.currentPosition)
    }

}
Run Code Online (Sandbox Code Playgroud)

将活动添加到清单中:

<activity
    android:name=".ui.FullScreenVideoActivity"
    android:screenOrientation="landscape" <-- this is optional
    android:theme="@style/AppTheme.NoActionBar.FullScreen" />
Run Code Online (Sandbox Code Playgroud)

最后添加主题styles.xml

<style name="AppTheme.NoActionBar.FullScreen">
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowContentOverlay">@null</item>
</style>
Run Code Online (Sandbox Code Playgroud)

就这样!希望能帮助到你。

当前活动中的替代解决方案

上面的解决方案工作得很好而且很简单。但是,它需要重新下载您已下载的视频的某些部分,这会中断播放:/

我一直试图通过遵循此指示来避免这种情况。这是我到目前为止所拥有的:

activity!!.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
val fullScreenPlayerView = PlayerView(context)
val dialog = object : Dialog(context!!, android.R.style.Theme_Black_NoTitleBar_Fullscreen) {
    override fun onBackPressed() {
        activity!!.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
        PlayerView.switchTargetView(player, fullScreenPlayerView, playerView)
        super.onBackPressed()
    }
}
dialog.addContentView(
    fullScreenPlayerView,
    ViewGroup.LayoutParams(
        ViewGroup.LayoutParams.MATCH_PARENT,
        ViewGroup.LayoutParams.MATCH_PARENT
    )
)
dialog.show()
PlayerView.switchTargetView(player, playerView, fullScreenPlayerView)
Run Code Online (Sandbox Code Playgroud)

请注意,要使其工作,您必须android:configChanges="orientation|screenSize|layoutDirection"在清单中设置您的活动。