如何处理 YouTube 片段 OnSaveInstanceState
How to Handle YouTube Fragment OnSaveInstanceState
问题
YouTube 文档没有明确概述在 API guide or documentation 的 YouTube 生命周期中为 Android 调用 seekToMillis()
的位置。
为了确保 YouTube 播放器在屏幕旋转时从它离开的地方开始播放,需要 seekToMillis(...)
。但是,此方法无法按预期直接在 loadVideo(...)
或 play()
.
之前或之后调用
预计
调用 seekToMillis(...)
以毫秒为单位在特定点开始播放视频。
解决方案
seekToMillis(...)
方法在 YouTubePlayer.PlayerStateChangeListener 中的事件发生后起作用。因此,可以将保存的实例状态包传递到为 PlayerStateChangeListener 制作的内部 class。
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
binding = FragmentYoutubeDialogBinding.inflate(inflater, container, false)
val youTubePlayerFragment = YouTubePlayerSupportFragment.newInstance()
youTubePlayerFragment.initialize(Auth.APP_API_ID, object : OnInitializedListener {
override fun onInitializationSuccess(provider: Provider, player: YouTubePlayer, wasRestored: Boolean) {
if (!wasRestored) {
youtubePlayer = player
player.setPlayerStateChangeListener(MyPlayerStateChangeListener(savedInstanceState))
player.setPlaybackEventListener(MyPlaybackEventListener())
player.loadVideo(arguments!!.getString(ITEM_ID))
player.play()
}
}
override fun onInitializationFailure(provider: Provider, result: YouTubeInitializationResult) {
// TODO: add log statement.
}
})
childFragmentManager.beginTransaction().replace(R.id.youtubePlayer, youTubePlayerFragment as Fragment).commit()
return binding.root
}
private inner class MyPlayerStateChangeListener(var savedInstanceState: Bundle?) : YouTubePlayer.PlayerStateChangeListener {
internal var playerState = "UNINITIALIZED"
override fun onLoading() {
playerState = "LOADING"
}
override fun onLoaded(videoId: String) {
playerState = String.format("LOADED %s", videoId)
}
override fun onAdStarted() {
playerState = "AD_STARTED"
}
override fun onVideoStarted() {
if (savedInstanceState != null) {
println("YT_CURRENT: " + savedInstanceState!!.getInt(YOUTUBE_CURRENT_TIME_KEY))
youtubePlayer.seekToMillis(savedInstanceState!!.getInt(YOUTUBE_CURRENT_TIME_KEY))
playerState = "VIDEO_STARTED"
}
}
问题
YouTube 文档没有明确概述在 API guide or documentation 的 YouTube 生命周期中为 Android 调用 seekToMillis()
的位置。
为了确保 YouTube 播放器在屏幕旋转时从它离开的地方开始播放,需要 seekToMillis(...)
。但是,此方法无法按预期直接在 loadVideo(...)
或 play()
.
预计
调用 seekToMillis(...)
以毫秒为单位在特定点开始播放视频。
解决方案
seekToMillis(...)
方法在 YouTubePlayer.PlayerStateChangeListener 中的事件发生后起作用。因此,可以将保存的实例状态包传递到为 PlayerStateChangeListener 制作的内部 class。
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
binding = FragmentYoutubeDialogBinding.inflate(inflater, container, false)
val youTubePlayerFragment = YouTubePlayerSupportFragment.newInstance()
youTubePlayerFragment.initialize(Auth.APP_API_ID, object : OnInitializedListener {
override fun onInitializationSuccess(provider: Provider, player: YouTubePlayer, wasRestored: Boolean) {
if (!wasRestored) {
youtubePlayer = player
player.setPlayerStateChangeListener(MyPlayerStateChangeListener(savedInstanceState))
player.setPlaybackEventListener(MyPlaybackEventListener())
player.loadVideo(arguments!!.getString(ITEM_ID))
player.play()
}
}
override fun onInitializationFailure(provider: Provider, result: YouTubeInitializationResult) {
// TODO: add log statement.
}
})
childFragmentManager.beginTransaction().replace(R.id.youtubePlayer, youTubePlayerFragment as Fragment).commit()
return binding.root
}
private inner class MyPlayerStateChangeListener(var savedInstanceState: Bundle?) : YouTubePlayer.PlayerStateChangeListener {
internal var playerState = "UNINITIALIZED"
override fun onLoading() {
playerState = "LOADING"
}
override fun onLoaded(videoId: String) {
playerState = String.format("LOADED %s", videoId)
}
override fun onAdStarted() {
playerState = "AD_STARTED"
}
override fun onVideoStarted() {
if (savedInstanceState != null) {
println("YT_CURRENT: " + savedInstanceState!!.getInt(YOUTUBE_CURRENT_TIME_KEY))
youtubePlayer.seekToMillis(savedInstanceState!!.getInt(YOUTUBE_CURRENT_TIME_KEY))
playerState = "VIDEO_STARTED"
}
}