如何在 Android 中使用 PlayerView 的 DefaultTimeBar outSide

how to use DefaultTimeBar outSide of PlayerView in Android

提问人:shanu 提问时间:5/6/2021 最后编辑:Reti43shanu 更新时间:11/19/2023 访问量:1246

问:

我正在使用 playerview,我想显示视频的进度。所以我使用了 PlayerView 并在 playerview 下方使用了 LinearLayout,在 LinearLayout 中我使用了 PlayerView <com.google.android.exoplayer2.ui.DefaultTimeBar> 但是我不知道如何将其与Playerview连接。我不想在 Playerview 上有任何控件,它应该在 Playerview 之外。

我的代码如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
android:orientation="vertical">

<com.google.android.exoplayer2.ui.PlayerView
    android:id="@+id/videoView"
    android:layout_width="match_parent"
    android:layout_height="300dp"
    android:layout_marginLeft="50dp"
    android:layout_marginRight="50dp"
    android:background="@android:color/white"
    android:visibility="visible">

</com.google.android.exoplayer2.ui.PlayerView>

     <com.google.android.exoplayer2.ui.DefaultTimeBar
       android:id="@+id/exo_progress1"
       style="@style/Base.Widget.AppCompat.SeekBar"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content" />

</LinearLayout>

这是我的要求

Requirement

进度条 android-progressbar

评论


答:

-1赞 damai007 9/17/2021 #1

对于这种情况,我有一个解决方法。这个想法是你仍然把 DefaultTimeBar 放在 PlayerView 控制器布局中,然后手动将 DefaultTimeBar 视图移动到 PlayerView 之外,PlayerView 在你的情况下位于 LinearLayout 中。

R.布局.main

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/mainView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/black"
    android:orientation="vertical">

    <com.google.android.exoplayer2.ui.PlayerView
        android:id="@+id/videoView"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:layout_marginLeft="50dp"
        android:layout_marginRight="50dp"
        android:background="@android:color/white"
        app:controller_layout_id="@layout/exo_playback_control_view" />

</LinearLayout>

R.layout.exo_playback_control_view

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.exoplayer2.ui.DefaultTimeBar
       android:id="@+id/exo_progress"
       style="@style/Base.Widget.AppCompat.SeekBar"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content" />

</RelativeLayout>

然后,在您的 activity/fragment 中的某个位置,手动移动视图(例如,我在这里使用 Kotlin)。

val mainView = findViewById<LinearLayout>(R.id.mainView)
val videoView = findViewById<PlayerView>(R.id.videoView)
val defaultTimeBarView = videoView.findViewById<DefaultTimeBar>(R.id.exo_progress)

val parent = defaultTimeBarView.parent as? ViewGroup
parent?.removeView(defaultTimeBarView)
mainView.addView(defaultTimeBarView)

但是,如果隐藏了 PlayerView 的控制器视图可见性,进度条上仍然有奇怪的动画,但如果它是可见的,则进度条可以工作。

1赞 Rob 11/19/2023 #2

试试这个

XML格式

    <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".PlayerActivity">

    <com.google.android.exoplayer2.ui.PlayerView
        android:id="@+id/player"
        android:layout_width="match_parent"
        android:layout_height="400dp"
        app:use_controller="false" // disabling default controlls, or you can just use SurfaceView instead
        android:background="@color/purple_700"
        app:controller_layout_id="@layout/custom_controlls"
        app:layout_constraintTop_toTopOf="parent" />

    <com.google.android.exoplayer2.ui.DefaultTimeBar
        android:id="@+id/tim_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:scrubber_color="@color/purple_500"
        app:played_color="@color/black"
        app:unplayed_color="@color/gray"
        app:buffered_color="@color/purple_700"
        app:layout_constraintBottom_toBottomOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Kotlin 类文件

class PlayerActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_player)

        val player: ExoPlayer = ExoPlayer.Builder(this).build()
        val timeBar = findViewById<DefaultTimeBar>(R.id.exo_progress1)
        val playerView = findViewById<PlayerView>(R.id.videoView)
        playerView.player = player

        val firstItem: MediaItem = MediaItem.fromUri(
            Uri.parse("http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/SubaruOutbackOnStreetAndDirt.mp4")
        )
        val secondItem: MediaItem = MediaItem.fromUri(
            Uri.parse("http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/VolkswagenGTIReview.mp4")
        )
        player.addMediaItem(firstItem)
        player.addMediaItem(secondItem)
        player.prepare()
        player.play()

        player.addListener(object : Listener {
            override fun onPlaybackStateChanged(playbackState: Int) {
                super.onPlaybackStateChanged(playbackState)
                // Once the player is ready you can get the track duration
                if (playbackState == Player.STATE_READY) {
                    timeBar.setDuration(player.duration) // set duration to timeBar
                    lifecycleScope.launch { // here is some example of how you can get the current position from player and set to the timeBar and Yes you have to manage that on your own now as you do not want to use default controls 
                        while (player.isPlaying) {
                            delay(1000L) // update per second
                            timeBar.setPosition(player.currentPosition)
                        }
                    }
                }
            }
        })
    }
}