A modern, fluent Laravel package for integrating with the ElevenLabs Text-to-Speech (TTS) and Speech-to-Text (STT) APIs. This package provides a clean and intuitive interface for converting text to speech and transcribing audio in your Laravel applications.
- PHP 8.2 or higher
- Laravel 12.0 or higher
You can install the package via Composer:
composer require digitalcorehub/laravel-elevenlabsPublish the configuration file:
php artisan vendor:publish --tag=elevenlabs-configThis will create a config/elevenlabs.php file in your config directory.
Add the following to your .env file:
ELEVENLABS_API_KEY=your_api_key_here
ELEVENLABS_DEFAULT_VOICE=nova
ELEVENLABS_DEFAULT_FORMAT=mp3_44100_128
ELEVENLABS_BASE_URL=https://api.elevenlabs.io/v1
ELEVENLABS_TIMEOUT=30- api_key: Your ElevenLabs API key (required)
- base_url: The base URL for the ElevenLabs API (default:
https://api.elevenlabs.io/v1) - default_voice: The default voice ID to use (default:
nova) - default_format: The default audio format (default:
mp3_44100_128) - timeout: Request timeout in seconds (default:
30)
The package provides a fluent API for generating text-to-speech audio:
use DigitalCoreHub\LaravelElevenLabs\Facades\ElevenLabs;
// Generate audio and save to storage
ElevenLabs::tts()
->voice('nova')
->text('Hello from Laravel')
->format('mp3_44100_128')
->save('voices/hello.mp3');If you've configured default voice and format, you can omit them:
ElevenLabs::tts()
->text('Hello from Laravel')
->save('voices/hello.mp3');Instead of saving directly, you can get an AudioFile object:
$audioFile = ElevenLabs::tts()
->voice('nova')
->text('Hello from Laravel')
->format('mp3_44100_128')
->generate();
// Access the content
$content = $audioFile->getContent();
// Get the format
$format = $audioFile->getFormat();
// Save to a different location
$audioFile->save('custom/path/audio.mp3', 's3');You can customize voice settings (stability, similarity_boost, etc.):
ElevenLabs::tts()
->voice('nova')
->text('Hello from Laravel')
->voiceSettings([
'stability' => 0.7,
'similarity_boost' => 0.8,
])
->save('voices/hello.mp3');Common voice IDs include:
novaracheldomibellaantoniellijosharnoldadamsam
mp3_44100_128mp3_44100_192mp3_44100_256pcm_16000pcm_22050pcm_24000pcm_44100ulaw_8000
ElevenLabs::tts()
->text('Hello from Laravel')
->save('voices/hello.mp3', 's3'); // Save to S3The package provides a fluent API for transcribing audio files:
use DigitalCoreHub\LaravelElevenLabs\Facades\ElevenLabs;
// Transcribe an audio file
$result = ElevenLabs::stt()
->file('audio.wav')
->transcribe();
// Access the transcribed text
echo $result->text;
// Access words array (if available)
$words = $result->words;
// Access confidence score (if available)
$confidence = $result->confidence;You can transcribe files from any Laravel storage disk:
// From local storage
$result = ElevenLabs::stt()
->file('audio/recording.wav', 'local')
->transcribe();
// From S3
$result = ElevenLabs::stt()
->file('audio/recording.wav', 's3')
->transcribe();You can also use absolute file paths:
$result = ElevenLabs::stt()
->file('/path/to/audio.wav')
->transcribe();You can specify a custom model for transcription:
$result = ElevenLabs::stt()
->file('audio.wav')
->model('eleven_multilingual_v2')
->transcribe();The transcribe() method returns a TranscriptionResult object with the following properties:
- text (string): The transcribed text
- words (array|null): Array of word objects with timing information (if available)
- confidence (float|null): Confidence score of the transcription (if available)
Example:
$result = ElevenLabs::stt()
->file('audio.wav')
->transcribe();
// Get text
$text = $result->getText();
// Get words array
$words = $result->getWords();
// [
// ['word' => 'Hello', 'start' => 0.0, 'end' => 0.5],
// ['word' => 'world', 'start' => 0.5, 'end' => 1.0],
// ]
// Get confidence
$confidence = $result->getConfidence(); // 0.95
// Convert to array
$array = $result->toArray();The STT API supports various audio formats:
- WAV
- MP3
- M4A
- FLAC
- And other common audio formats
Get a collection of all available voices:
$voices = ElevenLabs::voices()->list();
// Iterate through voices
foreach ($voices as $voice) {
echo $voice->name;
echo $voice->voiceId;
}
// Find voice by ID
$voice = $voices->findById('voice-id');
// Find voices by name
$found = $voices->findByName('Nova');Get detailed information about a specific voice:
$voice = ElevenLabs::voices()->get('voice-id');
// Access voice properties
echo $voice->name;
echo $voice->description;
echo $voice->category;
$settings = $voice->settings;Create a custom voice using audio files:
// Using absolute file paths
$voice = ElevenLabs::voices()
->name('My Custom Voice')
->files(['/path/to/voice1.wav', '/path/to/voice2.wav'])
->description('A custom voice for my project')
->labels(['accent' => 'british', 'age' => 'young'])
->create();
// Using storage disk files
$voice = ElevenLabs::voices()
->name('My Custom Voice')
->files([
['path' => 'voices/voice1.wav', 'disk' => 'local'],
['path' => 'voices/voice2.wav', 'disk' => 's3'],
])
->create();Delete a voice:
$deleted = ElevenLabs::voices()->delete('voice-id');Sync voices from the API (useful for caching or updating local database):
// Direct sync
$voices = ElevenLabs::voices()->sync();
// Using queue job
use DigitalCoreHub\LaravelElevenLabs\Jobs\SyncVoicesJob;
SyncVoicesJob::dispatch();The package dispatches events when voices are created or synced:
use DigitalCoreHub\LaravelElevenLabs\Events\VoiceCreated;
use DigitalCoreHub\LaravelElevenLabs\Events\VoiceSynced;
// Listen to voice created event
Event::listen(VoiceCreated::class, function (VoiceCreated $event) {
$voice = $event->voice;
// Handle voice creation
});
// Listen to voice synced event
Event::listen(VoiceSynced::class, function (VoiceSynced $event) {
$voices = $event->voices;
// Handle voice sync
});The Voice class provides access to all voice properties:
$voice = ElevenLabs::voices()->get('voice-id');
// Properties
$voice->voiceId;
$voice->name;
$voice->description;
$voice->category;
$voice->samples;
$voice->settings;
$voice->labels;
$voice->previewUrl;
// Convert to array
$array = $voice->toArray();The VoiceCollection extends Laravel's Collection with additional methods:
$voices = ElevenLabs::voices()->list();
// Collection methods
$voices->count();
$voices->first();
$voices->filter(fn ($voice) => $voice->category === 'premade');
// Custom methods
$voice = $voices->findById('voice-id');
$found = $voices->findByName('Nova');Dub videos or audio files to different languages:
// Run dubbing synchronously
$result = ElevenLabs::dubbing()
->source('input.mp4')
->target('tr')
->run();
// Check status
echo $result->status; // processing, completed, failed
echo $result->jobId;
echo $result->outputUrl; // Available when completedYou can use files from any Laravel storage disk:
// From local storage
$result = ElevenLabs::dubbing()
->source('videos/input.mp4', 'local')
->target('en')
->run();
// From S3
$result = ElevenLabs::dubbing()
->source('videos/input.mp4', 's3')
->target('es')
->run();You can also use absolute file paths:
$result = ElevenLabs::dubbing()
->source('/path/to/video.mp4')
->target('fr')
->run();You can pass additional options:
$result = ElevenLabs::dubbing()
->source('input.mp4')
->target('tr')
->options([
'num_speakers' => 2,
'watermark' => false,
])
->run();For long-running dubbing jobs, use the queue:
// Dispatch to queue
ElevenLabs::dubbing()
->source('input.mp4')
->target('tr')
->dispatch();
// Or with parameters
ElevenLabs::dubbing()->dispatch('input.mp4', 'tr');Or create a dedicated job:
use DigitalCoreHub\LaravelElevenLabs\Jobs\RunDubbingJob;
RunDubbingJob::dispatch('input.mp4', null, 'tr', ['watermark' => false]);Check the status of a dubbing job:
$result = ElevenLabs::dubbing()->status('job-id');
if ($result->isCompleted()) {
// Download the dubbed file
$outputUrl = $result->outputUrl;
}
if ($result->isInProgress()) {
// Job is still processing
}
if ($result->isFailed()) {
// Job failed
}The package dispatches events when dubbing completes:
use DigitalCoreHub\LaravelElevenLabs\Events\DubbingCompleted;
Event::listen(DubbingCompleted::class, function (DubbingCompleted $event) {
$result = $event->result;
if ($result->isCompleted()) {
// Download or process the dubbed file
$outputUrl = $result->outputUrl;
}
});The run() and status() methods return a DubbingResult object:
$result = ElevenLabs::dubbing()
->source('input.mp4')
->target('tr')
->run();
// Properties
$result->status; // processing, completed, failed
$result->jobId; // Job ID for status checking
$result->outputUrl; // URL to download dubbed file (when completed)
$result->duration; // Duration in seconds (when completed)
$result->metadata; // Additional metadata
// Status checks
$result->isCompleted();
$result->isInProgress();
$result->isFailed();
// Convert to array
$array = $result->toArray();Common target language codes:
en- Englishtr- Turkishes- Spanishfr- Frenchde- Germanit- Italianpt- Portuguese- And more...
You can easily queue TTS generation jobs:
use Illuminate\Support\Facades\Queue;
Queue::push(function () {
ElevenLabs::tts()
->text('This will be processed in the background')
->save('voices/queued.mp3');
});Or create a dedicated job:
namespace App\Jobs;
use DigitalCoreHub\LaravelElevenLabs\Facades\ElevenLabs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class GenerateTtsJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct(
public string $text,
public string $outputPath,
public ?string $voice = null
) {}
public function handle(): void
{
$tts = ElevenLabs::tts()->text($this->text);
if ($this->voice) {
$tts->voice($this->voice);
}
$tts->save($this->outputPath);
}
}The package includes fake providers for testing purposes.
use DigitalCoreHub\LaravelElevenLabs\Tests\Fake\FakeTtsProvider;
use DigitalCoreHub\LaravelElevenLabs\Http\Endpoints\TtsEndpoint;
use DigitalCoreHub\LaravelElevenLabs\Http\Clients\ElevenLabsClient;
// In your test setup
$this->app->singleton(TtsEndpoint::class, function ($app) {
$client = $app->make(ElevenLabsClient::class);
return new FakeTtsProvider($client);
});use DigitalCoreHub\LaravelElevenLabs\Tests\Fake\FakeSttProvider;
use DigitalCoreHub\LaravelElevenLabs\Http\Endpoints\SttEndpoint;
use DigitalCoreHub\LaravelElevenLabs\Http\Clients\ElevenLabsClient;
// In your test setup
$this->app->singleton(SttEndpoint::class, function ($app) {
$client = $app->make(ElevenLabsClient::class);
return new FakeSttProvider($client);
});- Fluent API for TTS generation
- Support for multiple audio formats
- Custom voice settings
- Storage integration
- Configuration management
- Comprehensive test coverage
- Fluent API for STT transcription
- File upload support (local and storage disks)
- TranscriptionResult data model
- Support for multiple audio formats
- Custom model selection
- Words array and confidence scores
- Comprehensive test coverage
- Fluent API for voice management
- List and get voice operations
- Custom voice creation with file uploads
- Voice deletion support
- Voice sync functionality
- Queue support with SyncVoicesJob
- Event system (VoiceCreated, VoiceSynced)
- Voice and VoiceCollection data models
- Storage disk integration
- Comprehensive test coverage
- Fluent API for video/audio dubbing
- Source file support (local and storage disks)
- Target language selection
- Dubbing options support
- Job status checking
- Queue support with RunDubbingJob
- Event system (DubbingCompleted)
- DubbingResult data model
- Status checking methods (isCompleted, isInProgress, isFailed)
- Storage disk integration
- Comprehensive test coverage
This package is open-sourced software licensed under the MIT license.
Contributions are welcome! Please feel free to submit a Pull Request.
For issues, questions, or contributions, please open an issue on GitHub.
Made with β€οΈ by DigitalCoreHub