@xmov/avatar 2.0.0-alpha.38
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/README.md +139 -0
- package/dist/agent/__tests__/agent.test.d.ts +1 -0
- package/dist/agent/audio-debug.d.ts +3 -0
- package/dist/agent/audio-uplink.d.ts +62 -0
- package/dist/agent/avatar.cjs +2 -0
- package/dist/agent/avatar.cjs.map +1 -0
- package/dist/agent/avatar.modern.js +2 -0
- package/dist/agent/avatar.modern.js.map +1 -0
- package/dist/agent/avatar.module.js +2 -0
- package/dist/agent/avatar.module.js.map +1 -0
- package/dist/agent/avatar.umd.js +2 -0
- package/dist/agent/avatar.umd.js.map +1 -0
- package/dist/agent/e2e-client.d.ts +32 -0
- package/dist/agent/fixed-audio-track.d.ts +48 -0
- package/dist/agent/index.cjs +5 -0
- package/dist/agent/index.d.ts +104 -0
- package/dist/agent/index.umd.js +10 -0
- package/dist/agent/microphone.d.ts +49 -0
- package/dist/agent/types.d.ts +153 -0
- package/dist/baseRender/AudioRenderer.d.ts +46 -0
- package/dist/baseRender/AudioWorklet.d.ts +78 -0
- package/dist/baseRender/AvatarRenderer.d.ts +226 -0
- package/dist/baseRender/MSEAudioPlayer.d.ts +51 -0
- package/dist/baseRender/UIRenderer.d.ts +39 -0
- package/dist/baseRender/pcm-audio-processor.d.ts +63 -0
- package/dist/control/APIForwarder.d.ts +23 -0
- package/dist/control/DataCacheQueue.d.ts +69 -0
- package/dist/control/EventDispatcher.d.ts +35 -0
- package/dist/control/RenderScheduler.d.ts +162 -0
- package/dist/control/SaveAndDownload.d.ts +14 -0
- package/dist/control/StreamingClient.d.ts +33 -0
- package/dist/control/VideoPlayer.d.ts +47 -0
- package/dist/control/ttsa.d.ts +111 -0
- package/dist/encoding/media-recorder-encoder.d.ts +33 -0
- package/dist/encoding/pcm-webm-encoder.d.ts +13 -0
- package/dist/encoding/webcodec-opus-encoder.d.ts +41 -0
- package/dist/encoding/webm-muxer.d.ts +90 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +231 -0
- package/dist/index.modern.js +2 -0
- package/dist/index.modern.js.map +1 -0
- package/dist/index.module.js +2 -0
- package/dist/index.module.js.map +1 -0
- package/dist/index.umd.js +2 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/modules/Composition.d.ts +28 -0
- package/dist/modules/ResourceManager.d.ts +295 -0
- package/dist/modules/TrackRenderer/base-track.d.ts +4 -0
- package/dist/modules/TrackRenderer/index.d.ts +12 -0
- package/dist/modules/TrackRenderer/render-implements.d.ts +19 -0
- package/dist/modules/TrackRenderer/track-pic.d.ts +8 -0
- package/dist/modules/TrackRenderer/track-subtitle.d.ts +8 -0
- package/dist/modules/cache-manager.d.ts +5 -0
- package/dist/modules/decoder.d.ts +84 -0
- package/dist/modules/error-handle.d.ts +17 -0
- package/dist/modules/network.d.ts +21 -0
- package/dist/proto/face_data_pb.d.ts +0 -0
- package/dist/types/capability.d.ts +15 -0
- package/dist/types/error.d.ts +70 -0
- package/dist/types/event.d.ts +25 -0
- package/dist/types/frame-data.d.ts +107 -0
- package/dist/types/index.d.ts +187 -0
- package/dist/types/render.d.ts +18 -0
- package/dist/utils/DataInterface.d.ts +113 -0
- package/dist/utils/GLDevice.d.ts +46 -0
- package/dist/utils/GLPipeline.d.ts +84 -0
- package/dist/utils/GLPipelineDebugTools.d.ts +5 -0
- package/dist/utils/Math.d.ts +21 -0
- package/dist/utils/__tests__/capability-checker.test.d.ts +1 -0
- package/dist/utils/audio-session.d.ts +11 -0
- package/dist/utils/audio.d.ts +1 -0
- package/dist/utils/capability-checker.d.ts +23 -0
- package/dist/utils/encodeToken.d.ts +7 -0
- package/dist/utils/face.d.ts +1 -0
- package/dist/utils/float32-decoder.d.ts +26 -0
- package/dist/utils/fpsTracker.d.ts +27 -0
- package/dist/utils/index.d.ts +22 -0
- package/dist/utils/logger.d.ts +9 -0
- package/dist/utils/media-recorder-timestamp.d.ts +15 -0
- package/dist/utils/pcmAnalyzer.d.ts +40 -0
- package/dist/utils/perfermance.d.ts +15 -0
- package/dist/utils/request.d.ts +19 -0
- package/dist/utils/requestAnimateFrames.d.ts +31 -0
- package/dist/utils/time.d.ts +9 -0
- package/dist/view/DebugOverlay.d.ts +54 -0
- package/dist/worker/streaming-video.d.ts +1 -0
- package/package.json +82 -0
- package/src/agent/__tests__/agent.test.ts +3787 -0
- package/src/agent/audio-debug.ts +36 -0
- package/src/agent/audio-uplink.ts +392 -0
- package/src/agent/e2e-client.ts +215 -0
- package/src/agent/fixed-audio-track.ts +547 -0
- package/src/agent/index.ts +1393 -0
- package/src/agent/microphone.ts +534 -0
- package/src/agent/types.ts +197 -0
- package/src/baseRender/AudioRenderer.ts +317 -0
- package/src/baseRender/AudioWorklet.ts +776 -0
- package/src/baseRender/AvatarRenderer.ts +1559 -0
- package/src/baseRender/MSEAudioPlayer.ts +243 -0
- package/src/baseRender/UIRenderer.ts +195 -0
- package/src/baseRender/pcm-audio-processor.js +267 -0
- package/src/control/APIForwarder.ts +67 -0
- package/src/control/DataCacheQueue.ts +372 -0
- package/src/control/EventDispatcher.ts +106 -0
- package/src/control/RenderScheduler.ts +945 -0
- package/src/control/SaveAndDownload.js +77 -0
- package/src/control/StreamingClient.ts +138 -0
- package/src/control/VideoPlayer.ts +306 -0
- package/src/control/ttsa.ts +676 -0
- package/src/encoding/media-recorder-encoder.ts +175 -0
- package/src/encoding/pcm-webm-encoder.ts +72 -0
- package/src/encoding/webcodec-opus-encoder.ts +258 -0
- package/src/encoding/webm-muxer.ts +337 -0
- package/src/global.d.ts +105 -0
- package/src/index.ts +1920 -0
- package/src/modules/Composition.ts +79 -0
- package/src/modules/ResourceManager.ts +899 -0
- package/src/modules/TrackRenderer/base-track.ts +7 -0
- package/src/modules/TrackRenderer/index.ts +40 -0
- package/src/modules/TrackRenderer/render-implements.ts +269 -0
- package/src/modules/TrackRenderer/track-pic.ts +19 -0
- package/src/modules/TrackRenderer/track-subtitle.ts +16 -0
- package/src/modules/cache-manager.ts +10 -0
- package/src/modules/decoder.ts +515 -0
- package/src/modules/error-handle.ts +20 -0
- package/src/modules/network.ts +71 -0
- package/src/proto/face_data.proto +45 -0
- package/src/proto/face_data_pb.js +1297 -0
- package/src/proto/protobuf.min.js +8 -0
- package/src/types/capability.ts +23 -0
- package/src/types/error.ts +211 -0
- package/src/types/event.ts +38 -0
- package/src/types/frame-data.ts +121 -0
- package/src/types/index.ts +207 -0
- package/src/types/render.ts +18 -0
- package/src/utils/DataInterface.ts +746 -0
- package/src/utils/GLDevice.ts +286 -0
- package/src/utils/GLPipeline.ts +1293 -0
- package/src/utils/GLPipelineDebugTools.ts +174 -0
- package/src/utils/Math.ts +266 -0
- package/src/utils/__tests__/capability-checker.test.ts +159 -0
- package/src/utils/audio-session.ts +144 -0
- package/src/utils/audio.ts +44 -0
- package/src/utils/blueimp-md5.d.ts +3 -0
- package/src/utils/capability-checker.ts +379 -0
- package/src/utils/encodeToken.ts +100 -0
- package/src/utils/face.ts +29 -0
- package/src/utils/float32-decoder.js +130 -0
- package/src/utils/fpsTracker.ts +100 -0
- package/src/utils/index.ts +182 -0
- package/src/utils/logger.js +36 -0
- package/src/utils/media-recorder-timestamp.ts +79 -0
- package/src/utils/pcmAnalyzer.ts +154 -0
- package/src/utils/perfermance.ts +141 -0
- package/src/utils/request.ts +95 -0
- package/src/utils/requestAnimateFrames.ts +195 -0
- package/src/utils/time.ts +32 -0
- package/src/view/DebugOverlay.ts +404 -0
- package/src/worker/streaming-video.ts +4647 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { AgentClientMessage, AgentServerEvent, AgentSocketState } from "./types";
|
|
2
|
+
export interface AgentE2EClientOptions {
|
|
3
|
+
wsUrl: string;
|
|
4
|
+
token: string;
|
|
5
|
+
audioInputEnabled?: boolean;
|
|
6
|
+
WebSocketCtor?: typeof WebSocket;
|
|
7
|
+
onStateChange?: (state: AgentSocketState) => void;
|
|
8
|
+
onEvent?: (event: AgentServerEvent) => void;
|
|
9
|
+
onError?: (error: Error) => void;
|
|
10
|
+
onClose?: (event: CloseEvent) => void;
|
|
11
|
+
}
|
|
12
|
+
export declare class AgentE2EClient {
|
|
13
|
+
private ws;
|
|
14
|
+
private connectPromise;
|
|
15
|
+
private rejectConnect;
|
|
16
|
+
private audioInputEnabled;
|
|
17
|
+
private readonly WebSocketCtor;
|
|
18
|
+
private readonly options;
|
|
19
|
+
constructor(options: AgentE2EClientOptions);
|
|
20
|
+
get isOpen(): boolean;
|
|
21
|
+
connect(): Promise<void>;
|
|
22
|
+
disconnect(code?: number, reason?: string): void;
|
|
23
|
+
send(message: AgentClientMessage): void;
|
|
24
|
+
trySend(message: AgentClientMessage): boolean;
|
|
25
|
+
sendBinary(frame: ArrayBuffer | ArrayBufferView | Blob): void;
|
|
26
|
+
ping(): void;
|
|
27
|
+
setAudioInputEnabled(enabled: boolean): void;
|
|
28
|
+
private assertOpen;
|
|
29
|
+
private parseMessage;
|
|
30
|
+
private buildWsUrl;
|
|
31
|
+
private updateAudioInputQuery;
|
|
32
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export interface FixedAudioTrackOptions {
|
|
2
|
+
onError?: (error: Error) => void;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Converts a microphone MediaStreamTrack to a verifiable 16 kHz mono track
|
|
6
|
+
* before it is handed to MediaRecorder. WebM/Opus remains the container/codec
|
|
7
|
+
* used on the wire; this class only owns the decoded audio track conversion.
|
|
8
|
+
*/
|
|
9
|
+
export declare class FixedAudioTrack {
|
|
10
|
+
private readonly options;
|
|
11
|
+
private inputTrack;
|
|
12
|
+
private reader;
|
|
13
|
+
private writer;
|
|
14
|
+
private generator;
|
|
15
|
+
private audioContext;
|
|
16
|
+
private audioSource;
|
|
17
|
+
private audioDestination;
|
|
18
|
+
private pumpPromise;
|
|
19
|
+
private pumpFinished;
|
|
20
|
+
private outputClosed;
|
|
21
|
+
private draining;
|
|
22
|
+
private inputSampleRate;
|
|
23
|
+
private resampleBuffer;
|
|
24
|
+
private resamplePosition;
|
|
25
|
+
private outputBuffer;
|
|
26
|
+
private outputTimestamp;
|
|
27
|
+
private startGeneration;
|
|
28
|
+
constructor(options?: FixedAudioTrackOptions);
|
|
29
|
+
start(inputTrack: MediaStreamTrack): Promise<MediaStream>;
|
|
30
|
+
private startWebAudio;
|
|
31
|
+
stop(): Promise<void>;
|
|
32
|
+
/** Stop input and flush decoded samples while keeping the output track live. */
|
|
33
|
+
drain(): Promise<void>;
|
|
34
|
+
private closeOutput;
|
|
35
|
+
private closeWebAudioOutput;
|
|
36
|
+
private pump;
|
|
37
|
+
private toMono;
|
|
38
|
+
private resample;
|
|
39
|
+
private writeChunk;
|
|
40
|
+
private validateAudioData;
|
|
41
|
+
private delay;
|
|
42
|
+
private stopGenerator;
|
|
43
|
+
private unsupported;
|
|
44
|
+
private contextSuspended;
|
|
45
|
+
private assertStartActive;
|
|
46
|
+
private normalizeWebAudioError;
|
|
47
|
+
private validateOutputTrack;
|
|
48
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import XmovAvatar from "../index";
|
|
2
|
+
import type { ISessionResponse } from "../modules/ResourceManager";
|
|
3
|
+
import type { AgentASRStartOptions, AgentASRState, AgentState, XingyunAvatarAgentInitParams, XingyunAvatarAgentOptions } from "./types";
|
|
4
|
+
export default class XingyunAvatarAgent extends XmovAvatar {
|
|
5
|
+
private e2eClient;
|
|
6
|
+
private microphone;
|
|
7
|
+
private stopASRPromise;
|
|
8
|
+
private initializationPromise;
|
|
9
|
+
private rejectInitialization;
|
|
10
|
+
private initialSessionAttempt;
|
|
11
|
+
private initialSessionGeneration;
|
|
12
|
+
private readonly initialTtsaReadySessionIds;
|
|
13
|
+
private initialTtsaReadyBeforeSession;
|
|
14
|
+
private asrStartGeneration;
|
|
15
|
+
private agentState;
|
|
16
|
+
private asrState;
|
|
17
|
+
private agentDestroyed;
|
|
18
|
+
private agentDestroying;
|
|
19
|
+
private suppressNextVoiceEnd;
|
|
20
|
+
private audioInputEnabled;
|
|
21
|
+
private farendAudioEnabled;
|
|
22
|
+
private readonly audioUplink;
|
|
23
|
+
private originalOnAudioPlaybackData?;
|
|
24
|
+
private playbackDataHandler?;
|
|
25
|
+
private readonly agentOptions;
|
|
26
|
+
private readonly reconnectOptions;
|
|
27
|
+
private reconnectTimer;
|
|
28
|
+
private reconnectAttempt;
|
|
29
|
+
private reconnectInFlight;
|
|
30
|
+
private sessionReloadFallback;
|
|
31
|
+
private waitingForTtsaReload;
|
|
32
|
+
private stateBeforeReconnect;
|
|
33
|
+
private reportingInitializationFailure;
|
|
34
|
+
private readonly handleOnlineForReconnect;
|
|
35
|
+
constructor(options: XingyunAvatarAgentOptions);
|
|
36
|
+
getAgentState(): AgentState;
|
|
37
|
+
getState(): AgentState;
|
|
38
|
+
getASRState(): AgentASRState;
|
|
39
|
+
init(params?: XingyunAvatarAgentInitParams): Promise<ISessionResponse | null | undefined>;
|
|
40
|
+
private initialize;
|
|
41
|
+
private beginInitialSession;
|
|
42
|
+
start(): void;
|
|
43
|
+
protected onTtsaReady(sessionInfo?: ISessionResponse): void;
|
|
44
|
+
private abortInitialization;
|
|
45
|
+
stop(): Promise<void>;
|
|
46
|
+
speak(...args: Parameters<XmovAvatar["speak"]>): string | undefined;
|
|
47
|
+
destroy(reason?: string): Promise<void>;
|
|
48
|
+
ask(text: string): Promise<void>;
|
|
49
|
+
speakByE2E(text: string): Promise<void>;
|
|
50
|
+
startASR(options?: AgentASRStartOptions): Promise<void>;
|
|
51
|
+
private cloneASRInputStream;
|
|
52
|
+
private assertASRStartActive;
|
|
53
|
+
stopASR(): Promise<void>;
|
|
54
|
+
private finishStopASR;
|
|
55
|
+
interruptConversation(reason?: string): Promise<void>;
|
|
56
|
+
protected onSessionReloaded(sessionInfo: ISessionResponse): Promise<void>;
|
|
57
|
+
protected onSessionReloadExhausted(error?: unknown): void;
|
|
58
|
+
reloadSuccess(): void;
|
|
59
|
+
private replaceE2EConnection;
|
|
60
|
+
private resolveE2EConnection;
|
|
61
|
+
private sendControl;
|
|
62
|
+
private assertAudioChunkDuration;
|
|
63
|
+
private sendAudioFrame;
|
|
64
|
+
private handleAudioUplinkError;
|
|
65
|
+
private applySessionFeatures;
|
|
66
|
+
private forwardFarendAudio;
|
|
67
|
+
private handleMicrophoneError;
|
|
68
|
+
private finishFailedASR;
|
|
69
|
+
private enableAudioInput;
|
|
70
|
+
private disableAudioInput;
|
|
71
|
+
private handleServerEvent;
|
|
72
|
+
private handleASRResult;
|
|
73
|
+
private handleLLMResponse;
|
|
74
|
+
private handleSemanticJudgeResult;
|
|
75
|
+
private forwardVoiceEnd;
|
|
76
|
+
private readFiniteNumber;
|
|
77
|
+
private handleBackendError;
|
|
78
|
+
private handleSocketClose;
|
|
79
|
+
private shouldReconnect;
|
|
80
|
+
private beginReconnect;
|
|
81
|
+
private scheduleE2EReconnect;
|
|
82
|
+
private attemptE2EReconnect;
|
|
83
|
+
private fallbackToSessionReload;
|
|
84
|
+
private finishReconnect;
|
|
85
|
+
private failReconnect;
|
|
86
|
+
private cancelReconnect;
|
|
87
|
+
private clearReconnectTimer;
|
|
88
|
+
private getReconnectDelay;
|
|
89
|
+
private readRestorableState;
|
|
90
|
+
private normalizeReconnectOptions;
|
|
91
|
+
private readNonNegativeNumber;
|
|
92
|
+
private stopASRAfterSocketClose;
|
|
93
|
+
private setAgentState;
|
|
94
|
+
private setASRState;
|
|
95
|
+
private emitConversation;
|
|
96
|
+
private emitError;
|
|
97
|
+
private safeEmit;
|
|
98
|
+
private assertRunning;
|
|
99
|
+
private assertE2EOpen;
|
|
100
|
+
private assertNotDestroyed;
|
|
101
|
+
}
|
|
102
|
+
export * from "./types";
|
|
103
|
+
export { AgentE2EClient } from "./e2e-client";
|
|
104
|
+
export { MicrophoneController } from "./microphone";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
(function (root) {
|
|
2
|
+
var entry = root.XingyunAvatarAgentModule;
|
|
3
|
+
if (!entry || !entry.default) {
|
|
4
|
+
throw new Error("XingyunAvatarAgentModule must be loaded before XingyunAvatarAgent");
|
|
5
|
+
}
|
|
6
|
+
root.XingyunAvatarAgent = entry.default;
|
|
7
|
+
root.XingyunAvatarAgent.AgentE2EClient = entry.AgentE2EClient;
|
|
8
|
+
root.XingyunAvatarAgent.DEFAULT_AGENT_AUDIO = entry.DEFAULT_AGENT_AUDIO;
|
|
9
|
+
root.XingyunAvatarAgent.MicrophoneController = entry.MicrophoneController;
|
|
10
|
+
}(typeof self !== "undefined" ? self : this));
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { AgentAudioMetadata, AgentAudioOptions } from "./types";
|
|
2
|
+
export interface MicrophoneControllerOptions {
|
|
3
|
+
audio?: AgentAudioOptions;
|
|
4
|
+
debugAudioChunks?: boolean;
|
|
5
|
+
/** Agent-owned input stream. When omitted, the controller requests the microphone. */
|
|
6
|
+
inputStream?: MediaStream;
|
|
7
|
+
/** Use deterministic 100ms PCM buckets with WebCodecs Opus encoding. */
|
|
8
|
+
usePcmWebCodecs?: boolean;
|
|
9
|
+
onMetadata?: (metadata: AgentAudioMetadata) => void;
|
|
10
|
+
/** WebM/Opus Blob callback; timestamp is the media-block start time. */
|
|
11
|
+
onFrame: (frame: Blob, timestamp?: number) => void;
|
|
12
|
+
onError?: (error: Error) => void;
|
|
13
|
+
}
|
|
14
|
+
export declare class MicrophoneController {
|
|
15
|
+
private stream;
|
|
16
|
+
private pendingInputStream;
|
|
17
|
+
private recordingStream;
|
|
18
|
+
private audioTransformer;
|
|
19
|
+
private mediaRecorder;
|
|
20
|
+
private pcmAudioContext;
|
|
21
|
+
private pcmSource;
|
|
22
|
+
private pcmWorklet;
|
|
23
|
+
private pcmEncoder;
|
|
24
|
+
private pcmEncodeQueue;
|
|
25
|
+
private pcmStartedAt;
|
|
26
|
+
private pcmGeneration;
|
|
27
|
+
private resolvePcmFlush;
|
|
28
|
+
private startGeneration;
|
|
29
|
+
private starting;
|
|
30
|
+
private hasAudioSessionCapture;
|
|
31
|
+
private metadata;
|
|
32
|
+
private readonly options;
|
|
33
|
+
private readonly usesProvidedInput;
|
|
34
|
+
constructor(options: MicrophoneControllerOptions);
|
|
35
|
+
get isRecording(): boolean;
|
|
36
|
+
getAudioMetadata(): AgentAudioMetadata;
|
|
37
|
+
start(): Promise<void>;
|
|
38
|
+
stop(): Promise<void>;
|
|
39
|
+
private startWebMRecorder;
|
|
40
|
+
private assertStartActive;
|
|
41
|
+
private cancelled;
|
|
42
|
+
private webMOpusUnsupported;
|
|
43
|
+
private webCodecsOpusUnsupported;
|
|
44
|
+
private startPcmWebMRecorder;
|
|
45
|
+
private stopPcmWebMRecorder;
|
|
46
|
+
private monotonicEpochNow;
|
|
47
|
+
private audioContextSuspended;
|
|
48
|
+
private stopMediaRecorder;
|
|
49
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import type { IAvatarOptions, IInitParams, INetworkInfo, RenderState } from "../types";
|
|
2
|
+
export type AgentState = "idle" | "initializing" | "ready" | "running" | "reconnecting" | "stopped" | "destroyed" | "failed";
|
|
3
|
+
export type AgentSocketState = "idle" | "connecting" | "open" | "closed" | "error";
|
|
4
|
+
export type AgentASRState = "idle" | "requesting-permission" | "starting" | "listening" | "stopping" | "failed";
|
|
5
|
+
export type AgentConversationState = "idle" | "asking" | "speaking-directly" | "speaking" | "completed" | "interrupted" | "failed";
|
|
6
|
+
export type AgentErrorDomain = "permission" | "network" | "asr" | "brain" | "ttsa" | "quota" | "sdk";
|
|
7
|
+
export interface AgentAudioOptions {
|
|
8
|
+
chunkMs?: number;
|
|
9
|
+
inputEnabled?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* @deprecated Session 返回 features.speech_frontend.enable_aec 后,以服务端返回值为准。
|
|
12
|
+
*/
|
|
13
|
+
echoCancellationEnabled?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface AgentReconnectOptions {
|
|
16
|
+
enabled?: boolean;
|
|
17
|
+
maxAttempts?: number;
|
|
18
|
+
initialDelayMs?: number;
|
|
19
|
+
maxDelayMs?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface AgentError {
|
|
22
|
+
code: string;
|
|
23
|
+
message: string;
|
|
24
|
+
domain: AgentErrorDomain;
|
|
25
|
+
retryable?: boolean;
|
|
26
|
+
cause?: unknown;
|
|
27
|
+
}
|
|
28
|
+
export interface AgentASRResult {
|
|
29
|
+
text: string;
|
|
30
|
+
isFinal: boolean;
|
|
31
|
+
raw?: unknown;
|
|
32
|
+
}
|
|
33
|
+
export interface AgentASRStartOptions {
|
|
34
|
+
/**
|
|
35
|
+
* Optional caller-owned audio stream used instead of requesting the physical microphone.
|
|
36
|
+
* The Agent clones one live audio track and never stops the caller-owned stream.
|
|
37
|
+
*/
|
|
38
|
+
inputStream?: MediaStream;
|
|
39
|
+
}
|
|
40
|
+
export interface AgentLLMUsage {
|
|
41
|
+
promptTokens: number;
|
|
42
|
+
completionTokens: number;
|
|
43
|
+
totalTokens: number;
|
|
44
|
+
cachedTokens: number;
|
|
45
|
+
}
|
|
46
|
+
export interface AgentLLMResponse {
|
|
47
|
+
event: "chunk" | "done";
|
|
48
|
+
text?: string;
|
|
49
|
+
isFirst?: boolean;
|
|
50
|
+
usage?: AgentLLMUsage;
|
|
51
|
+
raw?: unknown;
|
|
52
|
+
}
|
|
53
|
+
export interface AgentSemanticJudgeResult {
|
|
54
|
+
query: string;
|
|
55
|
+
meaningful: boolean;
|
|
56
|
+
action: string;
|
|
57
|
+
raw?: unknown;
|
|
58
|
+
}
|
|
59
|
+
export interface AgentSpeakStateEvent {
|
|
60
|
+
state: string;
|
|
61
|
+
clientSpeakId?: string | number;
|
|
62
|
+
raw?: unknown;
|
|
63
|
+
}
|
|
64
|
+
export interface AgentConversationEvent {
|
|
65
|
+
state: AgentConversationState;
|
|
66
|
+
text?: string;
|
|
67
|
+
raw?: unknown;
|
|
68
|
+
}
|
|
69
|
+
export interface XingyunAvatarAgentCallbacks {
|
|
70
|
+
onAgentStateChange?: (state: AgentState) => void;
|
|
71
|
+
onSocketStateChange?: (state: AgentSocketState) => void;
|
|
72
|
+
onASRStateChange?: (state: AgentASRState) => void;
|
|
73
|
+
onASRResult?: (result: AgentASRResult) => void;
|
|
74
|
+
onLLMResponse?: (response: AgentLLMResponse) => void;
|
|
75
|
+
onSpeakStateChange?: (event: AgentSpeakStateEvent) => void;
|
|
76
|
+
onConversationChange?: (event: AgentConversationEvent) => void;
|
|
77
|
+
onSemanticJudgeResult?: (result: AgentSemanticJudgeResult) => void;
|
|
78
|
+
onRenderChange?: (state: RenderState) => void;
|
|
79
|
+
onNetworkInfo?: (info: INetworkInfo) => void;
|
|
80
|
+
onError?: (error: AgentError) => void;
|
|
81
|
+
}
|
|
82
|
+
export type AgentServiceConfig = Record<string, unknown>;
|
|
83
|
+
export interface AgentBrainConfig extends AgentServiceConfig {
|
|
84
|
+
extra_body?: Record<string, unknown>;
|
|
85
|
+
}
|
|
86
|
+
export interface AgentFeatures extends AgentServiceConfig {
|
|
87
|
+
anti_interference?: {
|
|
88
|
+
semantic_judge_enabled?: boolean;
|
|
89
|
+
};
|
|
90
|
+
speech_frontend?: {
|
|
91
|
+
enabled?: boolean;
|
|
92
|
+
enable_aec?: boolean;
|
|
93
|
+
enable_speech_separation?: boolean;
|
|
94
|
+
};
|
|
95
|
+
vad_merge_mode?: boolean;
|
|
96
|
+
volume_and_repetition_text_detection?: boolean;
|
|
97
|
+
}
|
|
98
|
+
export interface XingyunAvatarAgentOptions extends IAvatarOptions {
|
|
99
|
+
asr_id?: number;
|
|
100
|
+
asr_config?: AgentServiceConfig;
|
|
101
|
+
tts_config?: AgentServiceConfig;
|
|
102
|
+
features?: AgentFeatures;
|
|
103
|
+
extras?: AgentServiceConfig;
|
|
104
|
+
llm_id?: number;
|
|
105
|
+
brain_config?: AgentBrainConfig;
|
|
106
|
+
session_speak_req_id?: 0 | 1;
|
|
107
|
+
e2eServer?: string;
|
|
108
|
+
authToken?: string;
|
|
109
|
+
audio?: AgentAudioOptions;
|
|
110
|
+
reconnect?: AgentReconnectOptions;
|
|
111
|
+
agentCallbacks?: XingyunAvatarAgentCallbacks;
|
|
112
|
+
webSocketCtor?: typeof WebSocket;
|
|
113
|
+
}
|
|
114
|
+
export type XingyunAvatarAgentInitParams = Omit<IInitParams, "onDownloadProgress"> & {
|
|
115
|
+
onDownloadProgress?: IInitParams["onDownloadProgress"];
|
|
116
|
+
};
|
|
117
|
+
export interface AgentSessionInfo {
|
|
118
|
+
ws_url?: string;
|
|
119
|
+
e2e_token?: string;
|
|
120
|
+
monitor_ws_url?: string;
|
|
121
|
+
}
|
|
122
|
+
export interface AgentClientMessage {
|
|
123
|
+
type: string;
|
|
124
|
+
message?: unknown;
|
|
125
|
+
[key: string]: unknown;
|
|
126
|
+
}
|
|
127
|
+
export interface AgentServerEvent {
|
|
128
|
+
type: string;
|
|
129
|
+
domain?: string;
|
|
130
|
+
code?: string | number;
|
|
131
|
+
event?: string;
|
|
132
|
+
message?: unknown;
|
|
133
|
+
text?: string;
|
|
134
|
+
is_first?: boolean;
|
|
135
|
+
is_final?: boolean;
|
|
136
|
+
usage?: {
|
|
137
|
+
prompt_tokens?: number;
|
|
138
|
+
completion_tokens?: number;
|
|
139
|
+
total_tokens?: number;
|
|
140
|
+
cached_tokens?: number;
|
|
141
|
+
};
|
|
142
|
+
[key: string]: unknown;
|
|
143
|
+
}
|
|
144
|
+
export interface AgentAudioMetadata {
|
|
145
|
+
format: "webm_opus";
|
|
146
|
+
mimeType: "audio/webm;codecs=opus";
|
|
147
|
+
/** Fixed output track sample rate passed to the MediaRecorder pipeline. */
|
|
148
|
+
sampleRate: number;
|
|
149
|
+
/** Fixed output track channel count passed to the MediaRecorder pipeline. */
|
|
150
|
+
channels: number;
|
|
151
|
+
chunkMs: number;
|
|
152
|
+
}
|
|
153
|
+
export declare const DEFAULT_AGENT_AUDIO: AgentAudioMetadata;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 音频渲染
|
|
3
|
+
* 使用 AudioContext 控制
|
|
4
|
+
*/
|
|
5
|
+
import ResourceManager from "../modules/ResourceManager";
|
|
6
|
+
import { DataCacheQueue } from "../control/DataCacheQueue";
|
|
7
|
+
import AudioWorklet from "./AudioWorklet";
|
|
8
|
+
import XmovAvatar from "../index";
|
|
9
|
+
type Option = {
|
|
10
|
+
sdk: XmovAvatar;
|
|
11
|
+
dataCacheQueue: DataCacheQueue;
|
|
12
|
+
resourceManager: ResourceManager;
|
|
13
|
+
};
|
|
14
|
+
export default class AudioRender {
|
|
15
|
+
private TAG;
|
|
16
|
+
private options;
|
|
17
|
+
isPlaying: boolean;
|
|
18
|
+
lastFrameIndex: number;
|
|
19
|
+
audio: AudioWorklet | null;
|
|
20
|
+
firstFrameIndex: number;
|
|
21
|
+
resourceManager: ResourceManager;
|
|
22
|
+
valume: number;
|
|
23
|
+
speech_id: number;
|
|
24
|
+
cacheFirstFrameIndex: number;
|
|
25
|
+
cacheAudioData: Uint8Array[];
|
|
26
|
+
oldSpeechId: number;
|
|
27
|
+
mseCacheAudioData: Array<{
|
|
28
|
+
data: ArrayBuffer;
|
|
29
|
+
frameIndex?: number;
|
|
30
|
+
speechId?: number;
|
|
31
|
+
}>;
|
|
32
|
+
private mseAudioPlayer;
|
|
33
|
+
constructor(options: Option);
|
|
34
|
+
updateAudioData(audioList: any): void;
|
|
35
|
+
_updateAudio(audioList: any): void;
|
|
36
|
+
render(frameIndex: number): Promise<void>;
|
|
37
|
+
resume(): void;
|
|
38
|
+
pause(): void;
|
|
39
|
+
stop(speech_id: number): void;
|
|
40
|
+
addNewAudioSegment(): void;
|
|
41
|
+
setVolume(valume: number): void;
|
|
42
|
+
setSpeed(speed: number): void;
|
|
43
|
+
getAudioPlayer(): AudioWorklet | null;
|
|
44
|
+
destroy(): void;
|
|
45
|
+
}
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web Audio Worklet版PCM流式播放器(24kHz采样率、S16LE单声道)
|
|
3
|
+
* 核心:无定时器,依赖AudioWorklet的process方法实时处理流式数据
|
|
4
|
+
*/
|
|
5
|
+
export default class PCMAudioPlayer {
|
|
6
|
+
readonly SAMPLE_RATE: number;
|
|
7
|
+
readonly FRAME_ALIGNMENT: number;
|
|
8
|
+
readonly WORKLET_SCRIPT_URL: string;
|
|
9
|
+
audioCtx: AudioContext | null;
|
|
10
|
+
audioWorkletNode: AudioWorkletNode | null;
|
|
11
|
+
isInitialized: boolean;
|
|
12
|
+
isPlaying: boolean;
|
|
13
|
+
private destroyResolve;
|
|
14
|
+
private unsubscribePlaybackSessionRestored;
|
|
15
|
+
private captureWorklet;
|
|
16
|
+
private captureCallback;
|
|
17
|
+
/**
|
|
18
|
+
* 初始化(加载Worklet + 创建AudioContext + 连接节点)
|
|
19
|
+
* @returns {Promise<void>} 初始化结果(需用户交互中调用)
|
|
20
|
+
*/
|
|
21
|
+
init(): Promise<void>;
|
|
22
|
+
private refreshPlaybackRoute;
|
|
23
|
+
/**
|
|
24
|
+
* 接收PCM音频流(流式下发到Worklet,无本地缓存)
|
|
25
|
+
* @param {Uint8Array} pcmData - 24kHz S16LE单声道PCM数据
|
|
26
|
+
*/
|
|
27
|
+
receivePCMStream(pcmData: Uint8Array): void;
|
|
28
|
+
/**
|
|
29
|
+
* 开始播放(激活Worklet的音频生成)
|
|
30
|
+
* @returns {Promise<void>} 启动结果
|
|
31
|
+
*/
|
|
32
|
+
start(): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* 暂停播放(停止Worklet音频生成,保留缓存)
|
|
35
|
+
*/
|
|
36
|
+
pause(): void;
|
|
37
|
+
/**
|
|
38
|
+
* 停止播放(清空Worklet缓存,重置状态)
|
|
39
|
+
*/
|
|
40
|
+
stop(): void;
|
|
41
|
+
/**
|
|
42
|
+
* 销毁播放器(释放所有音频资源,不可恢复)
|
|
43
|
+
* @returns {Promise<void>} 销毁结果
|
|
44
|
+
*/
|
|
45
|
+
destroy(): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* 挂载音频捕获节点(用于 PCM 模式下 ASR 回声消除)
|
|
48
|
+
* 将 PCM 播放器输出连接到 capture worklet,实时捕获重采样后的 16kHz S16LE 数据
|
|
49
|
+
*/
|
|
50
|
+
attachCapture(callback: (data: {
|
|
51
|
+
pcmData: ArrayBuffer;
|
|
52
|
+
hasAudio: boolean;
|
|
53
|
+
}) => void): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* 卸载音频捕获节点
|
|
56
|
+
*/
|
|
57
|
+
detachCapture(): void;
|
|
58
|
+
/**
|
|
59
|
+
* 清空 capture worklet 内部缓冲区
|
|
60
|
+
* 用于打断/会话切换时,避免旧音频数据混入新 session
|
|
61
|
+
*/
|
|
62
|
+
resetCaptureBuffer(): void;
|
|
63
|
+
/**
|
|
64
|
+
* 获取当前播放器状态
|
|
65
|
+
* @returns {Object} 状态对象
|
|
66
|
+
*/
|
|
67
|
+
getStatus(): {
|
|
68
|
+
isInitialized: boolean;
|
|
69
|
+
isPlaying: boolean;
|
|
70
|
+
isWorkletReady: boolean;
|
|
71
|
+
};
|
|
72
|
+
setVolume(valume: number): void;
|
|
73
|
+
setSpeed(speed: number): void;
|
|
74
|
+
/**
|
|
75
|
+
* @returns {Promise<void>} 恢复结果
|
|
76
|
+
*/
|
|
77
|
+
resume(): Promise<void>;
|
|
78
|
+
}
|