|
|
@@ -519,11 +519,11 @@ export default {
|
|
|
shouldRenderPlayer() {
|
|
|
// 参考 live-room.nvue:
|
|
|
// v-if="(state == 1 || (state == 2 && playUrl)) && !isPlayStopped"
|
|
|
- // 直播中即使 playUrl 暂时为空也要把容器挂上,让 <video> 后续能感知 src 变化;
|
|
|
- // 回放必须有 url;付费遮罩存在时不渲染播放器。
|
|
|
+ // 付费遮罩 / 尚无拉流地址时不挂播放器,避免空壳盖住封面变成黑屏
|
|
|
if (this.paywallOn) return false
|
|
|
+ if (!this.streamSrc) return false
|
|
|
if (this.sessionPhase === 'onair') return true
|
|
|
- if (this.sessionPhase === 'replay' && !!this.streamSrc) return true
|
|
|
+ if (this.sessionPhase === 'replay') return true
|
|
|
return false
|
|
|
},
|
|
|
pagerEnabled() {
|
|
|
@@ -1041,6 +1041,11 @@ export default {
|
|
|
this.paywallOn = false
|
|
|
this.paywallCoverReady = false
|
|
|
this.seedPosterFromFeed()
|
|
|
+ // 与详情并行拉取试看秒数,付费房据此决定锁屏 / 开播(-1=无限)
|
|
|
+ const trialPromise = pullTrialSeconds(this.roomKey).catch((err) => {
|
|
|
+ if (appSettings.debug) console.warn('[live] pullTrialSeconds failed', err)
|
|
|
+ return null
|
|
|
+ })
|
|
|
let detail = null
|
|
|
try {
|
|
|
detail = await pullBroadcastDetail(this.roomKey)
|
|
|
@@ -1094,18 +1099,9 @@ export default {
|
|
|
console.log('[LIVE-DIAG] platform =', this.platformLabel)
|
|
|
|
|
|
this.streamArchive = url
|
|
|
- const paidAmount = Number(detail && detail.paid_money) || 0
|
|
|
- // 付费未解锁:进房立刻锁屏,避免先出画面再等 getLastTime 才遮罩
|
|
|
- if (paidAmount > 0 && !this.unlocked) {
|
|
|
- this.paywallCoverReady = false
|
|
|
- this.paywallOn = true
|
|
|
- this.streamSrc = ''
|
|
|
- } else {
|
|
|
- this.paywallOn = false
|
|
|
- this.streamSrc = url || ''
|
|
|
- }
|
|
|
- // 强制让 <stream-player> 重新挂载,等价源代码 onShow 里 `playComponentKey = Date.now()`,
|
|
|
- // 解决 nvue + weex video 在 src 由空变非空时偶发不自动 reload 的问题。
|
|
|
+ // 先不拉流:等 getLastTime,避免已解锁闪锁 / 未解锁先裸播
|
|
|
+ this.streamSrc = ''
|
|
|
+ this.paywallOn = false
|
|
|
this.playerRenderToken += 1
|
|
|
this.lastDetailSnap = {
|
|
|
state: detail && detail.state,
|
|
|
@@ -1115,12 +1111,29 @@ export default {
|
|
|
src: this.streamSrc
|
|
|
}
|
|
|
console.log('=== [LIVE-DIAG] banner snap ===', this.lastDetailSnap)
|
|
|
- console.log('=== [LIVE-DIAG] shouldRenderPlayer =', this.shouldRenderPlayer, ' paywallOn =', this.paywallOn)
|
|
|
|
|
|
- // 试看检测不阻塞进房;付费房已先锁屏,有剩余试看时再放开
|
|
|
- this.setupTrial().catch((err) => {
|
|
|
- console.warn('[LIVE-DIAG] setupTrial failed', err)
|
|
|
- })
|
|
|
+ const paidAmount = Number(detail && detail.paid_money) || 0
|
|
|
+ try {
|
|
|
+ const sec = await trialPromise
|
|
|
+ console.log('[LIVE-DIAG] getLastTime last_time =', sec, ' paid_money =', paidAmount)
|
|
|
+ this.applyTrialSeconds(sec, { paidAmount })
|
|
|
+ } catch (err) {
|
|
|
+ console.warn('[LIVE-DIAG] applyTrialSeconds failed', err)
|
|
|
+ if (paidAmount > 0 && !this.unlocked) {
|
|
|
+ this.triggerPaywall()
|
|
|
+ } else {
|
|
|
+ this.releasePaywallForTrial()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ console.log(
|
|
|
+ '=== [LIVE-DIAG] shouldRenderPlayer =',
|
|
|
+ this.shouldRenderPlayer,
|
|
|
+ ' paywallOn =',
|
|
|
+ this.paywallOn,
|
|
|
+ ' streamSrc=',
|
|
|
+ !!this.streamSrc
|
|
|
+ )
|
|
|
+
|
|
|
this.resetGiftUiState()
|
|
|
this.$nextTick(() => {
|
|
|
this.$refs.chatPanel?.reset?.()
|
|
|
@@ -1163,48 +1176,79 @@ export default {
|
|
|
} catch (_) {}
|
|
|
},
|
|
|
async setupTrial() {
|
|
|
- if (this.unlocked) return
|
|
|
+ if (this.unlocked) {
|
|
|
+ this.releasePaywallForTrial()
|
|
|
+ return
|
|
|
+ }
|
|
|
let sec
|
|
|
try {
|
|
|
sec = await pullTrialSeconds(this.roomKey)
|
|
|
} catch (err) {
|
|
|
if (appSettings.debug) console.warn('[live] pullTrialSeconds failed', err)
|
|
|
- // 接口失败:付费房保持/打开锁屏,避免裸播
|
|
|
- if ((Number(this.session.paid_money) || 0) > 0 && !this.unlocked) {
|
|
|
- this.triggerPaywall()
|
|
|
- }
|
|
|
+ sec = null
|
|
|
+ }
|
|
|
+ this.applyTrialSeconds(sec)
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 按 getLastTime 结果处理:
|
|
|
+ * -1 => 无限播放(免费或已解锁)
|
|
|
+ * >0 => 试看倒计时
|
|
|
+ * <=0 => 付费锁屏
|
|
|
+ */
|
|
|
+ applyTrialSeconds(sec, opts = {}) {
|
|
|
+ const paidAmount =
|
|
|
+ opts.paidAmount != null
|
|
|
+ ? Number(opts.paidAmount) || 0
|
|
|
+ : Number(this.session && this.session.paid_money) || 0
|
|
|
+
|
|
|
+ if (this.unlocked) {
|
|
|
+ this.releasePaywallForTrial()
|
|
|
return
|
|
|
}
|
|
|
- // -1:免费全场
|
|
|
- if (sec === -1) {
|
|
|
+
|
|
|
+ let n = sec
|
|
|
+ if (n !== null && n !== undefined && n !== '') {
|
|
|
+ n = Number(n)
|
|
|
+ if (Number.isNaN(n)) n = null
|
|
|
+ } else {
|
|
|
+ n = null
|
|
|
+ }
|
|
|
+
|
|
|
+ this.trialClock?.stop()
|
|
|
+
|
|
|
+ // -1:无限播放
|
|
|
+ if (n === -1) {
|
|
|
+ this.unlocked = true
|
|
|
this.releasePaywallForTrial()
|
|
|
return
|
|
|
}
|
|
|
- if (sec == null) {
|
|
|
- if ((Number(this.session.paid_money) || 0) > 0 && !this.unlocked) {
|
|
|
+
|
|
|
+ if (n == null) {
|
|
|
+ if (paidAmount > 0) {
|
|
|
this.triggerPaywall()
|
|
|
+ } else {
|
|
|
+ this.releasePaywallForTrial()
|
|
|
}
|
|
|
return
|
|
|
}
|
|
|
- this.trialClock?.stop()
|
|
|
+
|
|
|
this.trialClock = new TrialMeter(() => this.triggerPaywall())
|
|
|
- if (sec <= 0) {
|
|
|
+ if (n <= 0) {
|
|
|
this.triggerPaywall()
|
|
|
return
|
|
|
}
|
|
|
- // 仍有试看:关锁屏、开播并倒计时
|
|
|
+ // 仍有试看
|
|
|
this.releasePaywallForTrial()
|
|
|
- this.trialClock.start(sec)
|
|
|
+ this.trialClock.start(n)
|
|
|
},
|
|
|
- /** 有试看时长时放开锁屏并恢复拉流 */
|
|
|
+ /** 关锁屏并恢复拉流(强制 remount,避免 nvue 空 src 挂载后黑屏) */
|
|
|
releasePaywallForTrial() {
|
|
|
- if (this.unlocked) return
|
|
|
this.paywallOn = false
|
|
|
- const url = this.streamArchive || resolvePlaybackUrl(this.session)
|
|
|
- if (!url) return
|
|
|
- if (this.streamSrc !== url) {
|
|
|
- this.streamSrc = url
|
|
|
- this.playerRenderToken += 1
|
|
|
+ const url = this.streamArchive || resolvePlaybackUrl(this.session) || ''
|
|
|
+ this.streamSrc = url
|
|
|
+ this.playerRenderToken += 1
|
|
|
+ if (!url) {
|
|
|
+ console.warn('[LIVE-DIAG] releasePaywallForTrial: empty stream url')
|
|
|
}
|
|
|
},
|
|
|
triggerPaywall() {
|
|
|
@@ -1351,15 +1395,15 @@ export default {
|
|
|
},
|
|
|
/** 解锁成功后恢复播放(本工程不整页 redirect) */
|
|
|
resumeAfterUnlock() {
|
|
|
- this.unlocked = true
|
|
|
- this.paywallOn = false
|
|
|
+ this.unlocked = true
|
|
|
+ this.paywallOn = false
|
|
|
this.showLivePayPopup = false
|
|
|
this.showInsufficientBalanceModal = false
|
|
|
this.trialClock?.stop()
|
|
|
const url = this.streamArchive || resolvePlaybackUrl(this.session)
|
|
|
this.streamSrc = url || ''
|
|
|
this.playerRenderToken += 1
|
|
|
- this.sessionPhase = describeRoomPhase(this.session.state)
|
|
|
+ this.sessionPhase = describeRoomPhase(this.session.state)
|
|
|
},
|
|
|
/** @deprecated 保留旧入口名,避免残留引用 */
|
|
|
confirmUnlock() {
|