Video model), while the tool handles asset generation, creating a clean separation of concerns.Process, Console) minimizes friction. The tool’s CLI-first design avoids Laravel-specific dependencies, reducing integration complexity.app:video:generate) can be invoked from Laravel via:
Process facade to execute the tool programmatically (e.g., in a job or controller).GenerateVideoJob) for async processing.VideoTemplate model or API payload) and passes it to the tool.symfony/console, symfony/process) may introduce version conflicts with Laravel’s dependencies. Risk mitigation:
conflict-checker or why-not to identify conflicts.composer.json to align with Laravel’s versions.storage/app/public) must be configured to grant the tool’s user (e.g., www-data) appropriate permissions..env or a secrets manager).mix or a CDN)?Seedance 2.0) be overridden or extended?Process facade or Artisan commands. Avoid deep integration with Symfony’s DI container unless necessary.VideoTemplate model).Video model).storage/app/video_assets).Storage facade to:
storage/app/video_templates/).storage/app/video_manifests/.mix or a CDN (e.g., S3)..env (e.g., REPLICATE_API_KEY).mvp-video.md).env() helper or a dedicated service to inject keys into the tool’s process.composer require darkwood/media-bundle
php bin/console app:video:generate examples/video.yaml
--benchmark flag to avoid live API calls.GenerateVideoCommand) that:
spatie/fork or custom rules).Process::run() with environment variables.Video model.use Symfony\Component\Process\Process;
use Illuminate\Support\Facades\Log;
class GenerateVideoCommand extends Command {
protected $signature = 'video:generate {template : Path to YAML template}';
protected $description = 'Generate video assets from a YAML template';
public function handle() {
$yamlPath = storage_path('app/video_templates/' . $this->argument('template'));
$manifestPath = storage_path('app/video_manifests/manifest.json');
$process = new Process([
'php', 'bin/console', 'app:video:generate', $yamlPath,
'--env', 'REPLICATE_API_KEY=' . env('REPLICATE_API_KEY'),
]);
$process->run();
if (!$process->isSuccessful()) {
Log::error('Video generation failed', ['output' => $process->getOutput()]);
throw new \RuntimeException('Failed to generate video');
}
// Parse manifest and save to DB
$manifest = json_decode(file_get_contents($manifestPath), true);
Video::create([
'template' => $this->argument('template'),
'status' => 'generated',
'metadata' => $manifest,
]);
}
}
GenerateVideoJob) for async processing.POST /api/videos):
public function generate(GenerateVideoRequest $request) {
GenerateVideoJob::dispatch($request->template)->onQueue('videos');
return response()->json(['status' => 'queued']);
}
queue:failed or job:handled events).monolog (e.g., log all stdout/stderr).How can I help you explore Laravel packages today?