Mes*_*Mes 10 android exoplayer
我正在使用exoPlayer将视频流式传输到我的应用程序,到目前为止工作正常.我现在要做的是添加一些额外的功能,例如右下角的按钮,作为"全屏按钮".
但是有两个问题.第一个是ExoPlayer似乎没有提供任何Control类,因此您可以简单地添加一个按钮并覆盖其功能.我想我必须在视频顶部显示该按钮,所以我可能必须将两者都包在一起FrameLayout并为按钮添加gravity = bottom或者是否有另一种方式?
第二个问题是:如果用户点击全屏按钮,我接下来该怎么办?Fragment全屏添加另一个视频视图?但是,如何从用户点击按钮开始播放视频,而不是从头开始播放?我无法在exoPlayer中找到与特定时间相关的任何内容.
如果您正在使用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)
另一个答案很好,为您指明了正确的方向,但它相当理论化,我在编写代码时仍然需要填补一些空白并解决一些问题。我会尽力补充一下。
首先将布局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"在清单中设置您的活动。
| 归档时间: |
|
| 查看次数: |
5082 次 |
| 最近记录: |