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

Media Bundle Laravel Package

darkwood/media-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require darkwood/media-bundle
    

    Ensure bin/console is executable (chmod +x bin/console).

  2. First Use Case: Generate a video from the bundled example:

    php bin/console app:video:generate examples/video.yaml
    

    Verify output in var/output/ (configurable via .env).

  3. Where to Look First:

    • YAML Schema: examples/video.yaml (defines scenes, voiceovers, and assets).
    • Configuration: docs/mvp-video.md (environment variables, Replicate setup).
    • Output: The tool generates:
      • Per-scene assets (var/output/scenes/).
      • A manifest.json (metadata for all assets).
  4. Quick Test: Run the mock tests to validate setup:

    make phpunit
    

    This skips live Replicate calls, using HTTP mocks instead.


Implementation Patterns

Usage Patterns

1. YAML-Driven Workflow

  • Define: Create a YAML file (e.g., storage/app/video_templates/welcome.yaml) with scenes like:
    scenes:
      - type: text
        content: "Welcome to {{user.name}}!"
        voice: "elevenlabs/voice-clone"
      - type: video
        source: "storage/app/media/intro.mp4"
    
  • Generate: Invoke the tool via Artisan or a Laravel command:
    php bin/console app:video:generate storage/app/video_templates/welcome.yaml
    
  • Consume: Parse manifest.json in Laravel to store metadata in a Video model:
    $manifest = json_decode(file_get_contents('var/output/manifest.json'), true);
    Video::create([
        'user_id' => $user->id,
        'scenes' => $manifest['scenes'],
        'status' => 'generated',
    ]);
    

2. Laravel Integration

  • Artisan Command Wrapper: Create a Laravel command to abstract the tool’s CLI:
    // app/Console/Commands/GenerateVideoCommand.php
    use Symfony\Component\Process\Process;
    
    class GenerateVideoCommand extends Command {
        protected $signature = 'video:generate {yaml} {--user= : User ID}';
        protected $description = 'Generate video for a user';
    
        public function handle() {
            $process = new Process(['php', 'bin/console', 'app:video:generate', $this->argument('yaml')]);
            $process->run();
    
            if (!$process->isSuccessful()) {
                $this->error($process->getErrorOutput());
                return 1;
            }
    
            // Store manifest in DB
            $manifest = json_decode(file_get_contents('var/output/manifest.json'), true);
            Video::create([
                'user_id' => $this->option('user'),
                'manifest' => $manifest,
            ]);
        }
    }
    
  • API Endpoint: Expose generation via a controller:
    // routes/api.php
    Route::post('/videos', [VideoController::class, 'generate']);
    
    // app/Http/Controllers/VideoController.php
    class VideoController extends Controller {
        public function generate(Request $request) {
            $yamlPath = $request->user()->videoTemplatePath();
            Artisan::call('video:generate', ['yaml' => $yamlPath, '--user' => $request->user()->id]);
            return response()->json(['status' => 'queued']);
        }
    }
    

3. Dynamic YAML Generation

  • Use Laravel’s Blade or a service to generate YAML dynamically:
    // app/Services/YamlGenerator.php
    class YamlGenerator {
        public function generateWelcomeVideo(User $user) {
            $yaml = <<<YAML
            scenes:
              - type: text
                content: "Welcome, {$user->name}!"
                voice: "elevenlabs/voice-clone"
            YAML;
            file_put_contents(storage_path("app/video_templates/{$user->id}.yaml"), $yaml);
            return storage_path("app/video_templates/{$user->id}.yaml");
        }
    }
    

4. Asset Management

  • Storage: Configure the tool’s output directory in .env:
    MEDIA_BUNDLE_OUTPUT_DIR=storage/app/video_assets
    
  • Symlinks: Create a symlink for public access:
    ln -s storage/app/video_assets/public var/www/html/videos
    
  • Cleanup: Add a Laravel scheduler job to purge old assets:
    // app/Console/Commands/CleanupVideoAssets.php
    class CleanupVideoAssets extends Command {
        public function handle() {
            $assetsDir = storage_path('app/video_assets');
            $this->deleteOldFiles($assetsDir, now()->subDays(30));
        }
    }
    

5. Benchmark Mode

  • Test locally without hitting Replicate:
    php bin/console app:video:generate video.yaml --env=local --benchmark
    
  • Useful for CI/CD pipelines to validate YAML syntax and structure.

Workflows

1. Personalized Video Emails

  • Workflow:
    1. User triggers an email (e.g., order confirmation).
    2. Laravel generates a YAML template with dynamic data ({{order.id}}).
    3. Queue a GenerateVideoJob with the YAML path.
    4. Tool generates assets; manifest is attached to the email.
  • Example Job:
    // app/Jobs/GenerateVideoJob.php
    class GenerateVideoJob implements ShouldQueue {
        use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    
        public function handle() {
            $yamlPath = $this->generateYamlForOrder($order);
            Artisan::queue('video:generate', ['yaml' => $yamlPath]);
        }
    }
    

2. Batch Processing

  • Process multiple YAML files in parallel:
    // app/Console/Commands/BatchGenerateVideos.php
    class BatchGenerateVideos extends Command {
        public function handle() {
            $yamlFiles = glob(storage_path('app/video_templates/batch/*.yaml'));
            foreach ($yamlFiles as $file) {
                Artisan::queue('video:generate', ['yaml' => $file]);
            }
        }
    }
    

3. Webhook Triggers

  • Trigger generation via a webhook (e.g., from a CMS):
    // routes/web.php
    Route::post('/webhooks/video-generate', function (Request $request) {
        $yaml = $request->yaml;
        file_put_contents(storage_path("app/webhook_templates/{$request->id}.yaml"), $yaml);
        Artisan::queue('video:generate', ['yaml' => storage_path("app/webhook_templates/{$request->id}.yaml")]);
        return response()->json(['status' => 'accepted']);
    });
    

Integration Tips

1. Environment Variables

  • Pass Replicate API keys via Laravel’s .env:
    REPLICATE_API_TOKEN=your_token_here
    
  • Override in the tool’s CLI call:
    php bin/console app:video:generate video.yaml --env=production
    

2. Error Handling

  • Catch tool failures in Laravel:
    try {
        Artisan::call('video:generate', ['yaml' => $yamlPath]);
    } catch (\Exception $e) {
        Video::updateOrCreate(
            ['user_id' => $user->id],
            ['status' => 'failed', 'error' => $e->getMessage()]
        );
        Log::error("Video generation failed: {$e->getMessage()}");
    }
    

3. Testing

  • Mock the tool’s HTTP calls in Laravel tests:
    // tests/Feature/VideoGenerationTest.php
    use Symfony\Component\Process\Process;
    
    public function test_video_generation() {
        $process = Process::fromShellCommandline(
            'php bin/console app:video:generate examples/video.yaml --benchmark'
        );
        $process->run();
    
        $this->assertTrue($process->isSuccessful());
        $this->assertFileExists('var/output/manifest.json');
    }
    

4. Extending the YAML Schema

  • Add custom scene types by extending the tool’s configuration (see config/packages/darkwood_media.yaml).
  • Example: Add a custom_scene type:
    # config/packages/darkwood_media.yaml
    darkwood_media:
        scene_types:
            custom_scene:
                handler: App\Services\CustomSceneHandler
    
  • Implement the handler:
    // app/Services/CustomSceneHandler.php
    class CustomSceneHandler {
        public function render(array $scene) {
            // Custom logic (e.g., call a GraphQL
    
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.
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager