Search by

ekandreas / sayit

EkAndreas

Converts text to speech via AWS and place it in a S3 bucket folder

Package info

github.com/ekandreas/sayit

pkg:composer/ekandreas/sayit

Fund package maintenance!

ekandreas

Statistics

Installs: 142

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

1.7 2026-10-19 12:17 UTC

This package is auto-updated.

Last update: 2026-10-19 12:18:17 UTC


README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

Converts text to speech via AWS and place it in a S3 bucket folder This package is PHP agnostic. Follow these steps to get started:

  1. composer require ekandreas/sayit
  2. Register an IAM programmatic account and set policy S3 full access and Polly Full Access to it.
  3. Use the key, secret, region and bucket name with the factory helper.
  4. Open a public folder in your S3 bucket and create a folder in it.

Code example:

$factory = TextToSpeech::make(
    $aws_key,
    $aws_secret,
    $aws_region,
    $aws_bucket
)
    ->voice("Elin")
    ->engine('neural')
    ->generate("Hej på dig, det här kommer att läsas upp i en mp3 efter generering.")
    ->store("your-folder");

// the url now points to a public s3 folder "your-folder" with a unique mp3 file generated from the text above.
$url = $factory->url();

ElevenLabs

Speech can also be generated with ElevenLabs. The mp3 is still stored in your S3 bucket. Pass your ElevenLabs API key and a voice ID to switch provider:

$factory = TextToSpeech::make(
    $aws_key,
    $aws_secret,
    $aws_region,
    $aws_bucket
)
    ->elevenlabs($elevenlabs_key, $elevenlabs_voice_id) // optional third argument: model, default "eleven_multilingual_v2"
    ->generate("Hej på dig, det här kommer att läsas upp i en mp3 efter generering.")
    ->store("your-folder");

Switch between providers with ->provider('polly') or ->provider('elevenlabs'). The voice ID and model can also be changed with ->elevenlabsVoice($id) and ->elevenlabsModel($model). The language is forced to Swedish by default. Change it with ->elevenlabsLanguage('en') (ISO 639-1), or pass null to let ElevenLabs detect it from the text.

Several texts in one file (e.g. a radio show)

generate() replaces what was generated before, append() adds to it. Voice can be changed between parts. Long texts are split into chunks automatically.

$factory = TextToSpeech::make($aws_key, $aws_secret, $aws_region, $aws_bucket)
    ->elevenlabs($elevenlabs_key, $host_voice_id)
    ->generate("Välkommen till Lindenytt radio.")
    ->elevenlabsVoice($reporter_voice_id)
    ->append($article1)
    ->append($article2)
    ->store("radio", "radio-2026-10-19"); // optional file name, default a unique id

// or, with one voice
$factory->generateMany([$intro, $article1, $article2])->store("radio");

Don't mix Polly and ElevenLabs in the same file, they produce different sample rates.

Delete a stored file

TextToSpeech::make($aws_key, $aws_secret, $aws_region, $aws_bucket)
    ->delete($url); // the url returned by ->url(), or an S3 key

Installation

You can install the package via composer:

composer require ekandreas/sayit

Testing

composer test

Set SAYIT_ELEVENLABS_KEY and SAYIT_ELEVENLABS_VOICE in .env to also run the ElevenLabs test.

Credits

License

The MIT License (MIT). Please see License File for more information.