优化画中画模式支持,添加播放器释放逻辑,修复相关引用管理

This commit is contained in:
2026-01-28 17:17:05 +08:00
parent a0b677df5e
commit 3c8383ee67
3 changed files with 46 additions and 1 deletions

Binary file not shown.

View File

@@ -201,6 +201,7 @@ class FeatureHubActivity : AppCompatActivity() {
} }
private fun handleAliveItemClick(item: AliveStreamItem) { private fun handleAliveItemClick(item: AliveStreamItem) {
LivePlayActivity.closePipIfAny()
val url = item.url?.trim().orEmpty() val url = item.url?.trim().orEmpty()
val intent = if (url.isNotEmpty()) { val intent = if (url.isNotEmpty()) {
LivePlayActivity.createIntent( LivePlayActivity.createIntent(

View File

@@ -55,6 +55,7 @@ import kotlinx.coroutines.launch
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
import java.lang.ref.WeakReference
class LivePlayActivity : AppCompatActivity() { class LivePlayActivity : AppCompatActivity() {
@@ -80,6 +81,7 @@ class LivePlayActivity : AppCompatActivity() {
private var firstAudioFrameCostMs: Long? = null private var firstAudioFrameCostMs: Long? = null
private var isLatencyChasingActive: Boolean = false private var isLatencyChasingActive: Boolean = false
private var lastLatencyChasingSpeed: Float? = null private var lastLatencyChasingSpeed: Float? = null
private var hasReleasedPlayer: Boolean = false
private val logLines: ArrayDeque<String> = ArrayDeque() private val logLines: ArrayDeque<String> = ArrayDeque()
private val logTimeFormat = SimpleDateFormat("HH:mm:ss.SSS", Locale.getDefault()) private val logTimeFormat = SimpleDateFormat("HH:mm:ss.SSS", Locale.getDefault())
@@ -209,9 +211,12 @@ class LivePlayActivity : AppCompatActivity() {
logEvent("释放播放器") logEvent("释放播放器")
logDialog?.dismiss() logDialog?.dismiss()
if (this::playerClient.isInitialized) { if (this::playerClient.isInitialized) {
playerClient.release() releasePlayerIfNeeded()
} }
uiScope.cancel() uiScope.cancel()
if (pipActivityRef?.get() === this) {
pipActivityRef = null
}
} }
override fun onStop() { override fun onStop() {
@@ -228,6 +233,11 @@ class LivePlayActivity : AppCompatActivity() {
override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean, newConfig: Configuration) { override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean, newConfig: Configuration) {
super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig) super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
updatePipUi(isInPictureInPictureMode) updatePipUi(isInPictureInPictureMode)
if (isInPictureInPictureMode) {
pipActivityRef = WeakReference(this)
} else if (pipActivityRef?.get() === this) {
pipActivityRef = null
}
} }
private fun togglePlay() { private fun togglePlay() {
@@ -258,6 +268,20 @@ class LivePlayActivity : AppCompatActivity() {
pipController.enterPictureInPictureMode(renderView) pipController.enterPictureInPictureMode(renderView)
} }
private fun releasePlayerIfNeeded() {
if (hasReleasedPlayer) return
hasReleasedPlayer = true
playerClient.release()
}
private fun finishForNewPlayback() {
logEvent("外部请求: 结束画中画播放")
if (this::playerClient.isInitialized) {
releasePlayerIfNeeded()
}
finish()
}
private fun startPlayback() { private fun startPlayback() {
val env = envStore.read() val env = envStore.read()
args.playParams?.let { params -> args.playParams?.let { params ->
@@ -706,6 +730,8 @@ class LivePlayActivity : AppCompatActivity() {
companion object { companion object {
private const val TAG = "LivePlayActivity" private const val TAG = "LivePlayActivity"
private const val MAX_LOG_LINES = 200 private const val MAX_LOG_LINES = 200
@Volatile
private var pipActivityRef: WeakReference<LivePlayActivity>? = null
const val EXTRA_PLAY_PROTOCOL = "play_protocol" const val EXTRA_PLAY_PROTOCOL = "play_protocol"
const val EXTRA_STREAM_ID_OR_URL = "stream_id_or_url" const val EXTRA_STREAM_ID_OR_URL = "stream_id_or_url"
const val EXTRA_PLAY_VHOST = "play_vhost" const val EXTRA_PLAY_VHOST = "play_vhost"
@@ -741,6 +767,24 @@ class LivePlayActivity : AppCompatActivity() {
.putExtra(EXTRA_PLAY_STREAM_NAME, streamName) .putExtra(EXTRA_PLAY_STREAM_NAME, streamName)
.putExtra(EXTRA_AUTO_START, autoStart) .putExtra(EXTRA_AUTO_START, autoStart)
} }
fun closePipIfAny(): Boolean {
val activity = pipActivityRef?.get() ?: return false
if (activity.isDestroyed || activity.isFinishing) {
pipActivityRef = null
return false
}
if (!activity.isInPictureInPictureMode) {
pipActivityRef = null
return false
}
if (Looper.myLooper() == Looper.getMainLooper()) {
activity.finishForNewPlayback()
} else {
activity.runOnUiThread { activity.finishForNewPlayback() }
}
return true
}
} }
private fun resolveChannelId(input: String): String { private fun resolveChannelId(input: String): String {