PHPackages                             yoanbernabeu/music-gpt-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. yoanbernabeu/music-gpt-bundle

ActiveSymfony-bundle[API Development](/categories/api)

yoanbernabeu/music-gpt-bundle
=============================

Symfony bundle for integrating Music GPT API into your applications

V0.1.0(5mo ago)12MITPHPPHP &gt;=8.4CI passing

Since Nov 29Pushed 5mo agoCompare

[ Source](https://github.com/yoanbernabeu/music-gpt-bundle)[ Packagist](https://packagist.org/packages/yoanbernabeu/music-gpt-bundle)[ RSS](/packages/yoanbernabeu-music-gpt-bundle/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (9)Versions (2)Used By (0)

Music GPT Bundle
================

[](#music-gpt-bundle)

A Symfony bundle for integrating [Music GPT API](https://musicgpt.com/api) into your applications.

> **🎵 Powered by [MusicGPT.com](https://musicgpt.com)** - Generate AI music and covers
> **🔌 API Access**: [musicgpt.com/api](https://musicgpt.com/api)

[![PHP Version](https://camo.githubusercontent.com/9c2f8ad80d34105266a94c4c06234f8ed18c968d3595039c2d9a7becd1e71c8b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253345253344382e342d626c75652e737667)](https://php.net/)[![Symfony](https://camo.githubusercontent.com/e5965b201347fe13e6a1bfbd76d95a11ba2ebdc4a710df71f1df7a89bad34520/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f73796d666f6e792d253545372e30253743253545382e302d677265656e2e737667)](https://symfony.com/)[![License](https://camo.githubusercontent.com/074b89bca64d3edc93a1db6c7e3b1636b874540ba91d66367c0e5e354c56d0ea/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e737667)](LICENSE)[![QA](https://github.com/yoanbernabeu/music-gpt-bundle/actions/workflows/qa.yml/badge.svg)](https://github.com/yoanbernabeu/music-gpt-bundle/actions/workflows/qa.yml)

Features
--------

[](#features)

- 🎵 **Music AI** - Generate custom music from text prompts
- 🎤 **Cover Songs** - Transform audio with AI voice models
- 🗣️ **Text To Speech** - Convert text to realistic speech with voice models
- 🎼 **Audio Extraction** - Extract stems (vocals, drums, bass, etc.) from audio
- 🎙️ **Voice Management** - Search and list AI voices
- 🔍 **Conversion Tracking** - Check status and retrieve results
- 🚀 **Type-Safe** - Full PHP 8.4 type safety with DTOs and Enums
- 📦 **Easy to Use** - Simple, intuitive API

Installation
------------

[](#installation)

```
composer require yoanbernabeu/music-gpt-bundle
```

If you're using Symfony Flex, the bundle will be automatically registered. Otherwise, add it to your `config/bundles.php`:

```
return [
    // ...
    YoanBernabeu\MusicGptBundle\MusicGptBundle::class => ['all' => true],
];
```

Configuration
-------------

[](#configuration)

Create `config/packages/music_gpt.yaml`:

```
music_gpt:
    api:
        api_key: '%env(MUSIC_GPT_API_KEY)%'
```

Add your API key to `.env`:

```
MUSIC_GPT_API_KEY=your_api_key_here
```

Get your API key at [musicgpt.com/api](https://musicgpt.com/api).

Usage
-----

[](#usage)

### Generate Music with AI

[](#generate-music-with-ai)

```
use YoanBernabeu\MusicGptBundle\Contract\MusicAIServiceInterface;
use YoanBernabeu\MusicGptBundle\DTO\MusicAI\MusicAIRequest;

class MusicController
{
    public function __construct(
        private readonly MusicAIServiceInterface $musicAI
    ) {}

    public function generate(): void
    {
        // Simple prompt
        $request = new MusicAIRequest(
            prompt: 'A cheerful song about coding in PHP'
        );

        $response = $this->musicAI->generate($request);

        echo "Task ID: {$response->getTaskId()}\n";
        echo "ETA: {$response->getEta()} seconds\n";
    }

    public function generateAdvanced(): void
    {
        // With custom style and vocals
        $request = new MusicAIRequest(
            musicStyle: 'Lo-fi Hip Hop',
            lyrics: 'Coding all night long...',
            voiceId: 'Drake',
            makeInstrumental: false
        );

        $response = $this->musicAI->generate($request);

        // The API generates 2 versions
        [$version1, $version2] = $response->getConversionIds();
    }
}
```

**Available Parameters:**

- `prompt` - Natural language description
- `musicStyle` - Genre (Rock, Pop, Jazz, Lo-fi, etc.)
- `lyrics` - Custom lyrics
- `voiceId` - Voice model for vocals
- `makeInstrumental` - Generate without vocals (default: false)
- `vocalOnly` - Generate vocals only (default: false)
- `webhookUrl` - Callback URL for async notifications

### Create AI Voice Covers

[](#create-ai-voice-covers)

```
use YoanBernabeu\MusicGptBundle\Contract\CoverServiceInterface;
use YoanBernabeu\MusicGptBundle\DTO\Cover\CoverRequest;

class CoverController
{
    public function __construct(
        private readonly CoverServiceInterface $cover
    ) {}

    public function create(): void
    {
        // From URL
        $request = new CoverRequest(
            audioUrl: 'https://example.com/song.mp3',
            voiceId: 'Drake'
        );

        $response = $this->cover->createCover($request);

        echo "Task ID: {$response->getTaskId()}\n";
        echo "Conversion ID: {$response->getConversionId()}\n";
    }

    public function createWithPitch(): void
    {
        // From local file with pitch adjustment
        $request = new CoverRequest(
            audioFile: '/path/to/audio.wav',
            voiceId: 'Taylor Swift',
            pitch: -2  // -12 to +12 semitones
        );

        $response = $this->cover->createCover($request);
    }
}
```

**Note:** Provide either `audioUrl` OR `audioFile`, not both.

### Generate Text To Speech

[](#generate-text-to-speech)

```
use YoanBernabeu\MusicGptBundle\Contract\TextToSpeechServiceInterface;
use YoanBernabeu\MusicGptBundle\DTO\TextToSpeech\TextToSpeechRequest;

class TextToSpeechController
{
    public function __construct(
        private readonly TextToSpeechServiceInterface $textToSpeech
    ) {}

    public function create(): void
    {
        // Simple text to speech with voice ID
        $request = new TextToSpeechRequest(
            text: 'Hello world, this is a test of the text to speech feature.',
            gender: 'male',
            voiceId: 'Drake'
        );

        $response = $this->textToSpeech->createTextToSpeech($request);

        echo "Task ID: {$response->getTaskId()}\n";
        echo "ETA: {$response->getEta()} seconds\n";
    }

    public function createWithSampleAudio(): void
    {
        // Using a sample audio URL for voice cloning
        $request = new TextToSpeechRequest(
            text: 'The character Sherlock Holmes first appeared in print in 1887.',
            gender: 'female',
            sampleAudioUrl: 'https://example.com/voice-sample.mp3'
        );

        $response = $this->textToSpeech->createTextToSpeech($request);
    }

    public function createWithWebhook(): void
    {
        // With webhook for async notification
        $request = new TextToSpeechRequest(
            text: 'When I think of superheroes I think of super humans.',
            gender: 'male',
            voiceId: 'Drake',
            webhookUrl: 'https://example.com/webhook'
        );

        $response = $this->textToSpeech->createTextToSpeech($request);
    }
}
```

**Available Parameters:**

- `text` (required) - Text content to convert to speech
- `gender` (required) - Voice gender: "male" or "female"
- `voiceId` (optional) - Voice model ID (e.g., "Drake", "Adele")
- `sampleAudioUrl` (optional) - URL of voice sample for cloning
- `webhookUrl` (optional) - Callback URL for async notifications

**Note:** Priority is given to `sampleAudioUrl`, then `voiceId`, then `gender`.

### Extract Audio Stems

[](#extract-audio-stems)

```
use YoanBernabeu\MusicGptBundle\Contract\ExtractionServiceInterface;
use YoanBernabeu\MusicGptBundle\DTO\Extraction\ExtractionRequest;

class ExtractionController
{
    public function __construct(
        private readonly ExtractionServiceInterface $extraction
    ) {}

    public function extractVocals(): void
    {
        // Extract vocals from a song
        $request = new ExtractionRequest(
            audioUrl: 'https://example.com/song.mp3',
            stems: ['vocals', 'instrumental']
        );

        $response = $this->extraction->extractStems($request);

        echo "Task ID: {$response->getTaskId()}\n";
        echo "ETA: {$response->getEta()} seconds\n";
    }

    public function extractMultipleStems(): void
    {
        // Extract multiple stems from a song
        $request = new ExtractionRequest(
            audioUrl: 'https://example.com/song.mp3',
            stems: ['vocals', 'drums', 'bass', 'guitar', 'piano']
        );

        $response = $this->extraction->extractStems($request);
    }

    public function extractWithPreprocessing(): void
    {
        // Extract with audio cleanup
        $request = new ExtractionRequest(
            audioFile: '/path/to/audio.wav',
            stems: ['vocals'],
            preprocessingOptions: ['Denoise', 'Dereverb']
        );

        $response = $this->extraction->extractStems($request);
    }

    public function cleanupAudio(): void
    {
        // Only apply preprocessing without extraction
        $request = new ExtractionRequest(
            audioUrl: 'https://example.com/noisy-audio.mp3',
            preprocessingOptions: ['Denoise', 'Deecho', 'Dereverb']
        );

        $response = $this->extraction->extractStems($request);
    }
}
```

**Available Stems:**

- Basic: `vocals`, `instrumental`
- Vocal types: `male_vocal`, `female_vocal`, `lead_vocal`, `back_vocal`
- Instruments: `bass`, `drums`, `guitar`, `piano`, `keys`, `strings`, `winds`
- Guitar types: `rhythm_guitar`, `solo_guitar`, `acoustic_guitar`, `electric_guitar`
- Drum components: `kick_drum`, `snare_drum`, `toms`, `hi_hat`, `ride`, `crash`

**Preprocessing Options:**

- `Denoise` - Remove background noise
- `Deecho` - Remove echo effects
- `Dereverb` - Remove reverb effects

**Note:** Provide either `audioUrl` OR `audioFile`, not both.

### Search and List Voices

[](#search-and-list-voices)

```
use YoanBernabeu\MusicGptBundle\Contract\VoiceServiceInterface;

class VoiceController
{
    public function __construct(
        private readonly VoiceServiceInterface $voice
    ) {}

    public function searchVoices(): void
    {
        // Search for voices by name
        $response = $this->voice->searchVoices('Drake');

        echo "Found {$response->getTotal()} voices\n";

        foreach ($response->getVoices() as $voice) {
            echo "ID: {$voice->getVoiceId()} - Name: {$voice->getVoiceName()}\n";
        }
    }

    public function searchWithPagination(): void
    {
        // Search with pagination
        $response = $this->voice->searchVoices(
            query: 'Taylor',
            limit: 50,
            page: 0
        );

        echo "Page {$response->getPage()} of " .
             ceil($response->getTotal() / $response->getLimit()) . "\n";
    }

    public function listAllVoices(): void
    {
        // Get all available voices
        $response = $this->voice->getAllVoices(limit: 100, page: 0);

        echo "Total voices available: {$response->getTotal()}\n";
        echo "Showing: " . count($response->getVoices()) . " voices\n";
    }

    public function browseVoices(): void
    {
        // Browse through all voices with pagination
        $page = 0;
        $limit = 20;

        do {
            $response = $this->voice->getAllVoices($limit, $page);

            foreach ($response->getVoices() as $voice) {
                echo "{$voice->getVoiceName()}\n";
            }

            $page++;
        } while (($page * $limit) < $response->getTotal());
    }
}
```

**Available Methods:**

- `searchVoices(string $query, int $limit = 20, int $page = 0)` - Search voices by name
- `getAllVoices(int $limit = 20, int $page = 0)` - Get all available voices

**Response Data:**

- `getVoices()` - Array of VoiceInfo objects
- `getTotal()` - Total number of voices available
- `getLimit()` - Results per page
- `getPage()` - Current page number

### Track Conversion Status

[](#track-conversion-status)

```
use YoanBernabeu\MusicGptBundle\Contract\ConversionServiceInterface;
use YoanBernabeu\MusicGptBundle\Enum\ConversionType;

class ConversionController
{
    public function __construct(
        private readonly ConversionServiceInterface $conversion
    ) {}

    public function checkStatus(): void
    {
        // Get details by Task ID
        $details = $this->conversion->getByTaskId(
            taskId: 'task_123456',
            conversionType: ConversionType::MUSIC_AI
        );

        if ($details->isCompleted()) {
            echo "✅ Completed!\n";
            echo "Audio 1: {$details->getAudioUrl1()}\n";
            echo "Audio 2: {$details->getAudioUrl2()}\n";
        } elseif ($details->isProcessing()) {
            echo "⏳ Processing: {$details->getStatus()}\n";
        } elseif ($details->isFailed()) {
            echo "❌ Failed: {$details->getStatusMessage()}\n";
        }
    }

    public function getByConversionId(): void
    {
        // Get details by Conversion ID
        $details = $this->conversion->getByConversionId(
            conversionId: 'conv_789012',
            conversionType: ConversionType::COVER
        );

        if ($details->isCompleted()) {
            echo "Audio: {$details->getAudioUrl()}\n";
            echo "Video: {$details->getVideoUrl()}\n";
            echo "Cover: {$details->getImageUrl()}\n";
        }
    }

    public function checkTextToSpeech(): void
    {
        // Check Text To Speech conversion
        $details = $this->conversion->getByTaskId(
            taskId: 'task_tts_123',
            conversionType: ConversionType::TEXT_TO_SPEECH
        );

        if ($details->isCompleted()) {
            echo "✅ Speech generated!\n";
            echo "Audio (MP3): {$details->getAudioUrl()}\n";
            echo "Audio (WAV): {$details->getAudioUrlWav()}\n";
        }
    }

    public function checkExtraction(): void
    {
        // Check Extraction conversion
        $details = $this->conversion->getByTaskId(
            taskId: 'task_extract_456',
            conversionType: ConversionType::EXTRACTION
        );

        if ($details->isCompleted()) {
            echo "✅ Stems extracted!\n";
            echo "Vocals: {$details->getVocalsUrl()}\n";
            echo "Instrumental: {$details->getInstrumentalUrl()}\n";
        }
    }
}
```

### Complete Workflow Example

[](#complete-workflow-example)

```
use YoanBernabeu\MusicGptBundle\Contract\MusicAIServiceInterface;
use YoanBernabeu\MusicGptBundle\Contract\ConversionServiceInterface;
use YoanBernabeu\MusicGptBundle\DTO\MusicAI\MusicAIRequest;
use YoanBernabeu\MusicGptBundle\Enum\ConversionType;

class WorkflowController
{
    public function __construct(
        private readonly MusicAIServiceInterface $musicAI,
        private readonly ConversionServiceInterface $conversion
    ) {}

    public function generateAndWait(): void
    {
        // 1. Generate music
        $request = new MusicAIRequest(prompt: 'A relaxing piano melody');
        $response = $this->musicAI->generate($request);

        $taskId = $response->getTaskId();

        // 2. Poll for completion
        $maxAttempts = 30;
        for ($i = 0; $i < $maxAttempts; $i++) {
            sleep(10);

            $details = $this->conversion->getByTaskId(
                $taskId,
                ConversionType::MUSIC_AI
            );

            if ($details->isCompleted()) {
                echo "✅ Done!\n";
                echo "Download: {$details->getAudioUrl1()}\n";
                break;
            }

            if ($details->isFailed()) {
                echo "❌ Failed: {$details->getStatusMessage()}\n";
                break;
            }

            echo "⏳ Processing... (attempt {$i}/{$maxAttempts})\n";
        }
    }
}
```

Error Handling
--------------

[](#error-handling)

```
use YoanBernabeu\MusicGptBundle\Exception\AuthenticationException;
use YoanBernabeu\MusicGptBundle\Exception\PaymentRequiredException;
use YoanBernabeu\MusicGptBundle\Exception\RateLimitException;
use YoanBernabeu\MusicGptBundle\Exception\ValidationException;

try {
    $response = $this->musicAI->generate($request);
} catch (AuthenticationException $e) {
    // Invalid API key (401/403)
    echo "Authentication error: {$e->getMessage()}";
} catch (PaymentRequiredException $e) {
    // Insufficient credits (402)
    echo "Payment required: {$e->getMessage()}";
} catch (RateLimitException $e) {
    // Too many requests (429)
    echo "Rate limited. Retry after: {$e->getRetryAfter()} seconds";
} catch (ValidationException $e) {
    // Invalid parameters (400/422)
    echo "Validation errors: " . print_r($e->getErrors(), true);
}
```

Rate Limits
-----------

[](#rate-limits)

Different plans have different limits. When rate limited (429), use `$exception->getRetryAfter()` to know when to retry.

PlanAudio GenerationsGet by IDFree1 parallel20/minPLUS5 parallel200/minPRO10 parallel500/minSee [official rate limits documentation](https://docs.musicgpt.com/api-documentation/utilities/ratelimits).

API Documentation
-----------------

[](#api-documentation)

### Main Documentation

[](#main-documentation)

- [Music GPT API Docs](https://docs.musicgpt.com)

### Conversion Endpoints

[](#conversion-endpoints)

- [Music AI Endpoint](https://docs.musicgpt.com/api-documentation/conversions/musicai)
- [Cover Endpoint](https://docs.musicgpt.com/api-documentation/conversions/cover)
- [Text To Speech Endpoint](https://docs.musicgpt.com/api-documentation/conversions/texttospeech)
- [Extraction Endpoint](https://docs.musicgpt.com/api-documentation/endpoint/extraction)

### Helper Endpoints

[](#helper-endpoints)

- [Get by ID Endpoint](https://docs.musicgpt.com/api-documentation/endpoint/getById)
- [Search Voices](https://docs.musicgpt.com/api-documentation/endpoint/searchVoices)
- [Get All Voices](https://docs.musicgpt.com/api-documentation/endpoint/getAllVoices)

Development
-----------

[](#development)

Run tests:

```
composer test
```

Check code style:

```
composer cs-check
composer cs-fix
```

Static analysis:

```
composer phpstan
```

Run all checks:

```
composer cs-check && composer phpstan && composer test
```

License
-------

[](#license)

This bundle is open-sourced software licensed under the [MIT license](LICENSE).

Author
------

[](#author)

**Yoan Bernabeu**

- Website: [yoandev.com](https://yoandev.co)
- GitHub: [@yoanbernabeu](https://github.com/yoanbernabeu)

Support
-------

[](#support)

For questions or issues, please open an issue on [GitHub](https://github.com/yoanbernabeu/music-gpt-bundle).

###  Health Score

35

—

LowBetter than 79% of packages

Maintenance71

Regular maintenance activity

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

164d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/21f6c1e090b5d45bb8bd5569f7779bde35d19fd06844327ed0d369c3544fa2e8?d=identicon)[yoanbernabeu](/maintainers/yoanbernabeu)

---

Top Contributors

[![yoanbernabeu](https://avatars.githubusercontent.com/u/59195351?v=4)](https://github.com/yoanbernabeu "yoanbernabeu (5 commits)")

---

Tags

aigenerative-aimusicmusic-aisymfony-bundle

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/yoanbernabeu-music-gpt-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/yoanbernabeu-music-gpt-bundle/health.svg)](https://phpackages.com/packages/yoanbernabeu-music-gpt-bundle)
```

###  Alternatives

[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.4k5.6M651](/packages/sylius-sylius)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
