{"_id":"@avatario/avatario-js-sdk","_rev":"6-ddb40b99de4c23ac93c8ceb95cd0ea18","name":"@avatario/avatario-js-sdk","dist-tags":{"latest":"0.1.8"},"versions":{"0.1.3":{"name":"@avatario/avatario-js-sdk","version":"0.1.3","keywords":["avatario","livekit","video","avatar","sdk"],"author":{"name":"Avatario"},"license":"MIT","_id":"@avatario/avatario-js-sdk@0.1.3","maintainers":[{"name":"kushalavatario","email":"kushal@listen2.it"}],"homepage":"https://github.com/Avatarioai/avatario-js-sdk#readme","bugs":{"url":"https://github.com/Avatarioai/avatario-js-sdk/issues"},"dist":{"shasum":"8b9d4817f32f78fe787429a1c57e77ca4542a2e3","tarball":"https://registry.npmjs.org/@avatario/avatario-js-sdk/-/avatario-js-sdk-0.1.3.tgz","fileCount":6,"integrity":"sha512-A8Wcsznc8bip//STF8vVWLSJ6jAPzMx/W7A2Y+8eAtq/sOYe6Hoaf/CEts5dDlGDIQIOdpm5LLlcR6yuf2EMvg==","signatures":[{"sig":"MEYCIQCiLnokG75OXEvhGRf30IG4SP4w92bjCQsOEO6PhoEXngIhAMMNOOC8B4fuhWX0oOlQsMs8nNBMfa/B35XJU5grKU37","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17478},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","gitHead":"ae781dd21a7ff5f52968b34e6bdec75821e4c141","scripts":{"dev":"tsup src/index.ts --format cjs,esm --dts --watch","build":"tsup src/index.ts --format cjs,esm --dts","clean":"rm -rf dist","prepublishOnly":"npm run build"},"_npmUser":{"name":"kushalavatario","email":"kushal@listen2.it"},"repository":{"url":"git+https://github.com/Avatarioai/avatario-js-sdk.git","type":"git"},"_npmVersion":"10.8.3","description":"JavaScript SDK for integrating Avatario video avatars","directories":{},"_nodeVersion":"22.9.0","dependencies":{"livekit-client":"^1.15.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/avatario-js-sdk_0.1.3_1745578707888_0.09801215993913215","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@avatario/avatario-js-sdk","version":"0.1.4","keywords":["avatario","livekit","video","avatar","sdk"],"author":{"name":"Avatario"},"license":"MIT","_id":"@avatario/avatario-js-sdk@0.1.4","maintainers":[{"name":"kushalavatario","email":"kushal@listen2.it"}],"homepage":"https://github.com/Avatarioai/avatario-js-sdk#readme","bugs":{"url":"https://github.com/Avatarioai/avatario-js-sdk/issues"},"dist":{"shasum":"6b233efacdfab9d438f0599a499837823a88ee76","tarball":"https://registry.npmjs.org/@avatario/avatario-js-sdk/-/avatario-js-sdk-0.1.4.tgz","fileCount":6,"integrity":"sha512-ZK7kVtbr4wrMCy8vQ7MPtpqU5vqC+107VRqRGB+FyqnrZ/KXxAsZtOQ4j0B38XiZAHvQg7EF+z0NPP/uSlSpFw==","signatures":[{"sig":"MEUCIQCg2P30d1UqQjOaF3xciWfOFKn59CqH0KEH4Y/msxcSlgIgQZzCYQbjdJPZ8TQKRSkfHrO64ngTh+uJXuTc6i+AqMY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17774},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","gitHead":"ae781dd21a7ff5f52968b34e6bdec75821e4c141","scripts":{"dev":"tsup src/index.ts --format cjs,esm --dts --watch","build":"tsup src/index.ts --format cjs,esm --dts","clean":"rm -rf dist","prepublishOnly":"npm run build"},"_npmUser":{"name":"kushalavatario","email":"kushal@listen2.it"},"repository":{"url":"git+https://github.com/Avatarioai/avatario-js-sdk.git","type":"git"},"_npmVersion":"10.8.3","description":"JavaScript SDK for integrating Avatario video avatars","directories":{},"_nodeVersion":"22.9.0","dependencies":{"livekit-client":"^1.15.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/avatario-js-sdk_0.1.4_1745579539285_0.16376994422291036","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"@avatario/avatario-js-sdk","version":"0.1.5","keywords":["avatario","livekit","video","avatar","sdk"],"author":{"name":"Avatario"},"license":"MIT","_id":"@avatario/avatario-js-sdk@0.1.5","maintainers":[{"name":"kushalavatario","email":"kushal@listen2.it"}],"homepage":"https://github.com/Avatarioai/avatario-js-sdk#readme","bugs":{"url":"https://github.com/Avatarioai/avatario-js-sdk/issues"},"dist":{"shasum":"db4e734dfe5fcec7431272b24f9baaa6dd202027","tarball":"https://registry.npmjs.org/@avatario/avatario-js-sdk/-/avatario-js-sdk-0.1.5.tgz","fileCount":6,"integrity":"sha512-7vWA0/0L3fQk/HUgBXxwjJAyXAk27XmZHrU8YDfTyR1KKUHoa8mUsdnlAE60QxO4rup67W/urDEOqv6HwVn8MA==","signatures":[{"sig":"MEYCIQCMqfX1c4VsjtYtw33wI8mo8loHx0TpeR39COqVDspsmAIhAOytPlxDTP3Oq214OHQvo5g8pbhTNq4uNI7lOUhFiN9x","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17770},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","gitHead":"ae781dd21a7ff5f52968b34e6bdec75821e4c141","scripts":{"dev":"tsup src/index.ts --format cjs,esm --dts --watch","build":"tsup src/index.ts --format cjs,esm --dts","clean":"rm -rf dist","prepublishOnly":"npm run build"},"_npmUser":{"name":"kushalavatario","email":"kushal@listen2.it"},"repository":{"url":"git+https://github.com/Avatarioai/avatario-js-sdk.git","type":"git"},"_npmVersion":"10.8.3","description":"JavaScript SDK for integrating Avatario video avatars","directories":{},"_nodeVersion":"22.9.0","dependencies":{"livekit-client":"^1.15.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/avatario-js-sdk_0.1.5_1745580036736_0.1226075343362576","host":"s3://npm-registry-packages-npm-production"}},"0.1.6":{"name":"@avatario/avatario-js-sdk","version":"0.1.6","keywords":["avatario","livekit","video","avatar","sdk"],"author":{"name":"Avatario"},"license":"MIT","_id":"@avatario/avatario-js-sdk@0.1.6","maintainers":[{"name":"kushalavatario","email":"kushal@listen2.it"}],"homepage":"https://github.com/Avatarioai/avatario-js-sdk#readme","bugs":{"url":"https://github.com/Avatarioai/avatario-js-sdk/issues"},"dist":{"shasum":"fa183bcc883ffd2dee7492c33ad6d5ca7d28f1bb","tarball":"https://registry.npmjs.org/@avatario/avatario-js-sdk/-/avatario-js-sdk-0.1.6.tgz","fileCount":6,"integrity":"sha512-zECieQ/TsFxTOalsDAhTrH69LhErVbv7oIG0mEOVXN2UhNr/+0Fi1Gso1VcNl8zeZxwm6DGTYGNxfhd5ObptQw==","signatures":[{"sig":"MEUCICft9lbHsZFI7PUIIJITFgVwEwIYPMveR5taoHpjZou/AiEA1WF0wT5xqwlyHai7AGu+cdVr8iGajTSxA2/D14c3JXw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17766},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","gitHead":"ae781dd21a7ff5f52968b34e6bdec75821e4c141","scripts":{"dev":"tsup src/index.ts --format cjs,esm --dts --watch","build":"tsup src/index.ts --format cjs,esm --dts","clean":"rm -rf dist","prepublishOnly":"npm run build"},"_npmUser":{"name":"kushalavatario","email":"kushal@listen2.it"},"repository":{"url":"git+https://github.com/Avatarioai/avatario-js-sdk.git","type":"git"},"_npmVersion":"10.8.3","description":"JavaScript SDK for integrating Avatario video avatars","directories":{},"_nodeVersion":"22.9.0","dependencies":{"livekit-client":"^1.15.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/avatario-js-sdk_0.1.6_1745580192823_0.5615693738981653","host":"s3://npm-registry-packages-npm-production"}},"0.1.7":{"name":"@avatario/avatario-js-sdk","version":"0.1.7","keywords":["avatario","livekit","video","avatar","sdk"],"author":{"name":"Avatario"},"license":"MIT","_id":"@avatario/avatario-js-sdk@0.1.7","maintainers":[{"name":"kushalavatario","email":"kushal@listen2.it"}],"homepage":"https://github.com/Avatarioai/avatario-js-sdk#readme","bugs":{"url":"https://github.com/Avatarioai/avatario-js-sdk/issues"},"dist":{"shasum":"10c8aa7a81979ebec626621fb478915fdffa2420","tarball":"https://registry.npmjs.org/@avatario/avatario-js-sdk/-/avatario-js-sdk-0.1.7.tgz","fileCount":6,"integrity":"sha512-TsC10GP14rQaUY4ugUMOh5AHbFWfsLy22O6U77XvzZEVdMSAb+z8vyI6QoTn0S/tMphowt6IO5Hfq7yKXZmeGw==","signatures":[{"sig":"MEUCIBQYMLM0yM51mFmKpgUToclPb+si3a8hCljbc4QOlbV1AiEAoa9H2o/E1CR3J77Yj9MNgySms5JONUtFs3wXvOU8anA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":26091},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","gitHead":"ae781dd21a7ff5f52968b34e6bdec75821e4c141","scripts":{"dev":"tsup src/index.ts --format cjs,esm --dts --watch","build":"tsup src/index.ts --format cjs,esm --dts","clean":"rm -rf dist","prepublishOnly":"npm run build"},"_npmUser":{"name":"kushalavatario","email":"kushal@listen2.it"},"repository":{"url":"git+https://github.com/Avatarioai/avatario-js-sdk.git","type":"git"},"_npmVersion":"10.8.3","description":"JavaScript SDK for integrating Avatario video avatars","directories":{},"_nodeVersion":"22.9.0","dependencies":{"livekit-client":"^1.15.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/avatario-js-sdk_0.1.7_1745581283375_0.12174818742378068","host":"s3://npm-registry-packages-npm-production"}},"0.1.8":{"name":"@avatario/avatario-js-sdk","version":"0.1.8","description":"JavaScript SDK for integrating Avatario video avatars","main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","scripts":{"build":"tsup src/index.ts --format cjs,esm --dts","dev":"tsup src/index.ts --format cjs,esm --dts --watch","clean":"rm -rf dist","prepublishOnly":"npm run build"},"dependencies":{"livekit-client":"^1.15.0"},"devDependencies":{"tsup":"^8.0.0","typescript":"^5.0.0"},"keywords":["avatario","livekit","video","avatar","sdk"],"author":{"name":"Avatario"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/Avatarioai/avatario-js-sdk.git"},"bugs":{"url":"https://github.com/Avatarioai/avatario-js-sdk/issues"},"homepage":"https://github.com/Avatarioai/avatario-js-sdk#readme","publishConfig":{"access":"public"},"_id":"@avatario/avatario-js-sdk@0.1.8","gitHead":"aecd7cabc91968c0c225f80006e73496f5df8eaf","_nodeVersion":"22.9.0","_npmVersion":"10.8.3","dist":{"integrity":"sha512-b9IT/mvafPHRCdPsMtOfdLPwt4xWzBRPJpSIiBrbYHznMVKmynUQeCC1UQgNf7vjlYUDsXI0xgh0FgTJhYwTKw==","shasum":"5853585bcd14770fb006fb21ab8e13ffaa8d469f","tarball":"https://registry.npmjs.org/@avatario/avatario-js-sdk/-/avatario-js-sdk-0.1.8.tgz","fileCount":6,"unpackedSize":26095,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIE0RvVFkk5fhc6ajn1eywYOjxoxzXFzfbZxmFslnEN0rAiA96iGsCbarYV9Eeo5Le2Jh1q0camiJxPkZAVJZjbd4/A=="}]},"_npmUser":{"name":"kushalavatario","email":"kushal@listen2.it"},"directories":{},"maintainers":[{"name":"kushalavatario","email":"kushal@listen2.it"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/avatario-js-sdk_0.1.8_1745824614894_0.3611881086910227"},"_hasShrinkwrap":false}},"time":{"created":"2025-04-25T10:58:27.799Z","modified":"2025-04-28T07:16:55.277Z","0.1.3":"2025-04-25T10:58:28.081Z","0.1.4":"2025-04-25T11:12:19.515Z","0.1.5":"2025-04-25T11:20:36.930Z","0.1.6":"2025-04-25T11:23:13.010Z","0.1.7":"2025-04-25T11:41:23.595Z","0.1.8":"2025-04-28T07:16:55.098Z"},"bugs":{"url":"https://github.com/Avatarioai/avatario-js-sdk/issues"},"author":{"name":"Avatario"},"license":"MIT","homepage":"https://github.com/Avatarioai/avatario-js-sdk#readme","keywords":["avatario","livekit","video","avatar","sdk"],"repository":{"type":"git","url":"git+https://github.com/Avatarioai/avatario-js-sdk.git"},"description":"JavaScript SDK for integrating Avatario video avatars","maintainers":[{"name":"kushalavatario","email":"kushal@listen2.it"}],"readme":"# Avatario JS SDK\n\nThe Avatario JS SDK allows you to easily integrate real-time AI video avatars into your web applications. This SDK provides a simple interface to connect to Avatario's video avatar service.\n\n## Installation\n\n```bash\n# Install Avatario JS SDK\nnpm install @avatario/avatario-js-sdk\n# or\nyarn add @avatario/avatario-js-sdk\n```\n\n## Quick Start\n\n```typescript\nimport { AvatarioClient } from '@avatario/avatario-js-sdk';\n\n// Initialize the SDK with your API key and avatar ID\nconst client = new AvatarioClient({\n  apiKey: 'your-api-key-here', // Required: Your Avatario API key\n  avatarId: 'your-avatar-id', // Required: Avatar ID to use\n  onConnected: () => console.log('Connected to Avatario room'),\n  onDisconnected: () => console.log('Disconnected from Avatario room'),\n  onError: (error) => console.error('Error:', error)\n});\n\n// Get video and audio elements from your HTML\nconst videoElement = document.getElementById('video') as HTMLVideoElement;\nconst audioElement = document.getElementById('audio') as HTMLAudioElement;\n\n// Connect to Avatario\ntry {\n  const { avatarioRoomName } = await client.connect(videoElement, audioElement);\n  console.log('Connected to room:', avatarioRoomName);\n} catch (error) {\n  console.error('Failed to connect:', error);\n}\n\n// Disconnect when done\nawait client.disconnect();\n```\n\n## API Reference\n\n### AvatarioClient\n\n#### Constructor\n\n```typescript\nnew AvatarioClient(options: AvatarioClientOptions)\n```\n\n##### Options\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| apiKey | string | Yes | Your Avatario API key |\n| avatarId | string | Yes | ID of the avatar to use for video generation |\n| onConnected | () => void | No | Callback when connected to the room |\n| onDisconnected | () => void | No | Callback when disconnected from the room |\n| onError | (error: Error) => void | No | Callback for error handling |\n\n#### Methods\n\n##### connect\n\n```typescript\nasync connect(\n  videoElement?: HTMLVideoElement,\n  audioElement?: HTMLAudioElement\n): Promise<{ avatarioRoomName: string }>\n```\n\nConnects to an Avatario room and sets up video/audio streaming.\n\nParameters:\n- `videoElement`: Optional HTML video element to display the avatar\n- `audioElement`: Optional HTML audio element to play the avatar's audio\n\nReturns:\n- `avatarioRoomName`: The name of the room that was created\n\n##### disconnect\n\n```typescript\nasync disconnect(): Promise<void>\n```\n\nDisconnects from the current Avatario room.\n\n##### isConnectedToRoom\n\n```typescript\nisConnectedToRoom(): boolean\n```\n\nReturns whether the SDK is currently connected to a room.\n\n##### getAvatarId\n\n```typescript\ngetAvatarId(): string\n```\n\nReturns the avatar ID that was specified during initialization.\n\n## Available Avatars\n\nThe SDK requires a valid avatar ID to function. You can use any of the following stock avatars:\n\n| Avatar ID | Name | Ethnicity | Gender |\n|-----------|------|-----------|--------|\n| 27a57eb6-c517-4006-98f2-d9357b82ff87 | Ching | Asian | Male |\n| b523e8ef-b85b-4e77-9a61-9f8ffb687658 | Sara | Caucasian | Female |\n| 347c0c95-ec73-467d-8a07-f73a084441a0 | Jack | African | Male |\n| 6d47156b-0cff-4ec5-8628-a0fc9e1e2899 | Amelia | Caucasian | Female |\n| eaa7840e-c092-40df-844b-d5df5cef1123 | Sam | Caucasian | Male |\n| d1fbd6bc-d848-4e26-918e-4c05ae513190 | Sandra | Caucasian | Female |\n\n## Advanced Integration: Using Avatario with LiveKit\n\nAvatario can be integrated with LiveKit for enhanced real-time communication capabilities. This section explains how to combine the power of Avatario's AI avatars with LiveKit's real-time audio and video communication.\n\n### Installing LiveKit\n\n```bash\n# Install LiveKit client alongside Avatario\nnpm install livekit-client\n# or\nyarn add livekit-client\n```\n\n### Basic LiveKit Setup\n\nHere's how to set up a basic LiveKit room connection for use with Avatario:\n\n```typescript\nimport { Room, RoomEvent, ConnectionState, Track } from \"livekit-client\";\n\n// Create a new Room instance\nconst room = new Room({\n  adaptiveStream: true,\n  dynacast: true,\n});\n\n// Connect to the room (requires a token from your backend)\nawait room.connect(livekitUrl, token);\n\n// Enable camera and microphone\nawait room.localParticipant.enableCameraAndMicrophone();\n\n// Listen for connection state changes\nroom.on(RoomEvent.ConnectionStateChanged, (state: ConnectionState) => {\n  if (state === ConnectionState.Connected) {\n    console.log(\"Connected to LiveKit room\");\n  } else if (state === ConnectionState.Disconnected) {\n    console.log(\"Disconnected from LiveKit room\");\n  }\n});\n\n// Disconnect when finished\nroom.disconnect();\n```\n\n### Integrating LiveKit with Avatario SDK\n\nWhen using LiveKit with the Avatario SDK, you typically want to:\n\n1. Connect to an Avatario room for AI avatar rendering\n2. Connect to a LiveKit room for real-time communication\n3. Send your audio/video to the LiveKit room while receiving avatar video from Avatario\n\nHere's how to implement this pattern:\n\n```typescript\nimport { Room, RoomEvent, ConnectionState, Track } from \"livekit-client\";\nimport { AvatarioClient } from \"@avatario/avatario-js-sdk\";\n\n// References\nconst userRoom = useRef<Room | null>(null);\nconst avatarioSDK = useRef<AvatarioClient | null>(null);\n\n// Video/audio elements\nconst localVideoRef = useRef<HTMLVideoElement>(null);\nconst remoteVideoRef = useRef<HTMLVideoElement>(null);\nconst remoteAudioRef = useRef<HTMLAudioElement>(null);\n\n// Initialize Avatario SDK\navatarioSDK.current = new AvatarioClient({\n  apiKey: \"your-api-key\",\n  avatarId: \"selected-avatar-id\",\n  onConnected: () => console.log(\"Avatario SDK connected\"),\n  onDisconnected: () => console.log(\"Avatario SDK disconnected\"),\n  onError: (error) => console.error(\"Avatario SDK error:\", error),\n});\n\n// Connect to Avatario\nconst connectToAvatario = async () => {\n  // Connect to Avatario room and get the room name\n  const { avatarioRoomName } = await avatarioSDK.current.connect(\n    remoteVideoRef.current!,\n    remoteAudioRef.current!\n  );\n  \n  return avatarioRoomName;\n};\n\n// Connect to LiveKit\nconst connectToLiveKit = async (token: string, url: string) => {\n  // Create room\n  const room = new Room({\n    adaptiveStream: true,\n    dynacast: true,\n  });\n  \n  // Set up event listener for connection state\n  room.on(RoomEvent.ConnectionStateChanged, (state: ConnectionState) => {\n    console.log(\"LiveKit room connection state:\", state);\n  });\n  \n  // Connect to LiveKit room\n  await room.connect(url, token);\n  \n  // Enable camera and microphone\n  await room.localParticipant.enableCameraAndMicrophone();\n  \n  // Attach local video to an element\n  if (localVideoRef.current) {\n    const videoTracks = room.localParticipant\n      .getTrackPublications()\n      .filter((publication) => publication.kind === Track.Kind.Video);\n      \n    if (videoTracks.length > 0 && videoTracks[0].track) {\n      videoTracks[0].track.attach(localVideoRef.current);\n    }\n  }\n  \n  // Store room reference\n  userRoom.current = room;\n  \n  return room;\n};\n\n// Main connect function\nconst handleConnect = async () => {\n  try {\n    // 1. Connect to Avatario\n    const avatarioRoomName = await connectToAvatario();\n    \n    // 2. Get LiveKit token (this would be a call to your backend)\n    const { token, url } = await getUserToken(avatarioRoomName);\n    \n    // 3. Connect to LiveKit room\n    await connectToLiveKit(token, url);\n    \n    console.log(\"Successfully connected to both services\");\n  } catch (error) {\n    console.error(\"Connection error:\", error);\n  }\n};\n\n// Disconnect from both services\nconst disconnect = () => {\n  if (userRoom.current) {\n    userRoom.current.disconnect();\n    userRoom.current = null;\n  }\n  \n  if (avatarioSDK.current?.isConnectedToRoom()) {\n    avatarioSDK.current.disconnect();\n  }\n};\n```\n\n### Getting LiveKit Tokens\n\nLiveKit requires authentication tokens to join rooms. Here's a simple example of how to fetch a token from your backend:\n\n```typescript\n// Function to get user token from backend\nconst getUserToken = async (avatarioRoomName: string) => {\n  try {\n    const response = await fetch(\"https://your-api.example.com/get-token\", {\n      method: \"POST\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n        \"x-api-key\": \"your-api-key\",\n      },\n      body: JSON.stringify({\n        local_identity: \"avatario-client\",\n        user_room_name: \"your-room-name\",\n        avatario_room_name: avatarioRoomName,\n      }),\n    });\n\n    if (response.ok) {\n      const data = await response.json();\n      return data.data; // { token: \"...\", url: \"...\" }\n    }\n    throw new Error(\"Failed to get token\");\n  } catch (error) {\n    console.error(\"Failed to get token:\", error);\n    return null;\n  }\n};\n```\n\n### Toggle Audio and Video with LiveKit\n\nControl local audio and video tracks in your LiveKit integration:\n\n```typescript\n// Toggle microphone\nconst toggleAudio = async () => {\n  if (!userRoom.current) return;\n  await userRoom.current.localParticipant.setMicrophoneEnabled(!audioEnabled);\n  setAudioEnabled(!audioEnabled);\n};\n\n// Toggle camera\nconst toggleVideo = async () => {\n  if (!userRoom.current) return;\n  await userRoom.current.localParticipant.setCameraEnabled(!videoEnabled);\n  setVideoEnabled(!videoEnabled);\n};\n```\n\n### React Integration Example\n\nWhen using Avatario with LiveKit in a React application, you can use hooks for better state management:\n\n```tsx\nimport React, { useState, useEffect, useRef } from \"react\";\nimport { Room, RoomEvent, ConnectionState } from \"livekit-client\";\nimport { AvatarioClient } from \"@avatario/avatario-js-sdk\";\n\nfunction VideoChat() {\n  const [isConnected, setIsConnected] = useState(false);\n  const [audioEnabled, setAudioEnabled] = useState(true);\n  const [videoEnabled, setVideoEnabled] = useState(true);\n  \n  const roomRef = useRef<Room | null>(null);\n  const avatarioRef = useRef<AvatarioClient | null>(null);\n  \n  const localVideoRef = useRef<HTMLVideoElement>(null);\n  const remoteVideoRef = useRef<HTMLVideoElement>(null);\n  const remoteAudioRef = useRef<HTMLAudioElement>(null);\n  \n  // Initialize Avatario SDK\n  useEffect(() => {\n    avatarioRef.current = new AvatarioClient({\n      apiKey: \"your-api-key\",\n      avatarId: \"selected-avatar-id\",\n      onConnected: () => setIsConnected(true),\n      onDisconnected: () => setIsConnected(false),\n      onError: (error) => console.error(error),\n    });\n    \n    return () => {\n      if (avatarioRef.current?.isConnectedToRoom()) {\n        avatarioRef.current.disconnect();\n      }\n    };\n  }, []);\n  \n  // Connect to both services\n  const handleConnect = async () => {\n    try {\n      // Steps as described earlier\n      // 1. Connect to Avatario\n      // 2. Get token\n      // 3. Connect to LiveKit\n    } catch (error) {\n      console.error(error);\n    }\n  };\n  \n  return (\n    <div>\n      <div className=\"video-container\">\n        <video ref={remoteVideoRef} autoPlay playsInline />\n        <audio ref={remoteAudioRef} autoPlay playsInline />\n        \n        <div className=\"local-video\">\n          <video ref={localVideoRef} autoPlay playsInline muted />\n        </div>\n      </div>\n      \n      <div className=\"controls\">\n        <button onClick={toggleAudio}>\n          {audioEnabled ? \"Mute\" : \"Unmute\"}\n        </button>\n        <button onClick={toggleVideo}>\n          {videoEnabled ? \"Hide Camera\" : \"Show Camera\"}\n        </button>\n        <button onClick={isConnected ? disconnect : handleConnect}>\n          {isConnected ? \"Disconnect\" : \"Connect\"}\n        </button>\n      </div>\n    </div>\n  );\n}\n```\n\n## Troubleshooting\n\n### Autoplay Policy Restrictions\n\nBrowser autoplay policies may block audio playback without user interaction. Use this pattern to handle it:\n\n```typescript\nuseEffect(() => {\n  if (isConnected) {\n    const unlockAudio = () => {\n      if (remoteAudioRef.current) {\n        // Create and play a silent audio context\n        const AudioContextClass = window.AudioContext || \n          (window as any).webkitAudioContext;\n        const audioContext = new AudioContextClass();\n        const emptySource = audioContext.createBufferSource();\n        emptySource.start();\n        emptySource.stop();\n        \n        // Try to play the audio element\n        remoteAudioRef.current\n          .play()\n          .catch(e => console.log(\"Audio playback still restricted:\", e));\n      }\n      \n      document.removeEventListener(\"click\", unlockAudio);\n      document.removeEventListener(\"touchstart\", unlockAudio);\n    };\n    \n    document.addEventListener(\"click\", unlockAudio);\n    document.addEventListener(\"touchstart\", unlockAudio);\n    \n    return () => {\n      document.removeEventListener(\"click\", unlockAudio);\n      document.removeEventListener(\"touchstart\", unlockAudio);\n    };\n  }\n}, [isConnected]);\n```\n\n### Device Permissions\n\nEnsure you properly handle device permissions for camera and microphone:\n\n```typescript\n// Check if user has granted permissions\nconst checkPermissions = async () => {\n  try {\n    await navigator.mediaDevices.getUserMedia({ audio: true, video: true });\n    return true;\n  } catch (error) {\n    console.error(\"Permission denied:\", error);\n    return false;\n  }\n};\n```\n\n## Error Handling\n\nThe Avatario SDK provides error handling through the `onError` callback in the options. Common errors include:\n\n- Invalid API key\n- Invalid avatar ID\n- Network connectivity issues\n- Room connection failures\n- Media device access issues\n\n## Requirements\n\n- Modern browser with WebRTC support\n- Valid Avatario API key\n- Valid avatar ID\n- Internet connection\n\n## Browser Support\n\nThe SDK works in all modern browsers that support WebRTC, including:\n- Chrome\n- Firefox\n- Safari\n- Edge\n\n## Resources\n\n- [Avatario JS SDK Documentation](https://app.onezot.work/docs)\n- [LiveKit Documentation](https://docs.livekit.io)\n- [WebRTC Standards](https://webrtc.org/) ","readmeFilename":"README.md"}