@sesionario/blocks 1.12.0 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +185 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +35 -2
- package/dist/index.d.ts +35 -2
- package/dist/index.js +184 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3462,6 +3462,20 @@ function kindForNative(input) {
|
|
|
3462
3462
|
if (code === MEDIA_ERR_NETWORK) return "unavailable";
|
|
3463
3463
|
return "generic";
|
|
3464
3464
|
}
|
|
3465
|
+
function describeAvResync(input) {
|
|
3466
|
+
const lag = Number.isFinite(input.lagSeconds) ? input.lagSeconds : 0;
|
|
3467
|
+
return {
|
|
3468
|
+
summary: `av-resync lag=${lag.toFixed(3)}s (non-fatal)`,
|
|
3469
|
+
kind: "resync",
|
|
3470
|
+
detail: {
|
|
3471
|
+
source: input.context.source,
|
|
3472
|
+
kind: "resync",
|
|
3473
|
+
fatal: false,
|
|
3474
|
+
reason: `presented frame lag ${lag.toFixed(3)}s`,
|
|
3475
|
+
context: input.context
|
|
3476
|
+
}
|
|
3477
|
+
};
|
|
3478
|
+
}
|
|
3465
3479
|
function describePlaybackError(input) {
|
|
3466
3480
|
if (input.source === "unsupported") {
|
|
3467
3481
|
return {
|
|
@@ -3520,6 +3534,10 @@ function describePlaybackError(input) {
|
|
|
3520
3534
|
// src/components/video/useHlsPlayback.ts
|
|
3521
3535
|
var RETRY_INTERVAL_MS = 3e3;
|
|
3522
3536
|
var MAX_MEDIA_ERROR_RETRIES = 5;
|
|
3537
|
+
var DRIFT_THRESHOLD_S = 0.4;
|
|
3538
|
+
var DRIFT_CONSECUTIVE_SAMPLES = 3;
|
|
3539
|
+
var RESYNC_COOLDOWN_MS = 1e4;
|
|
3540
|
+
var LIVE_EDGE_RESYNC_THRESHOLD_S = 8;
|
|
3523
3541
|
function useHlsPlayback({
|
|
3524
3542
|
src,
|
|
3525
3543
|
mode,
|
|
@@ -3559,6 +3577,7 @@ function useHlsPlayback({
|
|
|
3559
3577
|
let retryTimer = null;
|
|
3560
3578
|
let manifestParsed = false;
|
|
3561
3579
|
let mediaErrorRetries = 0;
|
|
3580
|
+
let playbackSource = "hls";
|
|
3562
3581
|
const teardown = [];
|
|
3563
3582
|
media.muted = muted;
|
|
3564
3583
|
setState("loading");
|
|
@@ -3567,7 +3586,13 @@ function useHlsPlayback({
|
|
|
3567
3586
|
setQualities([]);
|
|
3568
3587
|
setActiveLevel(-1);
|
|
3569
3588
|
function baseContext() {
|
|
3570
|
-
return {
|
|
3589
|
+
return {
|
|
3590
|
+
mode,
|
|
3591
|
+
src,
|
|
3592
|
+
manifestParsed,
|
|
3593
|
+
retryCount: mediaErrorRetries,
|
|
3594
|
+
source: playbackSource
|
|
3595
|
+
};
|
|
3571
3596
|
}
|
|
3572
3597
|
function clearRetryTimer() {
|
|
3573
3598
|
if (retryTimer !== null) {
|
|
@@ -3606,6 +3631,53 @@ function useHlsPlayback({
|
|
|
3606
3631
|
if (!cancelled) retryFn();
|
|
3607
3632
|
}, RETRY_INTERVAL_MS);
|
|
3608
3633
|
}
|
|
3634
|
+
function startDriftWatchdog(el) {
|
|
3635
|
+
if (typeof el.requestVideoFrameCallback !== "function") return;
|
|
3636
|
+
let consecutiveLagSamples = 0;
|
|
3637
|
+
let lastResyncAt = 0;
|
|
3638
|
+
let handle = null;
|
|
3639
|
+
const tick = (_now, metadata) => {
|
|
3640
|
+
if (cancelled) return;
|
|
3641
|
+
handle = el.requestVideoFrameCallback(tick);
|
|
3642
|
+
if (el.paused || el.ended) {
|
|
3643
|
+
consecutiveLagSamples = 0;
|
|
3644
|
+
return;
|
|
3645
|
+
}
|
|
3646
|
+
const lag = el.currentTime - metadata.mediaTime;
|
|
3647
|
+
if (!(lag > DRIFT_THRESHOLD_S)) {
|
|
3648
|
+
consecutiveLagSamples = 0;
|
|
3649
|
+
return;
|
|
3650
|
+
}
|
|
3651
|
+
consecutiveLagSamples += 1;
|
|
3652
|
+
if (consecutiveLagSamples < DRIFT_CONSECUTIVE_SAMPLES) return;
|
|
3653
|
+
const nowMs = performance.now();
|
|
3654
|
+
if (nowMs - lastResyncAt < RESYNC_COOLDOWN_MS) return;
|
|
3655
|
+
lastResyncAt = nowMs;
|
|
3656
|
+
consecutiveLagSamples = 0;
|
|
3657
|
+
if (mode === "live" && el.seekable.length > 0) {
|
|
3658
|
+
const edge = el.seekable.end(el.seekable.length - 1);
|
|
3659
|
+
if (edge - el.currentTime > LIVE_EDGE_RESYNC_THRESHOLD_S) {
|
|
3660
|
+
el.currentTime = edge;
|
|
3661
|
+
} else {
|
|
3662
|
+
el.currentTime = el.currentTime + 1e-3;
|
|
3663
|
+
}
|
|
3664
|
+
} else {
|
|
3665
|
+
el.currentTime = el.currentTime + 1e-3;
|
|
3666
|
+
}
|
|
3667
|
+
onErrorRef.current?.(
|
|
3668
|
+
describeAvResync({
|
|
3669
|
+
lagSeconds: lag,
|
|
3670
|
+
context: baseContext()
|
|
3671
|
+
})
|
|
3672
|
+
);
|
|
3673
|
+
};
|
|
3674
|
+
handle = el.requestVideoFrameCallback(tick);
|
|
3675
|
+
teardown.push(() => {
|
|
3676
|
+
if (handle != null && typeof el.cancelVideoFrameCallback === "function") {
|
|
3677
|
+
el.cancelVideoFrameCallback(handle);
|
|
3678
|
+
}
|
|
3679
|
+
});
|
|
3680
|
+
}
|
|
3609
3681
|
function onPlaying() {
|
|
3610
3682
|
manifestParsed = true;
|
|
3611
3683
|
mediaErrorRetries = 0;
|
|
@@ -3624,7 +3696,9 @@ function useHlsPlayback({
|
|
|
3624
3696
|
media.removeEventListener("pause", onPaused);
|
|
3625
3697
|
media.removeEventListener("ended", onPaused);
|
|
3626
3698
|
});
|
|
3699
|
+
startDriftWatchdog(media);
|
|
3627
3700
|
function initNative() {
|
|
3701
|
+
playbackSource = "native";
|
|
3628
3702
|
manifestParsed = false;
|
|
3629
3703
|
media.removeAttribute("src");
|
|
3630
3704
|
media.load();
|
|
@@ -3640,7 +3714,7 @@ function useHlsPlayback({
|
|
|
3640
3714
|
reportFatal({
|
|
3641
3715
|
source: "native",
|
|
3642
3716
|
mediaError: media.error,
|
|
3643
|
-
context:
|
|
3717
|
+
context: baseContext()
|
|
3644
3718
|
});
|
|
3645
3719
|
return;
|
|
3646
3720
|
}
|
|
@@ -3648,7 +3722,7 @@ function useHlsPlayback({
|
|
|
3648
3722
|
describePlaybackError({
|
|
3649
3723
|
source: "native",
|
|
3650
3724
|
mediaError: media.error,
|
|
3651
|
-
context:
|
|
3725
|
+
context: baseContext()
|
|
3652
3726
|
})
|
|
3653
3727
|
);
|
|
3654
3728
|
scheduleRetry(() => {
|
|
@@ -3664,6 +3738,7 @@ function useHlsPlayback({
|
|
|
3664
3738
|
});
|
|
3665
3739
|
}
|
|
3666
3740
|
function initHlsJs(Hls) {
|
|
3741
|
+
playbackSource = "hls";
|
|
3667
3742
|
destroyHls();
|
|
3668
3743
|
manifestParsed = false;
|
|
3669
3744
|
const config = mode === "live" ? createLiveHlsConfig() : createVodHlsConfig();
|
|
@@ -3695,7 +3770,7 @@ function useHlsPlayback({
|
|
|
3695
3770
|
response: data.response,
|
|
3696
3771
|
reason: data.reason,
|
|
3697
3772
|
error: data.error,
|
|
3698
|
-
context:
|
|
3773
|
+
context: baseContext()
|
|
3699
3774
|
})
|
|
3700
3775
|
);
|
|
3701
3776
|
if (!data.fatal) return;
|
|
@@ -3730,7 +3805,7 @@ function useHlsPlayback({
|
|
|
3730
3805
|
response: data.response,
|
|
3731
3806
|
reason: data.reason,
|
|
3732
3807
|
error: data.error,
|
|
3733
|
-
context:
|
|
3808
|
+
context: baseContext()
|
|
3734
3809
|
});
|
|
3735
3810
|
});
|
|
3736
3811
|
}
|
|
@@ -3747,9 +3822,10 @@ function useHlsPlayback({
|
|
|
3747
3822
|
} else if (media.canPlayType("application/vnd.apple.mpegurl")) {
|
|
3748
3823
|
initNative();
|
|
3749
3824
|
} else {
|
|
3825
|
+
playbackSource = "unsupported";
|
|
3750
3826
|
reportFatal({
|
|
3751
3827
|
source: "unsupported",
|
|
3752
|
-
context:
|
|
3828
|
+
context: baseContext()
|
|
3753
3829
|
});
|
|
3754
3830
|
}
|
|
3755
3831
|
}
|
|
@@ -4096,6 +4172,8 @@ function VideoPlayer({
|
|
|
4096
4172
|
return t.errorMedia;
|
|
4097
4173
|
case "unsupported":
|
|
4098
4174
|
return t.errorUnsupported;
|
|
4175
|
+
case "resync":
|
|
4176
|
+
return t.errorMedia;
|
|
4099
4177
|
case "generic":
|
|
4100
4178
|
return t.errorGeneric;
|
|
4101
4179
|
default: {
|
|
@@ -6905,6 +6983,105 @@ function createSupportChatClient(basePath = "/api/chat-svc") {
|
|
|
6905
6983
|
}
|
|
6906
6984
|
};
|
|
6907
6985
|
}
|
|
6986
|
+
var DEFAULT_RECONNECT_MS = 2e3;
|
|
6987
|
+
var MAX_RECONNECT_MS = 3e4;
|
|
6988
|
+
function useRealtimeChannel({
|
|
6989
|
+
getWsUrl,
|
|
6990
|
+
onEvent,
|
|
6991
|
+
enabled = true,
|
|
6992
|
+
reconnectDelayMs = DEFAULT_RECONNECT_MS
|
|
6993
|
+
}) {
|
|
6994
|
+
const onEventRef = React7.useRef(onEvent);
|
|
6995
|
+
onEventRef.current = onEvent;
|
|
6996
|
+
const getWsUrlRef = React7.useRef(getWsUrl);
|
|
6997
|
+
getWsUrlRef.current = getWsUrl;
|
|
6998
|
+
React7.useEffect(() => {
|
|
6999
|
+
if (!enabled) return;
|
|
7000
|
+
let cancelled = false;
|
|
7001
|
+
let socket = null;
|
|
7002
|
+
let reconnectTimer = null;
|
|
7003
|
+
let attempt = 0;
|
|
7004
|
+
const connectGen = { current: 0 };
|
|
7005
|
+
const clearReconnect = () => {
|
|
7006
|
+
if (reconnectTimer) {
|
|
7007
|
+
clearTimeout(reconnectTimer);
|
|
7008
|
+
reconnectTimer = null;
|
|
7009
|
+
}
|
|
7010
|
+
};
|
|
7011
|
+
const scheduleReconnect = () => {
|
|
7012
|
+
if (cancelled) return;
|
|
7013
|
+
clearReconnect();
|
|
7014
|
+
const delay = Math.min(reconnectDelayMs * 2 ** attempt, MAX_RECONNECT_MS);
|
|
7015
|
+
attempt += 1;
|
|
7016
|
+
reconnectTimer = setTimeout(() => {
|
|
7017
|
+
void connect();
|
|
7018
|
+
}, delay);
|
|
7019
|
+
};
|
|
7020
|
+
const connect = async () => {
|
|
7021
|
+
const gen = ++connectGen.current;
|
|
7022
|
+
clearReconnect();
|
|
7023
|
+
const url = await getWsUrlRef.current();
|
|
7024
|
+
if (cancelled || gen !== connectGen.current) return;
|
|
7025
|
+
if (!url) {
|
|
7026
|
+
scheduleReconnect();
|
|
7027
|
+
return;
|
|
7028
|
+
}
|
|
7029
|
+
if (socket) {
|
|
7030
|
+
try {
|
|
7031
|
+
socket.close();
|
|
7032
|
+
} catch {
|
|
7033
|
+
}
|
|
7034
|
+
socket = null;
|
|
7035
|
+
}
|
|
7036
|
+
const ws = new WebSocket(url);
|
|
7037
|
+
socket = ws;
|
|
7038
|
+
ws.onopen = () => {
|
|
7039
|
+
if (cancelled || gen !== connectGen.current) return;
|
|
7040
|
+
attempt = 0;
|
|
7041
|
+
};
|
|
7042
|
+
ws.onmessage = (msg) => {
|
|
7043
|
+
if (cancelled || gen !== connectGen.current) return;
|
|
7044
|
+
let data;
|
|
7045
|
+
try {
|
|
7046
|
+
data = JSON.parse(String(msg.data));
|
|
7047
|
+
} catch {
|
|
7048
|
+
return;
|
|
7049
|
+
}
|
|
7050
|
+
if (typeof data?.type !== "string") return;
|
|
7051
|
+
if (data.type === "pong") return;
|
|
7052
|
+
onEventRef.current(data);
|
|
7053
|
+
};
|
|
7054
|
+
ws.onclose = () => {
|
|
7055
|
+
if (cancelled || gen !== connectGen.current) return;
|
|
7056
|
+
socket = null;
|
|
7057
|
+
scheduleReconnect();
|
|
7058
|
+
};
|
|
7059
|
+
ws.onerror = () => {
|
|
7060
|
+
};
|
|
7061
|
+
};
|
|
7062
|
+
const onVisibility = () => {
|
|
7063
|
+
if (document.visibilityState !== "visible" || cancelled) return;
|
|
7064
|
+
if (!socket || socket.readyState === WebSocket.CLOSED) {
|
|
7065
|
+
void connect();
|
|
7066
|
+
}
|
|
7067
|
+
};
|
|
7068
|
+
void connect();
|
|
7069
|
+
document.addEventListener("visibilitychange", onVisibility);
|
|
7070
|
+
return () => {
|
|
7071
|
+
cancelled = true;
|
|
7072
|
+
connectGen.current += 1;
|
|
7073
|
+
clearReconnect();
|
|
7074
|
+
document.removeEventListener("visibilitychange", onVisibility);
|
|
7075
|
+
if (socket) {
|
|
7076
|
+
try {
|
|
7077
|
+
socket.close();
|
|
7078
|
+
} catch {
|
|
7079
|
+
}
|
|
7080
|
+
socket = null;
|
|
7081
|
+
}
|
|
7082
|
+
};
|
|
7083
|
+
}, [enabled, reconnectDelayMs]);
|
|
7084
|
+
}
|
|
6908
7085
|
|
|
6909
7086
|
Object.defineProperty(exports, "useMessageScroller", {
|
|
6910
7087
|
enumerable: true,
|
|
@@ -6977,6 +7154,7 @@ exports.createLiveHlsConfig = createLiveHlsConfig;
|
|
|
6977
7154
|
exports.createSupportChatClient = createSupportChatClient;
|
|
6978
7155
|
exports.createVodHlsConfig = createVodHlsConfig;
|
|
6979
7156
|
exports.defaultLanguages = defaultLanguages;
|
|
7157
|
+
exports.describeAvResync = describeAvResync;
|
|
6980
7158
|
exports.describePlaybackError = describePlaybackError;
|
|
6981
7159
|
exports.fuzzyMatch = fuzzyMatch;
|
|
6982
7160
|
exports.getAvatarColors = getAvatarColors;
|
|
@@ -6991,6 +7169,7 @@ exports.useHlsPlayback = useHlsPlayback;
|
|
|
6991
7169
|
exports.useLanguageContext = useLanguageContext;
|
|
6992
7170
|
exports.useMediaQuery = useMediaQuery2;
|
|
6993
7171
|
exports.usePlaybackStats = usePlaybackStats;
|
|
7172
|
+
exports.useRealtimeChannel = useRealtimeChannel;
|
|
6994
7173
|
exports.useSearchHotkey = useSearchHotkey;
|
|
6995
7174
|
exports.useSupportConversation = useSupportConversation;
|
|
6996
7175
|
exports.useSupportMessenger = useSupportMessenger;
|