Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ai Eleven Labs Platform Laravel Package

symfony/ai-eleven-labs-platform

Symfony AI bridge for the ElevenLabs Platform API. Provides integration for ElevenLabs authentication plus text-to-speech (convert/stream) and speech-to-text endpoints, enabling voice generation and transcription in Symfony applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Package

    composer require symfony/ai-eleven-labs-platform
    
  2. Configure API Key Add your ElevenLabs API key to your Symfony .env:

    ELEVENLABS_API_KEY=your_api_key_here
    
  3. Basic TTS Usage

    use Symfony\AI\ElevenLabs\ElevenLabsClient;
    use Symfony\AI\ElevenLabs\Voice;
    
    $client = new ElevenLabsClient($_ENV['ELEVENLABS_API_KEY']);
    $voice = new Voice('Rachel'); // ElevenLabs voice ID
    $audio = $client->convert('Hello, world!', $voice);
    
    file_put_contents('output.mp3', $audio->getContent());
    
  4. First Use Case: Dynamic Audio Generation Use the convert() method to generate audio on-demand (e.g., for notifications or IVR systems). Example:

    $client = new ElevenLabsClient($_ENV['ELEVENLABS_API_KEY']);
    $voices = $client->getModelCatalog()->getVoices();
    $selectedVoice = $voices->first(); // Pick a voice dynamically
    
    $audio = $client->convert("Your order #12345 is confirmed.", $selectedVoice);
    // Send $audio to user via email/SMS
    

Implementation Patterns

Core Workflows

1. Text-to-Speech (TTS) Patterns

  • Synchronous Conversion (for pre-generated audio):
    $client = new ElevenLabsClient($_ENV['ELEVENLABS_API_KEY']);
    $audio = $client->convert("Hello, user!", new Voice('Antoni'));
    file_put_contents('greeting.mp3', $audio->getContent());
    
  • Streaming TTS (for real-time apps like chatbots):
    $stream = $client->stream("Hello, user!", new Voice('Antoni'));
    while ($chunk = $stream->getChunk()) {
        // Send chunk to browser via SSE or WebSocket
        echo $chunk;
    }
    
  • Batch Processing (for bulk audio generation):
    $messages = ["Order confirmed", "Thank you for your purchase"];
    foreach ($messages as $message) {
        $audio = $client->convert($message, new Voice('Bella'));
        // Store in database or queue for delivery
    }
    

2. Speech-to-Text (STT) Patterns

  • Synchronous Transcription (for small files):
    $transcription = $client->transcribe('audio.mp3');
    echo $transcription->getText(); // "Hello, world!"
    
  • Asynchronous STT (for long audio files): Use Symfony Messenger to queue transcription jobs:
    use Symfony\Component\Messenger\MessageBusInterface;
    
    $bus->dispatch(new TranscribeMessage('long_audio.mp3'));
    
    Define a handler:
    class TranscribeHandler
    {
        public function __invoke(TranscribeMessage $message, ElevenLabsClient $client)
        {
            $transcription = $client->transcribe($message->getFilePath());
            // Save result or trigger follow-up actions
        }
    }
    

3. Dynamic Voice Selection

Fetch available voices and filter by criteria (e.g., language, similarity):

$voices = $client->getModelCatalog()->getVoices();
$englishVoices = $voices->filter(fn($voice) => $voice->getLabels()['language'] === 'en');

4. Error Handling and Retries

Wrap API calls in a retry mechanism:

use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;

try {
    $audio = $client->convert("Hello", new Voice('Rachel'));
} catch (ClientExceptionInterface | ServerExceptionInterface $e) {
    // Implement retry logic (e.g., exponential backoff)
    $this->retryWithBackoff(fn() => $client->convert("Hello", new Voice('Rachel')));
}

Integration Tips

Symfony-Specific Integrations

  1. Dependency Injection Register the client as a service in services.yaml:

    services:
        Symfony\AI\ElevenLabs\ElevenLabsClient:
            arguments:
                $apiKey: '%env(ELEVENLABS_API_KEY)%'
    

    Inject it into controllers/services:

    public function __construct(private ElevenLabsClient $elevenLabs) {}
    
  2. Messenger for Async STT Create a message and handler for background transcription:

    // src/Message/TranscribeMessage.php
    class TranscribeMessage
    {
        public function __construct(private string $filePath) {}
        public function getFilePath(): string { return $this->filePath; }
    }
    
    // src/MessageHandler/TranscribeHandler.php
    class TranscribeHandler
    {
        public function __invoke(TranscribeMessage $message, ElevenLabsClient $client)
        {
            $transcription = $client->transcribe($message->getFilePath());
            // Save to database or notify user
        }
    }
    
  3. Event Listeners for Post-Processing Trigger actions after transcription (e.g., update CRM):

    use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
    
    #[AsEventListener(event: 'elevenlabs.transcription.completed', method: 'onTranscriptionCompleted')]
    public function onTranscriptionCompleted(TranscriptionEvent $event)
    {
        $this->crmService->updateNote($event->getTranscription()->getText());
    }
    

Non-Symfony PHP (Laravel) Workarounds

If using Laravel, leverage the package’s standalone HTTP client usage:

use Symfony\AI\ElevenLabs\ElevenLabsClient;
use Symfony\Contracts\HttpClient\HttpClientInterface;

// Laravel's HTTP client implements HttpClientInterface
$client = new ElevenLabsClient($_ENV['ELEVENLABS_API_KEY'], app(HttpClientInterface::class));

Testing

Use provided test fixtures (Tests/Fixtures/audio.mp3) for local testing:

public function testTranscription()
{
    $client = new ElevenLabsClient($_ENV['ELEVENLABS_API_KEY']);
    $transcription = $client->transcribe(__DIR__.'/../../Tests/Fixtures/audio.mp3');
    $this->assertStringContainsString('test', $transcription->getText());
}

Gotchas and Tips

Pitfalls

  1. API Key Management

    • Gotcha: Hardcoding API keys in code violates security best practices.
    • Fix: Always use environment variables or a secrets manager (e.g., Symfony’s ParameterBag or Laravel’s .env).
  2. Rate Limiting

    • Gotcha: ElevenLabs enforces rate limits. Exceeding limits may cause 429 Too Many Requests errors.
    • Fix: Implement retry logic with exponential backoff:
      use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
      
      try {
          $audio = $client->convert("Hello", new Voice('Rachel'));
      } catch (TransportExceptionInterface $e) {
          if ($e->getCode() === 429) {
              sleep(2); // Wait before retry
              $audio = $client->convert("Hello", new Voice('Rachel'));
          }
      }
      
  3. Streaming Quirks

    • Gotcha: Streaming responses may time out for long audio. Symfony’s HttpClient defaults to a 30-second timeout.
    • Fix: Increase timeout for streaming requests:
      $client = new ElevenLabsClient(
          $_ENV['ELEVENLABS_API_KEY'],
          HttpClient::create(['timeout' => 300]) // 5-minute timeout
      );
      
  4. Voice Selection

    • Gotcha: Not all voices support all languages or features (e.g., streaming).
    • Fix: Check voice metadata before use:
      $voice = new Voice('Rachel');
      if (!$voice->supportsStreaming()) {
          throw new \RuntimeException("Voice does not support streaming.");
      }
      
  5. Error Handling

    • Gotcha: ElevenLabs returns custom error formats. The package wraps these in ElevenLabsApiException, but some edge cases may slip through.
    • Fix: Extend the exception handler:
      $client->getHttpClient()->on(
          ['error' => function (ResponseInterface $response, Throwable $exception) {
              if ($response->getStatusCode() === 401) {
                  throw new \RuntimeException("Invalid API key.");
              }
          }]
      );
      

Debugging Tips

  1. Enable HTTP Client Logging Add this to
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor