Weave 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

ElevenLabs platform bridge for Symfony AI, adding text-to-speech and speech-to-text integration through the ElevenLabs API. Supports converting text to audio and streaming, plus transcribing audio files within Symfony AI 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.
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo
stevenay/myanfont
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin