Cleanup added logs

This commit is contained in:
tapframe 2026-06-08 22:20:26 +05:30
parent a0af6ab07e
commit cf2b7459f9
3 changed files with 7 additions and 372 deletions

View file

@ -256,45 +256,6 @@ internal fun PlayerScreenRuntime.RenderPlayerRuntimeUi() {
openingMessage = p2pInitialLoadingMessage,
openingProgress = p2pInitialLoadingProgress,
)
val desktopControlsReadinessSignature = listOf(
playerSurfaceSourceUrl != null,
title.isNotBlank(),
episodeText.isNotBlank(),
activeStreamTitle.isNotBlank(),
activeProviderName.isNotBlank(),
openingOverlayWanted,
playbackSnapshot.isLoading,
initialLoadCompleted,
errorMessage != null,
background != null || poster != null,
logo != null,
p2pInitialLoadingMessage != null,
p2pInitialLoadingProgress != null,
).joinToString("|")
LaunchedEffect(isDesktop, desktopControlsReadinessSignature) {
if (!isDesktop) return@LaunchedEffect
println(
"[NuvioDesktopPlayerHandoff] compose controls " +
"sourceReady=${playerSurfaceSourceUrl != null} " +
"titleReady=${title.isNotBlank()} titleLen=${title.length} " +
"episodeReady=${episodeText.isNotBlank()} " +
"streamReady=${activeStreamTitle.isNotBlank()} streamLen=${activeStreamTitle.length} " +
"providerReady=${activeProviderName.isNotBlank()} providerLen=${activeProviderName.length} " +
"openingWanted=$openingOverlayWanted nativeLoading=${playbackSnapshot.isLoading} " +
"initialLoadCompleted=$initialLoadCompleted error=${errorMessage != null} " +
"artwork=${background != null || poster != null} logo=${logo != null} " +
"p2pMessage=${p2pInitialLoadingMessage != null} p2pProgress=${p2pInitialLoadingProgress != null}",
)
}
LaunchedEffect(isDesktop, playerSurfaceSourceUrl) {
if (isDesktop) {
println(
"[NuvioDesktopPlayerHandoff] surface source " +
"ready=${playerSurfaceSourceUrl != null} " +
"mode=${if (isP2pPlaybackActive) "p2p" else "direct"}",
)
}
}
val gestureCallbacks = rememberSurfaceGestureCallbacks()
Box(
@ -349,34 +310,10 @@ internal fun PlayerScreenRuntime.RenderPlayerRuntimeUi() {
true
},
onControllerReady = { controller ->
if (isDesktop) {
println(
"[NuvioDesktopPlayerHandoff] controller ready " +
"titleReady=${title.isNotBlank()} streamReady=${activeStreamTitle.isNotBlank()}",
)
}
playerController = controller
playerControllerSourceUrl = activeSourceUrl
},
onSnapshot = { snapshot ->
val previousSnapshot = playbackSnapshot
if (
isDesktop &&
(
previousSnapshot.isLoading != snapshot.isLoading ||
previousSnapshot.isPlaying != snapshot.isPlaying ||
(previousSnapshot.durationMs <= 0L && snapshot.durationMs > 0L) ||
previousSnapshot.isEnded != snapshot.isEnded
)
) {
println(
"[NuvioDesktopPlayerHandoff] snapshot " +
"loading=${snapshot.isLoading} wasLoading=${previousSnapshot.isLoading} " +
"playing=${snapshot.isPlaying} durationMs=${snapshot.durationMs} " +
"positionMs=${snapshot.positionMs} ended=${snapshot.isEnded} " +
"initialLoadCompletedBefore=$initialLoadCompleted",
)
}
playbackSnapshot = snapshot
if (!snapshot.isLoading) initialLoadCompleted = true
if (snapshot.isEnded) {
@ -549,17 +486,14 @@ private fun PlayerScreenRuntime.handlePlayerControlsAction(action: PlayerControl
args.onBack()
}
PlayerControlsAction.TogglePlayback -> {
println("[NuvioPlayerControls] action toggle route=native-fallback")
prepareTogglePlaybackForNativeFallback()
return false
}
PlayerControlsAction.SeekBack -> {
println("[NuvioPlayerControls] action seekBack route=native-fallback")
prepareSeekByForNativeFallback(-10_000L)
return false
}
PlayerControlsAction.SeekForward -> {
println("[NuvioPlayerControls] action seekForward route=native-fallback")
prepareSeekByForNativeFallback(10_000L)
return false
}
@ -574,7 +508,6 @@ private fun PlayerScreenRuntime.handlePlayerControlsAction(action: PlayerControl
showAudioModal = true
}
PlayerControlsAction.Sources -> {
println("[NuvioPlayerControls] action sources")
prepareSourcesForPlayerControls()
}
PlayerControlsAction.Episodes -> {
@ -594,12 +527,10 @@ private fun PlayerScreenRuntime.handlePlayerControlsAction(action: PlayerControl
}
}
PlayerControlsAction.DoubleTapSeekBack -> {
println("[NuvioPlayerControls] action doubleTapSeekBack route=native-fallback")
prepareDoubleTapSeekForNativeFallback(PlayerSeekDirection.Backward)
return false
}
PlayerControlsAction.DoubleTapSeekForward -> {
println("[NuvioPlayerControls] action doubleTapSeekForward route=native-fallback")
prepareDoubleTapSeekForNativeFallback(PlayerSeekDirection.Forward)
return false
}
@ -610,15 +541,10 @@ private fun PlayerScreenRuntime.handlePlayerControlsAction(action: PlayerControl
private fun PlayerScreenRuntime.handlePlayerControlsEvent(type: String, value: Double): Boolean {
when (type) {
"reloadSources" -> {
println("[NuvioPlayerControls] event reloadSources")
prepareSourcesForPlayerControls(forceRefresh = true)
}
"selectSource" -> {
val streams = sourceStreamsState.groups.flatMap { it.streams }
println(
"[NuvioPlayerControls] event selectSource index=${value.toInt()} " +
"available=${streams.size} ${sourceStreamsState.playerControlsStreamsSummary()}",
)
val stream = streams.getOrNull(value.toInt()) ?: return true
if (requestP2pConsentForPlayerControls(stream = stream, episode = null)) return true
switchToSource(stream)
@ -780,18 +706,9 @@ private fun PlayerScreenRuntime.enableP2pForPlayerControls() {
private fun PlayerScreenRuntime.prepareSourcesForPlayerControls(forceRefresh: Boolean = false) {
val vid = activeVideoId
if (vid == null) {
println(
"[NuvioPlayerControls] loadSources ignored reason=no-active-video " +
"type=${contentType ?: parentMetaType} parent=$parentMetaId force=$forceRefresh",
)
return
}
val requestType = contentType ?: parentMetaType
println(
"[NuvioPlayerControls] loadSources request type=$requestType id=$vid " +
"season=$activeSeasonNumber episode=$activeEpisodeNumber force=$forceRefresh " +
"before=${sourceStreamsState.playerControlsStreamsSummary()}",
)
PlayerStreamsRepository.loadSources(
type = requestType,
videoId = vid,
@ -824,14 +741,6 @@ private fun PlayerScreenRuntime.requestEpisodeStreamsForPlayerControls(
episodeStreamsPanelState = EpisodeStreamsPanelState(showStreams = true, selectedEpisode = episode)
}
private fun com.nuvio.app.features.streams.StreamsUiState.playerControlsStreamsSummary(): String {
val streams = groups.sumOf { it.streams.size }
val loadingGroups = groups.count { it.isLoading }
val errorGroups = groups.count { !it.error.isNullOrBlank() }
return "groups=${groups.size} streams=$streams isAnyLoading=$isAnyLoading " +
"loadingGroups=$loadingGroups errorGroups=$errorGroups empty=${emptyStateReason ?: "none"}"
}
private fun PlayerScreenRuntime.submitIntroFromPlayerControls() {
if (isSubmitIntroSubmitting) return
val imdbId = activeSubmitIntroImdbId()

View file

@ -38,8 +38,6 @@ internal class NativePlayerController(
private var pendingSource: PendingSource? = null
private var controlsState = PlayerControlsState()
private var lastSentControlsStructureKey: PlayerControlsState? = null
private var lastSourceControlsDiagnostics: String? = null
private var lastPlayerControlsDiagnostics: String? = null
private var onAction: (PlayerControlsAction) -> Boolean = { false }
private var onEvent: (String, Double) -> Boolean = { _, _ -> false }
private var onScrubChange: (Long) -> Boolean = { false }
@ -57,11 +55,6 @@ internal class NativePlayerController(
initialPositionMs: Long,
onError: (String?) -> Unit,
) {
println(
"[NuvioDesktopControls] attach requested " +
"source=${sourceUrl.redactedPlaybackSourceForLog()} " +
"headers=${sourceHeaders.size} playWhenReady=$playWhenReady initialPositionMs=$initialPositionMs",
)
val pending = PendingSource(
sourceUrl = sourceUrl,
headerLines = sourceHeaders.toHeaderLines(),
@ -80,19 +73,10 @@ internal class NativePlayerController(
val pending = pendingSource ?: return
SwingUtilities.invokeLater {
if (!host.isDisplayable) {
println(
"[NuvioDesktopControls] attach pending " +
"hostDisplayable=false source=${pending.sourceUrl.redactedPlaybackSourceForLog()}",
)
return@invokeLater
}
dispose()
runCatching {
println(
"[NuvioDesktopControls] create native player " +
"source=${pending.sourceUrl.redactedPlaybackSourceForLog()} " +
"headers=${pending.headerLines.size} initialPositionMs=${pending.initialPositionMs}",
)
val hostViewPtr = AwtNativeViewResolver.resolveNativeViewPointer(host)
handle = NativePlayerBridge.create(
hostViewPtr = hostViewPtr,
@ -104,16 +88,8 @@ internal class NativePlayerController(
eventSink = eventSink,
)
if (handle == 0L) error("Native player did not return a handle.")
println(
"[NuvioDesktopControls] create native player success " +
"handleReady=true source=${pending.sourceUrl.redactedPlaybackSourceForLog()}",
)
updateControls(controlsState)
}.onFailure { error ->
println(
"[NuvioDesktopControls] create native player failed " +
"source=${pending.sourceUrl.redactedPlaybackSourceForLog()} error=${error.message}",
)
pending.onError(error.message)
}
}
@ -135,29 +111,10 @@ internal class NativePlayerController(
controlsState = state
val currentHandle = handle
val structureKey = state.nativeControlsStructureKey()
val willSend = currentHandle != 0L && structureKey != lastSentControlsStructureKey
val sourceDiagnostics = state.sourceControlsDiagnostics()
if (sourceDiagnostics != lastSourceControlsDiagnostics) {
println("[NuvioDesktopControls] state handleReady=${currentHandle != 0L} willSend=$willSend $sourceDiagnostics")
lastSourceControlsDiagnostics = sourceDiagnostics
}
val playerDiagnostics = state.playerControlsDiagnostics()
if (playerDiagnostics != lastPlayerControlsDiagnostics) {
println(
"[NuvioDesktopControls] controls handleReady=${currentHandle != 0L} " +
"willSend=$willSend changed=${structureKey != lastSentControlsStructureKey} $playerDiagnostics",
)
lastPlayerControlsDiagnostics = playerDiagnostics
}
val current = currentHandle.takeIf { it != 0L } ?: return
if (structureKey == lastSentControlsStructureKey) return
lastSentControlsStructureKey = structureKey
val controlsJson = state.toControlsJson()
println(
"[NuvioDesktopControls] controls send " +
"jsonBytes=${controlsJson.length} $playerDiagnostics",
)
NativePlayerBridge.updateControls(current, controlsJson)
NativePlayerBridge.updateControls(current, state.toControlsJson())
}
fun setResizeMode(mode: PlayerResizeMode) {
@ -174,10 +131,6 @@ internal class NativePlayerController(
}
private fun handlePlayerEvent(type: String, value: Double) {
val shouldLog = type.isControlsDiagnosticEvent()
if (shouldLog) {
println("[NuvioDesktopControls] event received type=$type value=$value")
}
when (type) {
"scrubChange" -> {
if (!onScrubChange(value.toLong())) {
@ -186,31 +139,16 @@ internal class NativePlayerController(
}
"scrubFinish" -> {
val scrubHandled = onScrubFinished(value.toLong())
if (shouldLog) {
println(
"[NuvioDesktopControls] event route type=$type " +
"onScrubFinished=$scrubHandled fallback=${!scrubHandled}",
)
}
if (!scrubHandled) {
seekTo(value.toLong())
}
}
else -> {
val eventHandled = onEvent(type, value)
if (shouldLog) {
println("[NuvioDesktopControls] event route type=$type onEvent=$eventHandled")
}
if (eventHandled) return
val action = type.toPlayerControlsAction()
if (shouldLog) {
println("[NuvioDesktopControls] event map type=$type action=${action ?: "none"}")
}
if (action == null) return
val actionHandled = onAction(action)
if (shouldLog) {
println("[NuvioDesktopControls] event action=$action onAction=$actionHandled fallback=${!actionHandled}")
}
if (!actionHandled) {
handleFallbackAction(action)
}
@ -227,16 +165,9 @@ internal class NativePlayerController(
when (action) {
PlayerControlsAction.TogglePlayback -> {
val current = handle
if (current == 0L) {
println("[NuvioDesktopControls] fallback direct action=$action handleReady=false")
return
}
if (current == 0L) return
val isEnded = NativePlayerBridge.isEnded(current)
val isPaused = NativePlayerBridge.isPaused(current)
println(
"[NuvioDesktopControls] fallback direct action=$action " +
"handleReady=true ended=$isEnded paused=$isPaused",
)
if (isEnded) {
NativePlayerBridge.seekTo(current, 0L)
NativePlayerBridge.setPaused(current, false)
@ -244,21 +175,17 @@ internal class NativePlayerController(
NativePlayerBridge.setPaused(current, !isPaused)
}
}
PlayerControlsAction.SeekBack -> fallbackSeekBy(action, -10_000L)
PlayerControlsAction.SeekForward -> fallbackSeekBy(action, 10_000L)
PlayerControlsAction.DoubleTapSeekBack -> fallbackSeekBy(action, -10_000L)
PlayerControlsAction.DoubleTapSeekForward -> fallbackSeekBy(action, 10_000L)
PlayerControlsAction.SeekBack -> fallbackSeekBy(-10_000L)
PlayerControlsAction.SeekForward -> fallbackSeekBy(10_000L)
PlayerControlsAction.DoubleTapSeekBack -> fallbackSeekBy(-10_000L)
PlayerControlsAction.DoubleTapSeekForward -> fallbackSeekBy(10_000L)
PlayerControlsAction.Speed -> cycleFallbackSpeed()
else -> Unit
}
}
private fun fallbackSeekBy(action: PlayerControlsAction, offsetMs: Long) {
private fun fallbackSeekBy(offsetMs: Long) {
val current = handle
println(
"[NuvioDesktopControls] fallback direct action=$action " +
"handleReady=${current != 0L} offsetMs=$offsetMs",
)
if (current != 0L) {
NativePlayerBridge.seekBy(current, offsetMs)
}
@ -521,25 +448,6 @@ private fun String.toPlayerControlsAction(): PlayerControlsAction? =
else -> null
}
private fun String.isControlsDiagnosticEvent(): Boolean =
when (this) {
"toggle",
"seekBack",
"seekForward",
"doubleTapSeekBack",
"doubleTapSeekForward",
"scrubFinish",
"sources",
"reloadSources",
"selectSource",
"episodes",
"reloadEpisodeStreams",
"selectEpisode",
"selectEpisodeStream",
"backToEpisodes" -> true
else -> false
}
private fun PlayerControlsState.toControlsJson(): String =
buildString {
append('{')
@ -781,46 +689,6 @@ private fun PlayerControlsState.nativeControlsStructureKey(): PlayerControlsStat
positionMs = 0L,
)
private fun PlayerControlsState.sourceControlsDiagnostics(): String {
val loadingFilters = sourceFilters.count { it.isLoading }
val errorFilters = sourceFilters.count { it.hasError }
val currentItems = sourceItems.count { it.isCurrent }
val disabledItems = sourceItems.count { !it.isEnabled }
val firstItem = sourceItems.firstOrNull()?.let { item ->
"${item.addonName}:${item.label}".replace('\n', ' ').take(96)
} ?: "none"
return "sources(show=$showSources loading=$sourceIsLoading filters=${sourceFilters.size} " +
"filterLoading=$loadingFilters filterErrors=$errorFilters items=${sourceItems.size} " +
"current=$currentItems disabled=$disabledItems first=$firstItem)"
}
private fun PlayerControlsState.playerControlsDiagnostics(): String {
val openingProgressLabel = openingProgress?.let { value ->
(value.coerceIn(0f, 1f) * 100).toInt().toString() + "%"
} ?: "none"
return "metadata(title=${title.isNotBlank()}:${title.length} " +
"episode=${episodeText.isNotBlank()}:${episodeText.length} " +
"stream=${streamTitle.isNotBlank()}:${streamTitle.length} " +
"provider=${providerName.isNotBlank()}:${providerName.length}) " +
"opening(wanted=$showOpeningOverlay artwork=${!openingArtwork.isNullOrBlank()} " +
"logo=${!openingLogo.isNullOrBlank()} title=${openingTitle.isNotBlank()}:${openingTitle.length} " +
"message=${!openingMessage.isNullOrBlank()} progress=$openingProgressLabel) " +
"playback(loading=$isLoading playing=$isPlaying controlsVisible=$controlsVisible locked=$isLocked)"
}
private fun String.redactedPlaybackSourceForLog(): String {
val schemeEnd = indexOf("://")
if (schemeEnd < 0) return "opaque"
val scheme = substring(0, schemeEnd)
if (scheme == "file") return "file://<local>"
val host = substring(schemeEnd + 3)
.substringBefore('/')
.substringBefore('?')
.takeIf { it.isNotBlank() }
?: "<host>"
return "$scheme://$host/<redacted>"
}
private fun StringBuilder.appendJsonField(name: String, value: String) {
append('"').append(name).append("\":")
append(value.toJsonString())

View file

@ -2032,50 +2032,13 @@
endTime: "00:00",
status: "",
};
let lastSourceControlsDiagnostic = "";
let lastMetadataDiagnostic = "";
let lastOpeningDiagnostic = "";
let lastNativeUpdateDiagnostic = "";
let lastControlsUpdateDiagnostic = "";
let playerNativeUpdateCount = 0;
let playerControlsUpdateCount = 0;
let hasReceivedPlayerControls = false;
const prefersReducedMotion = window.matchMedia &&
window.matchMedia("(prefers-reduced-motion: reduce)").matches;
const modalTransitionMs = prefersReducedMotion ? 1 : 240;
const diagnosticCommands = new Set([
"toggle",
"seekBack",
"seekForward",
"doubleTapSeekBack",
"doubleTapSeekForward",
"scrubFinish",
"sources",
"reloadSources",
"selectSource",
"episodes",
"reloadEpisodeStreams",
"selectEpisode",
"selectEpisodeStream",
"backToEpisodes",
]);
const postDiagnostic = message => {
const bridge = window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.player;
if (!bridge) return;
try {
bridge.postMessage({ type: "diagnostic", value: 0, message });
} catch (_) {
// Diagnostics must never break controls.
}
};
const send = (type, value = 0) => {
const bridge = window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.player;
if (diagnosticCommands.has(type)) {
postDiagnostic(`event type=${type} value=${value} activeModal=${activeModal || "none"}`);
}
if (bridge) bridge.postMessage({ type, value });
};
@ -2124,33 +2087,6 @@
return Number.isFinite(progress) ? Math.max(0, Math.min(1, progress)) : null;
};
const booleanFlag = value => Boolean(value) ? "1" : "0";
const textReadiness = text => {
const value = String(text || "");
return `${booleanFlag(value.trim())}:${value.length}`;
};
const progressReadiness = progress =>
progress === null ? "none" : `${Math.round(progress * 100)}%`;
const controlsReadinessDiagnostic = () => {
const progress = normalizedOpeningProgress();
return [
`title=${textReadiness(state.title)}`,
`episode=${textReadiness(state.episodeText)}`,
`stream=${textReadiness(state.streamTitle)}`,
`provider=${textReadiness(state.providerName)}`,
`openingWanted=${booleanFlag(state.showOpeningOverlay)}`,
`nativeLoading=${booleanFlag(state.isLoading)}`,
`artwork=${booleanFlag(state.openingArtwork)}`,
`logo=${booleanFlag(state.openingLogo)}`,
`openingTitle=${textReadiness(state.openingTitle)}`,
`message=${textReadiness(state.openingMessage)}`,
`progress=${progressReadiness(progress)}`,
].join(" ");
};
const rangePositionMs = () => {
const durationMs = Math.max(0, Number(state.durationMs) || 0);
return durationMs > 0 ? Math.round(durationMs * Number(seek.value) / 1000) : 0;
@ -2559,27 +2495,6 @@
container.appendChild(row);
};
const sourceControlsDiagnostic = controlsState => {
const filters = normalizeItems(controlsState.sourceFilters);
const items = normalizeItems(controlsState.sourceItems);
const loadingFilters = filters.filter(filter => Boolean(filter.isLoading)).length;
const errorFilters = filters.filter(filter => Boolean(filter.hasError)).length;
const currentItems = items.filter(item => Boolean(item.isCurrent)).length;
const disabledItems = items.filter(item => item.isEnabled === false).length;
return [
`activeModal=${activeModal || "none"}`,
`showSources=${Boolean(controlsState.showSources)}`,
`sourceLoading=${Boolean(controlsState.sourceIsLoading)}`,
`filters=${filters.length}`,
`filterLoading=${loadingFilters}`,
`filterErrors=${errorFilters}`,
`items=${items.length}`,
`current=${currentItems}`,
`disabled=${disabledItems}`,
`sourceFilter=${sourceFilterId || "all"}`,
].join(" ");
};
const renderSourceModal = () => {
sourcePanelTitle.textContent = state.sourcesPanelTitle || "Sources";
sourceReloadButton.textContent = state.reloadLabel || "Reload";
@ -2600,11 +2515,6 @@
items = items.filter(item => String(item.filterId || "") === sourceFilterId);
}
if (items.length === 0) {
postDiagnostic(
`render sources empty loading=${Boolean(state.sourceIsLoading)} ` +
`rawItems=${normalizeItems(state.sourceItems).length} filters=${filters.length} ` +
`sourceFilter=${sourceFilterId || "all"}`,
);
appendEmptyTrackState(
sourceList,
state.sourceIsLoading ? "Loading streams..." : (state.noStreamsLabel || "No streams found"),
@ -2824,21 +2734,6 @@
const titleText = String(state.openingTitle || state.title || "").trim();
const messageText = String(state.openingMessage || "").trim();
const showHorizontalProgress = hasProgress && !logoUrl;
const openingDiagnostic = [
`visible=${booleanFlag(showOpening)}`,
`wanted=${booleanFlag(wantsOpening)}`,
`bootstrap=${booleanFlag(openingBootstrap)}`,
`nativeLoading=${booleanFlag(state.isLoading)}`,
`artwork=${booleanFlag(artworkUrl)}`,
`logo=${booleanFlag(logoUrl)}`,
`title=${textReadiness(titleText)}`,
`message=${textReadiness(messageText)}`,
`progress=${progressReadiness(progress)}`,
].join(" ");
if (openingDiagnostic !== lastOpeningDiagnostic) {
lastOpeningDiagnostic = openingDiagnostic;
postDiagnostic(`opening ${openingDiagnostic}`);
}
root.classList.toggle("opening-active", showOpening);
openingOverlay.classList.toggle("visible", showOpening);
@ -2869,18 +2764,6 @@
root.classList.toggle("locked-visible", Boolean(state.isLocked && state.lockedOverlayVisible));
root.classList.toggle("chrome-hidden", Boolean(!state.controlsVisible && !(state.isLocked && state.lockedOverlayVisible)));
const showOpening = renderOpeningOverlay();
const metadataDiagnostic = [
`title=${textReadiness(state.title)}`,
`episode=${textReadiness(state.episodeText)}`,
`stream=${textReadiness(state.streamTitle)}`,
`provider=${textReadiness(state.providerName)}`,
`controlsVisible=${booleanFlag(state.controlsVisible)}`,
`locked=${booleanFlag(state.isLocked)}`,
].join(" ");
if (metadataDiagnostic !== lastMetadataDiagnostic) {
lastMetadataDiagnostic = metadataDiagnostic;
postDiagnostic(`metadata ${metadataDiagnostic}`);
}
title.textContent = state.title || "";
setText(episode, state.episodeText);
@ -3232,25 +3115,12 @@
});
window.playerUpdate = update => {
playerNativeUpdateCount += 1;
const durationMs = Math.round((Number(update.duration) || 0) * 1000);
const positionMs = Math.round((Number(update.position) || 0) * 1000);
const audioTracks = normalizeTracks(update.audioTracks);
const subtitleTracks = normalizeTracks(update.subtitleTracks);
const audioTracksChanged = trackListSignature(audioTracks) !== trackListSignature(state.audioTracks);
const subtitleTracksChanged = trackListSignature(subtitleTracks) !== trackListSignature(state.subtitleTracks);
const nativeUpdateDiagnostic = [
`loading=${booleanFlag(update.loading || update.isLoading)}`,
`paused=${booleanFlag(update.paused)}`,
`durationReady=${booleanFlag(durationMs > 0)}`,
`audioTracks=${audioTracks.length}`,
`subtitleTracks=${subtitleTracks.length}`,
`openingWanted=${booleanFlag(state.showOpeningOverlay)}`,
].join(" ");
if (nativeUpdateDiagnostic !== lastNativeUpdateDiagnostic) {
lastNativeUpdateDiagnostic = nativeUpdateDiagnostic;
postDiagnostic(`nativeUpdate #${playerNativeUpdateCount} ${nativeUpdateDiagnostic}`);
}
state = {
...state,
durationMs,
@ -3268,20 +3138,9 @@
};
window.playerControls = nextState => {
playerControlsUpdateCount += 1;
const previousCloseToken = Number(state.closeModalsToken) || 0;
state = { ...state, ...nextState };
hasReceivedPlayerControls = true;
const controlsUpdateDiagnostic = controlsReadinessDiagnostic();
if (controlsUpdateDiagnostic !== lastControlsUpdateDiagnostic) {
lastControlsUpdateDiagnostic = controlsUpdateDiagnostic;
postDiagnostic(`controlsUpdate #${playerControlsUpdateCount} ${controlsUpdateDiagnostic}`);
}
const sourceDiagnostic = sourceControlsDiagnostic(state);
if (sourceDiagnostic !== lastSourceControlsDiagnostic) {
lastSourceControlsDiagnostic = sourceDiagnostic;
postDiagnostic(`state ${sourceDiagnostic}`);
}
const closeToken = Number(state.closeModalsToken) || 0;
if (closeToken !== previousCloseToken) {
closePlayerModal();
@ -3332,7 +3191,6 @@
setProgress(0, 0);
focusShortcutRoot();
render();
postDiagnostic("controlsReady window.playerControls=1");
send("controlsReady", 0);
</script>
</body>