realtime-avatar 0.8.0 → 0.9.1
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/{chunk-JNRRH2G7.js → chunk-F7E4HMBW.js} +1 -1
- package/dist/{chunk-TOXLWFQY.js → chunk-FTAD423K.js} +1 -1
- package/dist/express.js +2 -2
- package/dist/hono.js +2 -2
- package/dist/index.js +1 -1
- package/dist/nextjs.js +2 -2
- package/dist/{proxy-client-DDqYRz-_.d.ts → proxy-client-DlYBC6cp.d.ts} +4 -5
- package/dist/react-native.d.ts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +48 -11
- package/dist/server.js +1 -1
- package/dist/tanstack-start.js +2 -2
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RealtimeAvatar, isQueued, RealtimeAvatarHttpError } from './chunk-
|
|
1
|
+
import { RealtimeAvatar, isQueued, RealtimeAvatarHttpError } from './chunk-F7E4HMBW.js';
|
|
2
2
|
|
|
3
3
|
// ../proxy/src/config.ts
|
|
4
4
|
var json = (body, status = 200) => new Response(JSON.stringify(body), {
|
package/dist/express.js
CHANGED
package/dist/hono.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, isQueued, verifyTranscript } from './chunk-
|
|
1
|
+
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, isQueued, verifyTranscript } from './chunk-F7E4HMBW.js';
|
package/dist/nextjs.js
CHANGED
|
@@ -470,8 +470,8 @@ type AvatarVideoSurfaceProps = {
|
|
|
470
470
|
* Debounce (ms) before dropping BACK to the idle clip once the live layer stops
|
|
471
471
|
* being shown (turn end), so back-to-back turns don't flash the idle clip for a
|
|
472
472
|
* frame between them. Default 700. A disconnect bypasses this and reverts to idle
|
|
473
|
-
* immediately (a dead room is never held).
|
|
474
|
-
*
|
|
473
|
+
* immediately (a dead room is never held). A new track shows its first frame
|
|
474
|
+
* immediately; after a frame stall, sustained progress is required to return.
|
|
475
475
|
*/
|
|
476
476
|
idleReturnDelayMs?: number;
|
|
477
477
|
/**
|
|
@@ -520,9 +520,8 @@ type AvatarVideoSurfaceProps = {
|
|
|
520
520
|
* end, network drop, agent gone, turn-end mute).
|
|
521
521
|
*
|
|
522
522
|
* ONE BODY, ONE POSE. Only one media layer ever runs: the idle clip is paused while
|
|
523
|
-
* the live layer covers it
|
|
524
|
-
*
|
|
525
|
-
* `useIdleWhileResting` notes for the measurements behind it.
|
|
523
|
+
* the live layer covers it. A temporary interruption resumes the idle clip where
|
|
524
|
+
* it paused; a deliberate rest or disconnect returns it to its anchor (frame 0).
|
|
526
525
|
*
|
|
527
526
|
* This is the SSOT for "is the avatar live right now": it reads the LiveKit
|
|
528
527
|
* connection state ({@link useConnectionState}) and the bound avatar track
|
package/dist/react-native.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { LiveKitRoomProps } from '@livekit/react-native';
|
|
2
2
|
export { AudioSession, VideoTrack, VideoTrackProps, registerGlobals } from '@livekit/react-native';
|
|
3
3
|
import { ReactNode, ReactElement } from 'react';
|
|
4
|
-
import { L as LiveKitSessionGrant, A as AvatarVideoFit } from './proxy-client-
|
|
5
|
-
export { a as AdaptivePlayoutController, b as AdaptivePlayoutDecision, c as AdaptivePlayoutOptions, d as AdaptivePlayoutSample, e as ApproachingEndEvent, f as ApproachingEndReason, g as AvatarSessionClient, B as BehaviorSnapshot, C as CallTranscript, h as CallTranscriptSegment, i as CartesiaTtsModel, j as ClipResult, k as ClosingTurnResult, l as CreditsLowEvent, D as DEFAULT_APPROACHING_END_LEAD_SECONDS, m as DEFAULT_CREDITS_LOW_LEAD_SECONDS, n as DEFAULT_GOVERNOR_CONFIG, o as DEFAULT_GRACE_CEILING_SECONDS, p as DEFAULT_GRACE_WINDOW_LEAD_SECONDS, q as DEFAULT_IDLE_SECONDS, r as DEFAULT_IDLE_WARN_LEAD_SECONDS, s as DEFAULT_TURN_TIMEOUT_SECONDS, E as EndReason, t as EndedEvent, u as ExtendResult, F as FishTtsModel, v as FreezeReadingFn, G as Governor, w as GovernorAction, x as GovernorConfig, y as GovernorSignal, z as GovernorState, H as GraceWindowClosedEvent, I as GraceWindowOpenEvent, J as GraceWindowState, K as IdleWarningEvent, M as InboundRtpCursor, N as InboundRtpReading, O as KnownBehaviorState, P as LLMProvider, Q as LLMSelection, R as LiveKitAvatarGrantState, S as LiveKitAvatarGrantStatus, T as LiveKitCapacityState, U as LiveKitConnectionStatus, V as LiveKitSessionRequest, W as LiveKitSessionStartResult, X as MAX_RECONNECT_ATTEMPTS, Y as MAX_SESSION_INSTRUCTIONS_CHARS, Z as ProxyClientOptions, _ as QualityCap, $ as RECONNECT_BACKOFF_MS, a0 as RealtimeAvatarRequestOptions, a1 as RealtimeSessionApi, a2 as RealtimeSessionMedia, a3 as RealtimeSessionRoomSinks, a4 as ReconnectPolicy, a5 as ReconnectingEvent, a6 as RecoveryState, a7 as RetryStep, a8 as SessionBehavior, a9 as SessionClip, aa as SessionClocks, ab as SessionEndReason, ac as SessionLifecycleApi, ad as SessionLifecyclePhase, ae as SessionLifecyclePhaseKind, af as SessionLifecycleRoomBridge, ag as SessionLifecycleRoomBridgeProps, ah as SurfaceLayers, ai as TurnState, aj as TurnTimeoutEvent, ak as UseAvatarQualityGovernorInput, al as UseLiveKitAvatarGrantInput, am as UseRealtimeSessionInput, an as UseSessionLifecycleInput, ao as VoiceSpec, ap as VoiceSpecInput, aq as capacityErrorFromBusy, ar as capacityStateFromGrant, as as createProxyClient, at as isNativeLiveTrackSubscribed, au as knownBehaviorStates, av as mapTurnState, aw as readInboundRtp, ax as sessionBehaviorSchema, ay as sessionClipSchema, az as splitCallTranscript, aA as useAvatarAdaptivePlayoutDelay, aB as useAvatarPlayoutDelay, aC as useAvatarQualityGovernor, aD as useCallTranscript, aE as useLiveKitAvatarGrant, aF as useLiveTrackProducing, aG as useMicLease, aH as useRealtimeSession, aI as useReleaseMicLeaseOnTrackEnded, aJ as useSessionLifecycle } from './proxy-client-
|
|
4
|
+
import { L as LiveKitSessionGrant, A as AvatarVideoFit } from './proxy-client-DlYBC6cp.js';
|
|
5
|
+
export { a as AdaptivePlayoutController, b as AdaptivePlayoutDecision, c as AdaptivePlayoutOptions, d as AdaptivePlayoutSample, e as ApproachingEndEvent, f as ApproachingEndReason, g as AvatarSessionClient, B as BehaviorSnapshot, C as CallTranscript, h as CallTranscriptSegment, i as CartesiaTtsModel, j as ClipResult, k as ClosingTurnResult, l as CreditsLowEvent, D as DEFAULT_APPROACHING_END_LEAD_SECONDS, m as DEFAULT_CREDITS_LOW_LEAD_SECONDS, n as DEFAULT_GOVERNOR_CONFIG, o as DEFAULT_GRACE_CEILING_SECONDS, p as DEFAULT_GRACE_WINDOW_LEAD_SECONDS, q as DEFAULT_IDLE_SECONDS, r as DEFAULT_IDLE_WARN_LEAD_SECONDS, s as DEFAULT_TURN_TIMEOUT_SECONDS, E as EndReason, t as EndedEvent, u as ExtendResult, F as FishTtsModel, v as FreezeReadingFn, G as Governor, w as GovernorAction, x as GovernorConfig, y as GovernorSignal, z as GovernorState, H as GraceWindowClosedEvent, I as GraceWindowOpenEvent, J as GraceWindowState, K as IdleWarningEvent, M as InboundRtpCursor, N as InboundRtpReading, O as KnownBehaviorState, P as LLMProvider, Q as LLMSelection, R as LiveKitAvatarGrantState, S as LiveKitAvatarGrantStatus, T as LiveKitCapacityState, U as LiveKitConnectionStatus, V as LiveKitSessionRequest, W as LiveKitSessionStartResult, X as MAX_RECONNECT_ATTEMPTS, Y as MAX_SESSION_INSTRUCTIONS_CHARS, Z as ProxyClientOptions, _ as QualityCap, $ as RECONNECT_BACKOFF_MS, a0 as RealtimeAvatarRequestOptions, a1 as RealtimeSessionApi, a2 as RealtimeSessionMedia, a3 as RealtimeSessionRoomSinks, a4 as ReconnectPolicy, a5 as ReconnectingEvent, a6 as RecoveryState, a7 as RetryStep, a8 as SessionBehavior, a9 as SessionClip, aa as SessionClocks, ab as SessionEndReason, ac as SessionLifecycleApi, ad as SessionLifecyclePhase, ae as SessionLifecyclePhaseKind, af as SessionLifecycleRoomBridge, ag as SessionLifecycleRoomBridgeProps, ah as SurfaceLayers, ai as TurnState, aj as TurnTimeoutEvent, ak as UseAvatarQualityGovernorInput, al as UseLiveKitAvatarGrantInput, am as UseRealtimeSessionInput, an as UseSessionLifecycleInput, ao as VoiceSpec, ap as VoiceSpecInput, aq as capacityErrorFromBusy, ar as capacityStateFromGrant, as as createProxyClient, at as isNativeLiveTrackSubscribed, au as knownBehaviorStates, av as mapTurnState, aw as readInboundRtp, ax as sessionBehaviorSchema, ay as sessionClipSchema, az as splitCallTranscript, aA as useAvatarAdaptivePlayoutDelay, aB as useAvatarPlayoutDelay, aC as useAvatarQualityGovernor, aD as useCallTranscript, aE as useLiveKitAvatarGrant, aF as useLiveTrackProducing, aG as useMicLease, aH as useRealtimeSession, aI as useReleaseMicLeaseOnTrackEnded, aJ as useSessionLifecycle } from './proxy-client-DlYBC6cp.js';
|
|
6
6
|
import { StyleProp, ViewStyle } from 'react-native';
|
|
7
7
|
export { useChat, useConnectionState, useLocalParticipant, useRoomContext, useTrackToggle, useTranscriptions, useVoiceAssistant } from '@livekit/components-react';
|
|
8
8
|
export { D as DEFAULT_AVATAR_PLAYOUT_DELAY_SECONDS } from './playout-delay-DWOc8iCl.js';
|
package/dist/react.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import { g as AvatarSessionClient, A as AvatarVideoFit } from './proxy-client-
|
|
3
|
-
export { a as AdaptivePlayoutController, b as AdaptivePlayoutDecision, c as AdaptivePlayoutOptions, d as AdaptivePlayoutSample, e as ApproachingEndEvent, f as ApproachingEndReason, aK as AvatarVideoSurface, aL as AvatarVideoSurfaceProps, B as BehaviorSnapshot, C as CallTranscript, h as CallTranscriptSegment, i as CartesiaTtsModel, j as ClipResult, k as ClosingTurnResult, l as CreditsLowEvent, D as DEFAULT_APPROACHING_END_LEAD_SECONDS, m as DEFAULT_CREDITS_LOW_LEAD_SECONDS, n as DEFAULT_GOVERNOR_CONFIG, o as DEFAULT_GRACE_CEILING_SECONDS, p as DEFAULT_GRACE_WINDOW_LEAD_SECONDS, q as DEFAULT_IDLE_SECONDS, r as DEFAULT_IDLE_WARN_LEAD_SECONDS, s as DEFAULT_TURN_TIMEOUT_SECONDS, E as EndReason, t as EndedEvent, u as ExtendResult, F as FishTtsModel, v as FreezeReadingFn, G as Governor, w as GovernorAction, x as GovernorConfig, y as GovernorSignal, z as GovernorState, H as GraceWindowClosedEvent, I as GraceWindowOpenEvent, J as GraceWindowState, K as IdleWarningEvent, M as InboundRtpCursor, N as InboundRtpReading, O as KnownBehaviorState, P as LLMProvider, Q as LLMSelection, R as LiveKitAvatarGrantState, S as LiveKitAvatarGrantStatus, T as LiveKitCapacityState, U as LiveKitConnectionStatus, V as LiveKitSessionRequest, W as LiveKitSessionStartResult, aM as LivePlaybackKeeper, X as MAX_RECONNECT_ATTEMPTS, Y as MAX_SESSION_INSTRUCTIONS_CHARS, aN as MIC_LEASE_ENDED_TIMEOUT_MS, aO as MicLease, aP as PlayableVideoElement, Z as ProxyClientOptions, _ as QualityCap, $ as RECONNECT_BACKOFF_MS, aQ as RealtimeAvatarCapacityError, aR as RealtimeAvatarLiveKitRoom, aS as RealtimeAvatarLiveKitRoomProps, a0 as RealtimeAvatarRequestOptions, a1 as RealtimeSessionApi, a2 as RealtimeSessionMedia, a3 as RealtimeSessionRoomSinks, a4 as ReconnectPolicy, a5 as ReconnectingEvent, a6 as RecoveryState, a7 as RetryStep, a8 as SessionBehavior, a9 as SessionClip, aa as SessionClocks, ab as SessionEndReason, ac as SessionLifecycleApi, ad as SessionLifecyclePhase, ae as SessionLifecyclePhaseKind, af as SessionLifecycleRoomBridge, ag as SessionLifecycleRoomBridgeProps, ah as SurfaceLayers, ai as TurnState, aj as TurnTimeoutEvent, ak as UseAvatarQualityGovernorInput, al as UseLiveKitAvatarGrantInput, am as UseRealtimeSessionInput, an as UseSessionLifecycleInput, ao as VoiceSpec, ap as VoiceSpecInput, aq as capacityErrorFromBusy, ar as capacityStateFromGrant, as as createProxyClient, au as knownBehaviorStates, av as mapTurnState, aw as readInboundRtp, ax as sessionBehaviorSchema, ay as sessionClipSchema, aT as shouldReplayPendingTurn, az as splitCallTranscript, aA as useAvatarAdaptivePlayoutDelay, aB as useAvatarPlayoutDelay, aC as useAvatarQualityGovernor, aD as useCallTranscript, aE as useLiveKitAvatarGrant, aG as useMicLease, aH as useRealtimeSession, aI as useReleaseMicLeaseOnTrackEnded, aJ as useSessionLifecycle } from './proxy-client-
|
|
2
|
+
import { g as AvatarSessionClient, A as AvatarVideoFit } from './proxy-client-DlYBC6cp.js';
|
|
3
|
+
export { a as AdaptivePlayoutController, b as AdaptivePlayoutDecision, c as AdaptivePlayoutOptions, d as AdaptivePlayoutSample, e as ApproachingEndEvent, f as ApproachingEndReason, aK as AvatarVideoSurface, aL as AvatarVideoSurfaceProps, B as BehaviorSnapshot, C as CallTranscript, h as CallTranscriptSegment, i as CartesiaTtsModel, j as ClipResult, k as ClosingTurnResult, l as CreditsLowEvent, D as DEFAULT_APPROACHING_END_LEAD_SECONDS, m as DEFAULT_CREDITS_LOW_LEAD_SECONDS, n as DEFAULT_GOVERNOR_CONFIG, o as DEFAULT_GRACE_CEILING_SECONDS, p as DEFAULT_GRACE_WINDOW_LEAD_SECONDS, q as DEFAULT_IDLE_SECONDS, r as DEFAULT_IDLE_WARN_LEAD_SECONDS, s as DEFAULT_TURN_TIMEOUT_SECONDS, E as EndReason, t as EndedEvent, u as ExtendResult, F as FishTtsModel, v as FreezeReadingFn, G as Governor, w as GovernorAction, x as GovernorConfig, y as GovernorSignal, z as GovernorState, H as GraceWindowClosedEvent, I as GraceWindowOpenEvent, J as GraceWindowState, K as IdleWarningEvent, M as InboundRtpCursor, N as InboundRtpReading, O as KnownBehaviorState, P as LLMProvider, Q as LLMSelection, R as LiveKitAvatarGrantState, S as LiveKitAvatarGrantStatus, T as LiveKitCapacityState, U as LiveKitConnectionStatus, V as LiveKitSessionRequest, W as LiveKitSessionStartResult, aM as LivePlaybackKeeper, X as MAX_RECONNECT_ATTEMPTS, Y as MAX_SESSION_INSTRUCTIONS_CHARS, aN as MIC_LEASE_ENDED_TIMEOUT_MS, aO as MicLease, aP as PlayableVideoElement, Z as ProxyClientOptions, _ as QualityCap, $ as RECONNECT_BACKOFF_MS, aQ as RealtimeAvatarCapacityError, aR as RealtimeAvatarLiveKitRoom, aS as RealtimeAvatarLiveKitRoomProps, a0 as RealtimeAvatarRequestOptions, a1 as RealtimeSessionApi, a2 as RealtimeSessionMedia, a3 as RealtimeSessionRoomSinks, a4 as ReconnectPolicy, a5 as ReconnectingEvent, a6 as RecoveryState, a7 as RetryStep, a8 as SessionBehavior, a9 as SessionClip, aa as SessionClocks, ab as SessionEndReason, ac as SessionLifecycleApi, ad as SessionLifecyclePhase, ae as SessionLifecyclePhaseKind, af as SessionLifecycleRoomBridge, ag as SessionLifecycleRoomBridgeProps, ah as SurfaceLayers, ai as TurnState, aj as TurnTimeoutEvent, ak as UseAvatarQualityGovernorInput, al as UseLiveKitAvatarGrantInput, am as UseRealtimeSessionInput, an as UseSessionLifecycleInput, ao as VoiceSpec, ap as VoiceSpecInput, aq as capacityErrorFromBusy, ar as capacityStateFromGrant, as as createProxyClient, au as knownBehaviorStates, av as mapTurnState, aw as readInboundRtp, ax as sessionBehaviorSchema, ay as sessionClipSchema, aT as shouldReplayPendingTurn, az as splitCallTranscript, aA as useAvatarAdaptivePlayoutDelay, aB as useAvatarPlayoutDelay, aC as useAvatarQualityGovernor, aD as useCallTranscript, aE as useLiveKitAvatarGrant, aG as useMicLease, aH as useRealtimeSession, aI as useReleaseMicLeaseOnTrackEnded, aJ as useSessionLifecycle } from './proxy-client-DlYBC6cp.js';
|
|
4
4
|
export { D as DEFAULT_AVATAR_PLAYOUT_DELAY_SECONDS } from './playout-delay-DWOc8iCl.js';
|
|
5
5
|
import '@livekit/components-react';
|
|
6
6
|
import 'livekit-client';
|
package/dist/react.js
CHANGED
|
@@ -978,6 +978,33 @@ function useAvatarQualityGovernor(input) {
|
|
|
978
978
|
}, [enabled, room, videoTrack, freezeReading, config, tickMs]);
|
|
979
979
|
}
|
|
980
980
|
|
|
981
|
+
// ../client/src/react/frame-recovery.ts
|
|
982
|
+
var FrameRecovery = class {
|
|
983
|
+
constructor(stallAfterMs) {
|
|
984
|
+
this.stallAfterMs = stallAfterMs;
|
|
985
|
+
}
|
|
986
|
+
stallAfterMs;
|
|
987
|
+
lastFrameAtMs = null;
|
|
988
|
+
stableSinceMs = null;
|
|
989
|
+
ready = true;
|
|
990
|
+
stall() {
|
|
991
|
+
this.ready = false;
|
|
992
|
+
this.stableSinceMs = null;
|
|
993
|
+
}
|
|
994
|
+
frame(nowMs) {
|
|
995
|
+
const gapMs = this.lastFrameAtMs === null ? 0 : nowMs - this.lastFrameAtMs;
|
|
996
|
+
if (this.lastFrameAtMs !== null && gapMs > this.stallAfterMs) this.stall();
|
|
997
|
+
if (!this.ready) {
|
|
998
|
+
if (this.stableSinceMs === null || gapMs > Math.min(350, this.stallAfterMs)) {
|
|
999
|
+
this.stableSinceMs = nowMs;
|
|
1000
|
+
}
|
|
1001
|
+
this.ready = nowMs - this.stableSinceMs >= 500;
|
|
1002
|
+
}
|
|
1003
|
+
this.lastFrameAtMs = nowMs;
|
|
1004
|
+
return this.ready;
|
|
1005
|
+
}
|
|
1006
|
+
};
|
|
1007
|
+
|
|
981
1008
|
// ../client/src/react/avatar-video-surface.ts
|
|
982
1009
|
var DEFAULT_AVATAR_FRAME_STALL_MS = 800;
|
|
983
1010
|
var AVATAR_FRAME_GAP_FREEZE_FLOOR_MS = 100;
|
|
@@ -1045,7 +1072,12 @@ function AvatarVideoSurface(props) {
|
|
|
1045
1072
|
const liveDims = videoTrack?.publication?.dimensions ?? null;
|
|
1046
1073
|
const idleVideoRef = useRef(null);
|
|
1047
1074
|
const boxAspect = aspectRatio ?? null;
|
|
1048
|
-
useIdleWhileResting(
|
|
1075
|
+
useIdleWhileResting(
|
|
1076
|
+
idleVideoRef,
|
|
1077
|
+
idleVideoUrl,
|
|
1078
|
+
showLive,
|
|
1079
|
+
!live || connectionState === ConnectionState.Disconnected
|
|
1080
|
+
);
|
|
1049
1081
|
useLiveResumeOnProducing(liveWrapRef, trackProducing);
|
|
1050
1082
|
const fitClass = fit === "cover" ? AVATAR_VIDEO_FIT_COVER : AVATAR_VIDEO_FIT_CONTAIN;
|
|
1051
1083
|
const liveLabel = showLive && liveDims && liveDims.width > 0 && liveDims.height > 0 ? `${liveDims.width}\xD7${liveDims.height}` : null;
|
|
@@ -1177,6 +1209,7 @@ function isFrameFreezeInhibited(snapshot) {
|
|
|
1177
1209
|
}
|
|
1178
1210
|
function useLiveFrameFlow(wrapRef, trackProducing, trackIdentity, stallAfterMs) {
|
|
1179
1211
|
const boundedStallMs = normalizeFrameStallMs(stallAfterMs);
|
|
1212
|
+
const recovery = useMemo(() => new FrameRecovery(boundedStallMs), [trackIdentity, boundedStallMs]);
|
|
1180
1213
|
const [flowing, setFlowing] = useState(false);
|
|
1181
1214
|
const [seenFrame, setSeenFrame] = useState(false);
|
|
1182
1215
|
const flowingRef = useRef(false);
|
|
@@ -1206,6 +1239,7 @@ function useLiveFrameFlow(wrapRef, trackProducing, trackIdentity, stallAfterMs)
|
|
|
1206
1239
|
const markFrame = () => {
|
|
1207
1240
|
const previous = sampleRef.current;
|
|
1208
1241
|
const now = Date.now();
|
|
1242
|
+
lastCurrentTime = video?.currentTime ?? lastCurrentTime;
|
|
1209
1243
|
const firstFrame = !previous.seenFrame;
|
|
1210
1244
|
sampleRef.current = {
|
|
1211
1245
|
seenFrame: true,
|
|
@@ -1219,9 +1253,10 @@ function useLiveFrameFlow(wrapRef, trackProducing, trackIdentity, stallAfterMs)
|
|
|
1219
1253
|
resumePending: false
|
|
1220
1254
|
};
|
|
1221
1255
|
if (firstFrame) setSeenFrame(true);
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1256
|
+
const nextFlowing = recovery.frame(now);
|
|
1257
|
+
if (flowingRef.current !== nextFlowing) {
|
|
1258
|
+
flowingRef.current = nextFlowing;
|
|
1259
|
+
setFlowing(nextFlowing);
|
|
1225
1260
|
}
|
|
1226
1261
|
};
|
|
1227
1262
|
const cancelFrameCallback = () => {
|
|
@@ -1263,12 +1298,14 @@ function useLiveFrameFlow(wrapRef, trackProducing, trackIdentity, stallAfterMs)
|
|
|
1263
1298
|
lastCurrentTime = video.currentTime;
|
|
1264
1299
|
markFrame();
|
|
1265
1300
|
}
|
|
1266
|
-
const
|
|
1301
|
+
const frameFresh = isFrameFlowingAt({
|
|
1267
1302
|
seenFrame: sampleRef.current.seenFrame,
|
|
1268
1303
|
lastFrameAtMs: sampleRef.current.lastFrameAtMs,
|
|
1269
1304
|
nowMs: Date.now(),
|
|
1270
1305
|
stallAfterMs: boundedStallMs
|
|
1271
1306
|
});
|
|
1307
|
+
if (!frameFresh && sampleRef.current.seenFrame) recovery.stall();
|
|
1308
|
+
const nextFlowing = frameFresh && recovery.ready;
|
|
1272
1309
|
if (flowingRef.current !== nextFlowing) {
|
|
1273
1310
|
flowingRef.current = nextFlowing;
|
|
1274
1311
|
setFlowing(nextFlowing);
|
|
@@ -1281,7 +1318,7 @@ function useLiveFrameFlow(wrapRef, trackProducing, trackIdentity, stallAfterMs)
|
|
|
1281
1318
|
stopObserving();
|
|
1282
1319
|
cancelFrameCallback();
|
|
1283
1320
|
};
|
|
1284
|
-
}, [wrapRef, trackProducing, trackIdentity, boundedStallMs]);
|
|
1321
|
+
}, [wrapRef, trackProducing, trackIdentity, boundedStallMs, recovery]);
|
|
1285
1322
|
const freezeReading = useCallback(() => {
|
|
1286
1323
|
const sample = sampleRef.current;
|
|
1287
1324
|
const lastFrameAtMs = sample.lastFrameAtMs;
|
|
@@ -1320,19 +1357,19 @@ function useDebouncedHide(wanted, delayMs) {
|
|
|
1320
1357
|
}, [wanted, delayMs]);
|
|
1321
1358
|
return shown;
|
|
1322
1359
|
}
|
|
1323
|
-
function useIdleWhileResting(videoRef, idleVideoUrl, showLive) {
|
|
1360
|
+
function useIdleWhileResting(videoRef, idleVideoUrl, showLive, resetToAnchor) {
|
|
1324
1361
|
useEffect(() => {
|
|
1325
1362
|
const video = videoRef.current;
|
|
1326
1363
|
if (!video || !idleVideoUrl) return;
|
|
1327
|
-
applyIdleRest(video, showLive);
|
|
1328
|
-
}, [videoRef, idleVideoUrl, showLive]);
|
|
1364
|
+
applyIdleRest(video, showLive, resetToAnchor);
|
|
1365
|
+
}, [videoRef, idleVideoUrl, showLive, resetToAnchor]);
|
|
1329
1366
|
}
|
|
1330
|
-
function applyIdleRest(video, showLive) {
|
|
1367
|
+
function applyIdleRest(video, showLive, resetToAnchor = true) {
|
|
1331
1368
|
if (showLive) {
|
|
1332
1369
|
video.pause();
|
|
1333
1370
|
return;
|
|
1334
1371
|
}
|
|
1335
|
-
if (video.currentTime !== 0) video.currentTime = 0;
|
|
1372
|
+
if (resetToAnchor && video.currentTime !== 0) video.currentTime = 0;
|
|
1336
1373
|
if (video.paused) void Promise.resolve(video.play()).catch(() => {
|
|
1337
1374
|
});
|
|
1338
1375
|
}
|
package/dist/server.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, isQueued, verifyTranscript } from './chunk-
|
|
1
|
+
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, isQueued, verifyTranscript } from './chunk-F7E4HMBW.js';
|
package/dist/tanstack-start.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "realtime-avatar",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Realtime Avatar SDK. `realtime-avatar` and the route adapters hold your API key and are server-only; `realtime-avatar/react`, `/browser` and `/tools` never can — importing a server entry into a browser build throws at bundle time.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "The Influence Company",
|