@@ -11,14 +11,19 @@ import androidx.media3.ui.AspectRatioFrameLayout
11
11
import au.com.shiftyjelly.pocketcasts.player.R
12
12
import au.com.shiftyjelly.pocketcasts.repositories.playback.PlaybackManager
13
13
import au.com.shiftyjelly.pocketcasts.repositories.playback.SimplePlayer
14
+ import au.com.shiftyjelly.pocketcasts.utils.log.LogBuffer
14
15
15
16
class VideoView @JvmOverloads constructor(context : Context , attrs : AttributeSet ? = null , defStyleAttr : Int = 0 ) : FrameLayout(context, attrs, defStyleAttr), SurfaceHolder.Callback, SimplePlayer.VideoChangedListener {
17
+ companion object {
18
+ private const val DELAY_MS = 300L
19
+ private const val TAG = " VideoView"
20
+ }
16
21
17
22
var playbackManager: PlaybackManager ? = null
18
23
var show: Boolean = false
19
24
set(value) {
20
25
field = value
21
- connect ()
26
+ connectWithDelay ()
22
27
}
23
28
24
29
private val view = LayoutInflater .from(context).inflate(R .layout.video_view, this , true )
@@ -30,6 +35,7 @@ class VideoView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
30
35
private val surfaceView = view.findViewById<SurfaceView >(R .id.surfaceView)
31
36
private var isSurfaceCreated: Boolean = false
32
37
private var isSurfaceSet: Boolean = false
38
+ private var pendingConnection = false
33
39
34
40
init {
35
41
surfaceView.holder.addCallback(this )
@@ -78,7 +84,7 @@ class VideoView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
78
84
override fun surfaceCreated (holder : SurfaceHolder ) {
79
85
isSurfaceCreated = true
80
86
isSurfaceSet = false
81
- connect ()
87
+ connectWithDelay ()
82
88
}
83
89
84
90
override fun surfaceChanged (holder : SurfaceHolder , format : Int , width : Int , height : Int ) {
@@ -87,11 +93,30 @@ class VideoView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
87
93
override fun surfaceDestroyed (holder : SurfaceHolder ) {
88
94
isSurfaceCreated = false
89
95
isSurfaceSet = false
96
+ pendingConnection = false // Cancel any pending connection
90
97
}
91
98
92
99
fun updatePlayerPrepared (prepared : Boolean ) {
93
100
if (prepared && ! isSurfaceSet) {
94
- connect ()
101
+ connectWithDelay ()
95
102
}
96
103
}
104
+
105
+ private fun connectWithDelay () {
106
+ pendingConnection = true
107
+ // Temporary fix for https://github.com/Automattic/pocket-casts-android/issues/3807
108
+ // The delay gives time for the Activity/Fragment transition to complete and
109
+ // prevents the race condition where surface gets destroyed immediately after creation
110
+
111
+ postDelayed({
112
+ if (pendingConnection) {
113
+ try {
114
+ connect()
115
+ } catch (e: Exception ) {
116
+ LogBuffer .e(TAG , " Failed to connect video surface" , e)
117
+ }
118
+ }
119
+ pendingConnection = false
120
+ }, DELAY_MS )
121
+ }
97
122
}
0 commit comments