🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@byteplus/avatar-web-sdk

Package Overview
Dependencies
Maintainers
24
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@byteplus/avatar-web-sdk - npm Package Compare versions

Comparing version
1.0.1-beta.1
to
1.0.1-beta.2
avatar-web-sdk.es.js

Sorry, the diff of this file is too big to display

+70
import { AvatarErrorCode } from "../types/errors";
/**
* AvatarError - Custom error class for Avatar SDK
*
* @note Use the static factory methods to create errors for consistency
*/
export declare class AvatarError extends Error {
/** Error domain */
readonly domain: string;
/** Error code */
readonly code: AvatarErrorCode;
/** Underlying error (if any) */
readonly cause?: Error;
/** Additional details (if any) */
readonly details?: Record<string, unknown>;
/**
* Create an AvatarError instance
* @param code - Error code
* @param message - Error message (optional, uses default if not provided)
* @param cause - Underlying error (optional)
* @param details - Additional details (optional)
*/
constructor(code: AvatarErrorCode, message?: string, cause?: Error, details?: Record<string, unknown>);
/**
* Create an error with default domain, code and description
* @param code - Error code
* @param message - Error message (optional)
* @returns AvatarError instance
*/
static withCode(code: AvatarErrorCode, message?: string): AvatarError;
/**
* Create an error with default domain, code, description and underlying error
* @param code - Error code
* @param message - Error message (optional)
* @param cause - Underlying error
* @returns AvatarError instance
*/
static withCause(code: AvatarErrorCode, message: string | undefined, cause: Error): AvatarError;
/**
* Create an error with default domain, code, description and additional details
* @param code - Error code
* @param message - Error message (optional)
* @param details - Additional details (optional)
* @returns AvatarError instance
*/
static withDetails(code: AvatarErrorCode, message: string | undefined, details?: Record<string, unknown>): AvatarError;
/**
* Create an error with default domain, code, description, underlying error and additional details
* @param code - Error code
* @param message - Error message (optional)
* @param cause - Underlying error (optional)
* @param details - Additional details (optional)
* @returns AvatarError instance
*/
static withFullDetails(code: AvatarErrorCode, message: string | undefined, cause?: Error, details?: Record<string, unknown>): AvatarError;
/**
* Convert a plain Error to AvatarError (if not already an AvatarError)
* @param error - Error to convert
* @param defaultCode - Default error code if converting a plain Error
* @returns AvatarError instance
*/
static from(error: Error, defaultCode?: AvatarErrorCode): AvatarError;
/**
* Check if an error is an AvatarError with a specific code
* @param error - Error to check
* @param code - Error code to match
* @returns true if the error is an AvatarError with the specified code
*/
static is(error: unknown, code?: AvatarErrorCode): error is AvatarError;
}
import { AvatarSDKConfig, AvatarSessionConfig } from "../types";
import { AvatarSession } from "./AvatarSession";
import { LogManager } from "../logging/LogManager";
/**
* AvatarSDK main class
*
* @note Best practice: Create one instance per application process lifecycle and use it as a singleton.
* @warning The config is immutable after initialization. Any subsequent changes to the config object will not take effect.
*/
export declare class AvatarSDK {
/** Current version of the Avatar Web SDK, populated at build time from package.json. */
static readonly version: string;
/** Configuration for AvatarSDK (readonly) */
readonly config: Readonly<AvatarSDKConfig>;
readonly logger: LogManager;
/**
* Initialize AvatarSDK with configuration
* @param config - Configuration for AvatarSDK
* @throws Error if appKey or secretKey is missing
*/
constructor(config: AvatarSDKConfig);
/**
* Create AvatarSession instance with config
* @param config - Session configuration
* @returns AvatarSession instance
*/
createSession(config: AvatarSessionConfig): AvatarSession;
}
import { EventEmitter } from "eventemitter3";
import { AvatarSDK } from "./AvatarSDK";
import { AvatarSessionConfig, AvatarSessionState, RenderMode, AvatarSessionEvents } from "../types";
/**
* AvatarSession class manages the lifecycle of an avatar session
*
* @note Use `AvatarSDK.createSession()` to create an instance instead of using the constructor directly.
* @warning Once the session ends (either normally or due to an error), the session object becomes invalid
* and cannot be reused. To start a new session, you must create a new AvatarSession instance
* using `AvatarSDK.createSession()`. All resources are automatically cleaned up when the session ends.
*/
export declare class AvatarSession extends EventEmitter<AvatarSessionEvents> {
private readonly _config;
private readonly _avatarSDK;
private _connection;
private _protocol;
private _state;
private _rtcService;
private _webRecorder;
private readonly _localSessionId;
private _sessionId;
/**
* Create AvatarSession instance
* @param config - Session configuration
* @param avatarSDK - AvatarSDK instance
*/
constructor(config: AvatarSessionConfig, avatarSDK: AvatarSDK);
/** Current state of the session */
get state(): AvatarSessionState;
/** Local session identifier */
get localSessionId(): string;
/**
* Start the avatar session
* @returns Promise that resolves when the session starts
* @note If the session is already starting or started, this method will ignore the request
*/
start(): Promise<void>;
/**
* End the avatar session
* @returns Promise that resolves when the session ends
* @note If the session is already idle, ending, or ended, this method will ignore the request
* @warning After calling this method, the session object becomes invalid and cannot be reused.
* All resources (WebRecorder, RTCService, Connection) will be automatically cleaned up.
* The 'end' event will be emitted before cleanup. To start a new session, create a new
* AvatarSession instance using `AvatarSDK.createSession()`.
*/
end(): Promise<void>;
/**
* Set avatar video canvas
* @param container - HTMLDivElement to render avatar video. Pass null to unset the canvas.
* @param mode - Render mode
*/
setAvatarVideoCanvas(container: HTMLDivElement | null, mode: RenderMode): void;
/**
* Start local microphone recording
* @returns Promise that resolves when audio capture starts successfully
* @throws Error if session is not started or audio capture fails to start
* @note Audio format: mono channel, 16000Hz sample rate, int16 sample format, little-endian byte order
*/
startAudioCapture(): Promise<void>;
/**
* Stop local microphone recording
* @returns Promise that resolves when audio capture stops successfully
* @throws Error if audio capture fails to stop
*/
stopAudioCapture(): Promise<void>;
/** Destroy the session and release all resources */
destroy(): void;
private _generateUUID;
private _buildEventParams;
private _trackEvent;
private _sendCreateSessionMessage;
private _sendEndSessionMessage;
private _sendAudioData;
private _generateServerConfig;
private _onConnectionOpen;
private _onConnectionError;
private _onConnectionClose;
private _onConnectionMessage;
private _startRTCService;
private _onRTCReady;
private _onRTCError;
private _onAudioCaptureStart;
private _onAudioCaptureStop;
private _onAudioCaptureFail;
private _onAudioFrame;
private _bytesToHex;
private _handleSessionError;
}
export { AvatarSDK } from "./core/AvatarSDK";
export { AvatarSession } from "./core/AvatarSession";
export { VERSION, getBuildInfo, getRtcVariant } from "./version";
export type { AvatarSDKConfig } from "./types";
export type { AvatarSessionConfig } from "./types";
export type { AvatarSessionState } from "./types";
export type { RenderMode } from "./types";
export type { AudioFrame } from "./types";
export type { AvatarSessionEvents } from "./types";
export type { LogLevel } from "./types";
export type { BuildInfo, RtcVariant } from "./version";
import { LogLevel } from "../types";
interface LogEvents {
verbose: [message: string];
debug: [message: string];
info: [message: string];
warn: [message: string];
error: [message: string];
}
export declare class LogManager {
private logEnabled;
private logLevel;
private readonly moduleName;
private readonly emitter;
constructor(config: {
logEnabled?: boolean;
logLevel?: LogLevel;
moduleName?: string;
});
private shouldLog;
private _pad2;
private _pad3;
private _formatTimestamp;
private formatMessage;
private emitLog;
verbose(message: string, ..._args: unknown[]): void;
debug(message: string, ..._args: unknown[]): void;
info(message: string, ..._args: unknown[]): void;
warn(message: string, ..._args: unknown[]): void;
error(message: string, ..._args: unknown[]): void;
on<K extends keyof LogEvents>(event: K, handler: (...args: LogEvents[K]) => void): void;
off<K extends keyof LogEvents>(event: K, handler: (...args: LogEvents[K]) => void): void;
once<K extends keyof LogEvents>(event: K, handler: (...args: LogEvents[K]) => void): void;
removeAllListeners(event?: keyof LogEvents): void;
setLogLevel(level: LogLevel): void;
getLogLevel(): LogLevel;
setLogEnabled(enabled: boolean): void;
getLogEnabled(): boolean;
}
export {};
interface ConnectServerMessage {
type: "connect";
code?: number;
message?: string;
rtcAppId?: string;
rtcRoomId?: string;
rtcAvatarId?: string;
rtcUserId?: string;
rtcUserToken?: string;
sessionId?: string;
}
interface ErrorServerMessage {
type: "error";
code?: number;
message?: string;
sessionId?: string;
}
interface HeartbeatServerMessage {
type: "heartbeat";
}
type ServerMessage = ConnectServerMessage | ErrorServerMessage | HeartbeatServerMessage;
export declare class Protocol {
serializeStartSession(config: Record<string, unknown>): string;
serializeEndSession(): string;
serializeAudio(pcmData: Uint8Array): Uint8Array;
deserialize(data: unknown): ServerMessage;
private _parseServerMessage;
private _buildServerMessage;
}
export {};
import { EventEmitter } from "eventemitter3";
import { AvatarSDK } from "../core/AvatarSDK";
type ConnectionReadyState = "connecting" | "open" | "closing" | "closed";
interface ConnectionEvents {
open: [];
error: [error: Error];
close: [code: number, reason: string, wasClean: boolean];
message: [message: unknown];
}
export declare class Connection extends EventEmitter<ConnectionEvents> {
private readonly _avatarSDK;
private _ws;
private _readyState;
private _sessionId;
private _xTtLogid;
private _lastHeartbeatTimestamp;
private _heartbeatTimer;
private _disconnectCompleted;
private _disconnectTimeout;
constructor(avatarSDK: AvatarSDK);
get readyState(): ConnectionReadyState;
get sessionId(): string | null;
get xTtLogid(): string | null;
private _getWsStateDescription;
connect(): Promise<void>;
disconnect(): Promise<void>;
sendText(text: string): Promise<void>;
sendBinary(data: Uint8Array): Promise<void>;
private _buildWebSocketUrl;
private _handleMessage;
private _startHeartbeatCheck;
private _stopHeartbeatCheck;
private _completeDisconnect;
destroy(): void;
}
export {};
import { EventEmitter } from "eventemitter3";
import { AvatarSDK } from "../core/AvatarSDK";
import { RenderMode, AudioFrame } from "../types";
import { RTCServiceConfig } from "../types/internal";
interface RTCServiceEvents {
ready: [];
error: [error: Error];
audioCaptureStart: [];
audioCaptureStop: [];
audioCaptureFail: [error: Error];
audioFrame: [frame: AudioFrame];
}
export declare class RTCService extends EventEmitter<RTCServiceEvents> {
private readonly _config;
private readonly _avatarSDK;
private _ready;
private _audioCapturing;
private _startAudioCaptureRequested;
private _audioStreamState;
private _localUserReady;
private _avatarUserAudioReady;
private _avatarUserVideoReady;
private _engine;
constructor(config: RTCServiceConfig, avatarSDK: AvatarSDK);
get ready(): boolean;
start(): Promise<void>;
stop(): Promise<void>;
setAvatarVideoCanvas(container: HTMLDivElement | null, mode: RenderMode): void;
startAudioCapture(): Promise<void>;
stopAudioCapture(): Promise<void>;
private _initializeRTC;
private _bindEngineEvents;
private _unbindEngineEvents;
private _joinRoom;
private _leaveRoom;
private _destroyRTC;
private _setupRemoteVideo;
private _convertRenderMode;
private _startAudioCapture;
private _stopAudioCapture;
private _updateReadyState;
private _handleEngineError;
private _handleConnectionStateChanged;
private _handleAudioDeviceStateChanged;
private _handleUserJoined;
private _handleUserLeave;
private _handleUserPublishStream;
private _handleUserUnpublishStream;
destroy(): void;
}
export {};
import { EventEmitter } from "eventemitter3";
import { AvatarSDK } from "../core/AvatarSDK";
import { AudioFrame } from "../types";
import { AudioRecorderConfig } from "../types/internal";
interface WebRecorderEvents {
start: [];
stop: [];
pause: [];
resume: [];
error: [error: Error];
audioFrame: [frame: AudioFrame];
volumeChange: [volume: {
spl: number;
percent: number;
}];
durationChange: [duration: number];
permissionChange: [state: PermissionState | undefined];
}
declare enum WebRecorderState {
Uninitialized = "Uninitialized",
Initializing = "Initializing",
Initialized = "Initialized",
Recording = "Recording",
Paused = "Paused",
Destroyed = "Destroyed"
}
type WebRecorderStateType = keyof typeof WebRecorderState;
declare class WebRecorder extends EventEmitter<WebRecorderEvents> {
private readonly _config;
private readonly _avatarSDK;
private _audioContext;
private _mediaStream;
private _audioWorklet;
private _analyserNode;
private _state;
private _totalDataLength;
private _fftSize;
private _volumeTimer;
private readonly _channel;
private readonly _sampleRate;
private readonly _sampleFormat;
private readonly _byteOrder;
constructor(config: AudioRecorderConfig, avatarSDK: AvatarSDK);
get state(): WebRecorderStateType;
get recording(): boolean;
get paused(): boolean;
checkMicrophonePermission(): Promise<PermissionState | undefined>;
start(): Promise<void>;
pause(): Promise<void>;
resume(): Promise<void>;
stop(): Promise<void>;
clearData(): void;
private _initialize;
private _setupAudioWorklet;
private _setupAnalyser;
private _processAudioFrame;
private _getBytesPerSample;
private _writeSample;
private _startVolumeMonitoring;
private _stopVolumeMonitoring;
private _postMessageToWorklet;
private _changeState;
private _setupDeviceWatcher;
private _cleanup;
destroy(): void;
}
export { WebRecorder, WebRecorderState };
/**
* Avatar error codes
* Error code range:
* - -1: Unknown error
* - 0xxx: Common errors
* - 1xxx: Connection/WebSocket errors
* - 2xxx: Message/Protocol errors
* - 3xxx: RTC errors
* - 4xxx: Server errors
* - 5xxx: Audio/Permission errors
*/
export declare enum AvatarErrorCode {
/** -1: Unknown error */
Unknown = -1,
/** 0xxx: Common errors */
InvalidParameter = 1,
NotInitialized = 2,
InvalidState = 3,
/** 1xxx: Connection/WebSocket errors */
ConnectionLost = 1001,
ConnectionFailed = 1002,
ConnectionClosed = 1003,
ConnectTimeout = 1004,
DisconnectTimeout = 1005,
SendFailed = 1006,
SocketError = 1007,
/** 2xxx: Message/Protocol errors */
InvalidMessageType = 2001,
MessageParseFailed = 2002,
MessageSerializeFailed = 2003,
InvalidMessageFormat = 2004,
JSONParseFailed = 2005,
InvalidBinaryData = 2006,
/** 3xxx: RTC errors */
RTCEngineCreateFailed = 3001,
RTCEngineNotInitialized = 3002,
RTCRoomCreateFailed = 3003,
RTCJoinRoomFailed = 3004,
RTCAvatarUserLeft = 3005,
RTCAvatarAudioStopped = 3006,
RTCAvatarVideoStopped = 3007,
RTCAudioCaptureFailed = 3008,
RTCAudioDeviceError = 3009,
RTCSetCanvasFailed = 3010,
RTCEngineError = 3011,
RTCStreamNotAvailable = 3012,
/** 4xxx: Server errors */
ServerError = 4001,
ServerConnectFailed = 4002,
ServerErrorMessage = 4003,
SignFailed = 4004,
/** 5xxx: Audio/Permission errors */
MicrophonePermissionDenied = 5001,
AudioRecorderInitFailed = 5002,
AudioWorkletError = 5003,
AudioContextError = 5004
}
/** Error domain for Avatar SDK */
export declare const AVATAR_ERROR_DOMAIN = "com.bytedance.bdavatar.error";
/** Default error description map */
export declare const errorDescriptionMap: Record<AvatarErrorCode, string>;
/**
* Get default error description for error code
* @param code - Error code
* @returns Default error description
*/
export declare function getDefaultErrorDescription(code: AvatarErrorCode): string;
export * from "./errors";
export { AvatarError } from "../core/AvatarError";
/**
* Log level for SDK logging
*/
export type LogLevel = "verbose" | "debug" | "info" | "warn" | "error";
/**
* Environment type
*/
export type Environment = "cn" | "overseas";
/**
* AvatarSDK configuration interface
*/
export interface AvatarSDKConfig {
/** App Key (Required) */
appKey: string;
/** Secret Key (Required) */
secretKey: string;
/** STS Token (Optional) */
stsToken?: string;
/** Enable logging (Optional), default is true */
logEnabled?: boolean;
/** Log level (Optional), default is "info" */
logLevel?: LogLevel;
/** Environment type (Optional), default is "cn" */
environment?: Environment;
/** Extra parameters dictionary (Optional) */
extraDict?: Record<string, unknown>;
}
/**
* AvatarSession configuration interface
*/
export interface AvatarSessionConfig {
/** Avatar image URL (Required). Photo URL of the avatar */
avatarImageUrl: string;
/** Speaker (Required). The speaker ID for TTS */
speaker: string;
/** User prompt (Optional). Custom prompt for the avatar */
userPrompt?: string;
/**
* Speech rate (Optional). Controls the speed of output speech,
* value range [-50, 100], default is 0
*/
speechRate?: number;
/**
* Loudness rate (Optional). Controls the volume of output speech,
* value range [-50, 100], default is 0
*/
loudnessRate?: number;
/** Enable web search (Optional), default is false */
enableWebsearch?: boolean;
/** Extra parameters dictionary (Optional) */
extraParams?: Record<string, unknown>;
}
/**
* Avatar session state
*/
export type AvatarSessionState = "idle" | "starting" | "started" | "ending" | "ended";
/**
* Image or video stream scaling mode
*/
export type RenderMode =
/**
* Fit the view first, default value.
* Video scales proportionally until it fills the view. When video and view dimensions don't match,
* the extra part of the video will be cropped.
*/
"hidden"
/**
* Show all video content first.
* Video scales proportionally to ensure all content is visible. When video and view dimensions don't match,
* the unfilled area of the view will be filled with background color.
*/
| "fit"
/**
* Video adapts to canvas.
* Video scales non-proportionally to fill the view. During this process, the aspect ratio of the video may change.
*/
| "fill";
/**
* Audio frame data structure
*/
export interface AudioFrame {
/** Sample rate of the audio */
sampleRate: number;
/** Number of audio channels */
channel: number;
/** Number of samples in the frame */
samples: number;
/** PCM audio buffer */
buffer: Uint8Array;
}
/**
* AvatarSession event types and their argument signatures
*/
export interface AvatarSessionEvents {
/** Session did start successfully */
start: [];
/** Called when an Avatar session has ended, either by request or due to an error */
end: [error?: Error];
/** Audio capture started successfully */
audioCaptureStart: [];
/** Audio capture stopped */
audioCaptureStop: [];
/** Audio capture error (either start failed or runtime error) */
audioCaptureFail: [error: Error];
/** Audio frame callback from local microphone recording */
audioFrame: [frame: AudioFrame];
}
export interface RTCServiceConfig {
rtcAppId: string;
rtcRoomId: string;
rtcAvatarId: string;
rtcUserId: string;
rtcUserToken: string;
}
/**
* Audio sample format (internal use only)
*/
export type AudioSampleFormat = "int8" | "int16" | "int32" | "float32";
/**
* Audio byte order (internal use only)
*/
export type AudioByteOrder = "little-endian" | "big-endian";
/**
* Audio recorder configuration (internal use only)
*/
export interface AudioRecorderConfig {
channel?: number;
sampleRate?: number;
sampleFormat?: AudioSampleFormat;
byteOrder?: AudioByteOrder;
bufferSizeMs?: number;
}
export declare class CryptoFallback {
private static readonly K;
private static _rightRotate;
private static _padMessage;
static sha256(data: Uint8Array): Uint8Array;
static hmacSha256(key: Uint8Array, data: Uint8Array): Uint8Array;
}
import { AvatarSDKConfig } from "../types";
interface URLSignerResult {
url: string;
headers: Record<string, string>;
queries: Record<string, string>;
}
export declare class URLSigner {
static signWithConfig(config: AvatarSDKConfig): Promise<URLSignerResult | null>;
static signWithConfigBase64(config: AvatarSDKConfig): Promise<string | null>;
private static _getServerInfo;
private static _signerResult;
private static _formatDate;
private static _hexStringFromSHA256;
private static _hexStringFromHMACSHA256;
private static _hashSHA256;
private static _hmacSHA256;
private static _getSignedKey;
private static _hexStringFromData;
private static _canonicalQueryString;
private static _urlEncode;
private static _sortObject;
private static _stringToUint8Array;
}
export {};
export type RtcVariant = "byteplus" | "volcengine";
export interface BuildInfo {
buildTime: string;
gitHash: string;
}
export declare const VERSION: string;
export declare const getRtcVariant: () => RtcVariant;
export declare const getBuildInfo: () => BuildInfo;
+12
-2
{
"name": "@byteplus/avatar-web-sdk",
"version": "1.0.1-beta.1",
"version": "1.0.1-beta.2",
"type": "module",

@@ -19,3 +19,13 @@ "main": "./avatar-web-sdk.es.js",

"files": [
"."
"avatar-web-sdk.es.js",
"index.d.ts",
"version.d.ts",
"core/",
"logging/",
"protocol/",
"services/",
"types/",
"utils/",
"README.md",
"LICENSE"
],

@@ -22,0 +32,0 @@ "publishConfig": {