@@ -3,21 +3,21 @@ package dev.aaa1115910.bv.player.mobile.component
3
3
import androidx.compose.foundation.layout.fillMaxHeight
4
4
import androidx.compose.runtime.Composable
5
5
import androidx.compose.runtime.LaunchedEffect
6
- import androidx.compose.runtime.SideEffect
7
6
import androidx.compose.runtime.getValue
8
7
import androidx.compose.runtime.mutableStateOf
9
8
import androidx.compose.runtime.remember
10
9
import androidx.compose.runtime.saveable.rememberSaveable
11
10
import androidx.compose.runtime.setValue
12
11
import androidx.compose.ui.Modifier
13
12
import androidx.compose.ui.draw.alpha
14
- import androidx.media3.common.Player
15
- import androidx.media3.exoplayer.ExoPlayer
16
13
import com.kuaishou.akdanmaku.DanmakuConfig
17
14
import com.kuaishou.akdanmaku.data.DanmakuItemData
18
15
import com.kuaishou.akdanmaku.ecs.component.filter.TypeFilter
19
16
import com.kuaishou.akdanmaku.ext.RETAINER_BILIBILI
20
17
import com.kuaishou.akdanmaku.ui.DanmakuPlayer
18
+ import dev.aaa1115910.bv.player.AbstractVideoPlayer
19
+ import dev.aaa1115910.bv.player.BvVideoPlayer
20
+ import dev.aaa1115910.bv.player.VideoPlayerListener
21
21
import dev.aaa1115910.bv.player.mobile.component.controller.BvPlayerController
22
22
import dev.aaa1115910.bv.player.mobile.util.LocalMobileVideoPlayerData
23
23
import kotlinx.coroutines.delay
@@ -35,11 +35,14 @@ fun BvPlayer(
35
35
onDanmakuOpacityChange : (Float ) -> Unit ,
36
36
onDanmakuScaleChange : (Float ) -> Unit ,
37
37
onDanmakuAreaChange : (Float ) -> Unit ,
38
- videoPlayer : ExoPlayer ,
39
- danmakuPlayer : DanmakuPlayer
38
+ videoPlayer : AbstractVideoPlayer ,
39
+ danmakuPlayer : DanmakuPlayer ?
40
40
) {
41
41
val mobileVideoPlayerData = LocalMobileVideoPlayerData .current
42
42
var isPlaying by rememberSaveable { mutableStateOf(false ) }
43
+ var isError by remember { mutableStateOf(false ) }
44
+ var isBuffering by remember { mutableStateOf(false ) }
45
+ var exception by remember { mutableStateOf<Exception ?>(null ) }
43
46
44
47
var enabledDanmaku by rememberSaveable { mutableStateOf(mobileVideoPlayerData.enabledDanmaku) }
45
48
val typeFilter by remember { mutableStateOf(TypeFilter ()) }
@@ -75,6 +78,13 @@ fun BvPlayer(
75
78
}
76
79
}
77
80
81
+ // 直接调用 danmakuPlayer 会始终为 null
82
+ var mDanmakuPlayer: DanmakuPlayer ? by remember { mutableStateOf(null ) }
83
+
84
+ LaunchedEffect (danmakuPlayer) {
85
+ mDanmakuPlayer = danmakuPlayer
86
+ }
87
+
78
88
val initDanmakuConfig: () -> Unit = {
79
89
updateEnabledDanmakuTypeFilter(mobileVideoPlayerData.currentDanmakuTypes)
80
90
danmakuConfig = danmakuConfig.copy(
@@ -83,27 +93,122 @@ fun BvPlayer(
83
93
dataFilter = listOf (typeFilter)
84
94
)
85
95
danmakuConfig.updateFilter()
86
- danmakuPlayer .updateConfig(danmakuConfig)
96
+ mDanmakuPlayer? .updateConfig(danmakuConfig)
87
97
}
88
98
89
99
val updateDanmakuConfigTypeFilter: () -> Unit = {
90
100
updateEnabledDanmakuTypeFilter(mobileVideoPlayerData.currentDanmakuTypes)
91
101
danmakuConfig.updateFilter()
92
- danmakuPlayer .updateConfig(danmakuConfig)
102
+ mDanmakuPlayer? .updateConfig(danmakuConfig)
93
103
}
94
104
95
105
val toggleDanmakuEnabled: (Boolean ) -> Unit = { enabled ->
96
106
updateEnabledDanmakuTypeFilter(if (enabled) mobileVideoPlayerData.currentDanmakuTypes else listOf ())
97
107
danmakuConfig.updateFilter()
98
- danmakuPlayer .updateConfig(danmakuConfig)
108
+ mDanmakuPlayer? .updateConfig(danmakuConfig)
99
109
}
100
110
101
111
val updateDanmakuConfig: () -> Unit = {
102
112
danmakuConfig = danmakuConfig.copy(
103
113
retainerPolicy = RETAINER_BILIBILI ,
104
114
textSizeScale = mobileVideoPlayerData.currentDanmakuScale,
105
115
)
106
- danmakuPlayer.updateConfig(danmakuConfig)
116
+ mDanmakuPlayer?.updateConfig(danmakuConfig)
117
+ }
118
+
119
+ val videoPlayerListener = object : VideoPlayerListener {
120
+ override fun onError (error : Exception ) {
121
+ println (" onError: $error " )
122
+ isError = true
123
+ exception = error.cause as Exception ?
124
+ }
125
+
126
+ override fun onReady () {
127
+ println (" onReady" )
128
+ isError = false
129
+ exception = null
130
+ initDanmakuConfig()
131
+
132
+ videoPlayer.start()
133
+
134
+ // updateVideoAspectRatio()
135
+
136
+ // reset default play speed
137
+ // logger.info { "Reset default play speed: $currentPlaySpeed" }
138
+ // videoPlayer.speed = currentPlaySpeed
139
+ // playerViewModel.danmakuPlayer?.updatePlaySpeed(currentPlaySpeed)
140
+ }
141
+
142
+ override fun onPlay () {
143
+ println (" onPlay" )
144
+ // logger.info { "onPlay" }
145
+ println (" start danmaku player, ${danmakuPlayer != null } " )
146
+ mDanmakuPlayer?.start()
147
+ isPlaying = true
148
+ isBuffering = false
149
+
150
+ // if (playerViewModel.lastPlayed > 0 && hideBackToHistoryTimer == null) {
151
+ // showBackToHistory = true
152
+ // hideBackToHistoryTimer = countDownTimer(5000, 1000, "hideBackToHistoryTimer") {
153
+ // showBackToHistory = false
154
+ // hideBackToHistoryTimer = null
155
+ // playerViewModel.lastPlayed = 0
156
+ // }
157
+ // }
158
+ }
159
+
160
+ override fun onPause () {
161
+ println (" onPause" )
162
+ println (" pause danmaku player 1" )
163
+ mDanmakuPlayer?.pause()
164
+ isPlaying = false
165
+ }
166
+
167
+ override fun onBuffering () {
168
+ println (" onBuffering" )
169
+ isBuffering = true
170
+ println (" pause danmaku player 2" )
171
+ mDanmakuPlayer?.pause()
172
+ }
173
+
174
+ override fun onEnd () {
175
+ println (" onEnd" )
176
+ println (" pause danmaku player 3" )
177
+ mDanmakuPlayer?.pause()
178
+ isPlaying = false
179
+ // if (!Prefs.incognitoMode) sendHeartbeat()
180
+
181
+ // val videoListIndex = playerViewModel.availableVideoList.indexOfFirst {
182
+ // it.cid == playerViewModel.currentCid
183
+ // }
184
+ // if (videoListIndex + 1 < playerViewModel.availableVideoList.size) {
185
+ // val nextVideo = playerViewModel.availableVideoList[videoListIndex + 1]
186
+ // logger.info { "Play next video: $nextVideo" }
187
+ // playerViewModel.partTitle = nextVideo.title
188
+ // playerViewModel.loadPlayUrl(
189
+ // avid = nextVideo.aid,
190
+ // cid = nextVideo.cid,
191
+ // epid = nextVideo.epid,
192
+ // seasonId = nextVideo.seasonId,
193
+ // continuePlayNext = true
194
+ // )
195
+ // }
196
+ }
197
+
198
+ override fun onIdle () {
199
+ println (" onIdle" )
200
+ println (" pause danmaku player 4" )
201
+ mDanmakuPlayer?.pause()
202
+ }
203
+
204
+ override fun onSeekBack (seekBackIncrementMs : Long ) {
205
+ mDanmakuPlayer?.seekTo(currentTime)
206
+ }
207
+
208
+ override fun onSeekForward (seekForwardIncrementMs : Long ) {
209
+ mDanmakuPlayer?.seekTo(currentTime)
210
+ }
211
+
107
212
}
108
213
109
214
LaunchedEffect (Unit ) {
@@ -113,42 +218,6 @@ fun BvPlayer(
113
218
}
114
219
}
115
220
116
- SideEffect {
117
- videoPlayer.addListener(object : Player .Listener {
118
- override fun onIsPlayingChanged (playing : Boolean ) {
119
- isPlaying = playing
120
- if (isPlaying) {
121
- danmakuPlayer.start()
122
- } else {
123
- danmakuPlayer.pause()
124
- }
125
- }
126
-
127
- override fun onPlaybackStateChanged (playbackState : Int ) {
128
- when (playbackState) {
129
- Player .STATE_READY -> {
130
- initDanmakuConfig()
131
- danmakuPlayer.seekTo(videoPlayer.currentPosition)
132
- if (! isPlaying) danmakuPlayer.pause()
133
- }
134
-
135
- Player .STATE_ENDED -> danmakuPlayer.pause()
136
- Player .STATE_IDLE -> {}
137
- Player .STATE_BUFFERING -> danmakuPlayer.pause()
138
- else -> danmakuPlayer.pause()
139
- }
140
- }
141
-
142
- override fun onPlayWhenReadyChanged (playWhenReady : Boolean , reason : Int ) {
143
- if (playWhenReady) {
144
- danmakuPlayer.start()
145
- } else {
146
- danmakuPlayer.pause()
147
- }
148
- }
149
- })
150
- }
151
-
152
221
BvPlayerController (
153
222
modifier = modifier,
154
223
isPlaying = isPlaying,
@@ -168,11 +237,15 @@ fun BvPlayer(
168
237
onEnterFullScreen = onEnterFullScreen,
169
238
onExitFullScreen = onExitFullScreen,
170
239
onBack = onBack,
171
- onPlay = { videoPlayer.play () },
240
+ onPlay = { videoPlayer.start () },
172
241
onPause = { videoPlayer.pause() },
173
- onSeekToPosition = videoPlayer::seekTo,
242
+ onSeekToPosition = { position ->
243
+ mDanmakuPlayer?.seekTo(position)
244
+ mDanmakuPlayer?.pause()
245
+ videoPlayer.seekTo(position)
246
+ },
174
247
onChangeResolution = onChangeResolution,
175
- onChangeSpeed = videoPlayer::setPlaybackSpeed ,
248
+ onChangeSpeed = { videoPlayer.speed = it } ,
176
249
onToggleDanmaku = {
177
250
enabledDanmaku = ! enabledDanmaku
178
251
toggleDanmakuEnabled(enabledDanmaku)
@@ -189,12 +262,13 @@ fun BvPlayer(
189
262
},
190
263
onDanmakuAreaChange = onDanmakuAreaChange
191
264
) {
192
- Media3VideoPlayer (videoPlayer = videoPlayer)
265
+ // Media3VideoPlayer(videoPlayer = videoPlayer)
266
+ BvVideoPlayer (videoPlayer = videoPlayer, playerListener = videoPlayerListener)
193
267
AkDanmakuPlayer (
194
268
modifier = Modifier
195
269
.alpha(mobileVideoPlayerData.currentDanmakuOpacity)
196
270
.fillMaxHeight(mobileVideoPlayerData.currentDanmakuArea),
197
- danmakuPlayer = danmakuPlayer
271
+ danmakuPlayer = mDanmakuPlayer
198
272
)
199
273
}
200
274
}
0 commit comments