Weave 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

Laravel Media Converter Laravel Package

meema/laravel-media-converter

Laravel Media Converter uses FFmpeg to convert uploaded video and audio files via queued jobs, with progress tracking and custom conversion formats. It handles thumbnails, streaming, and S3 storage, giving you a clean, configurable API for background media processing.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Check compatibility before installing. The last release was August 2021, so inspect composer.json for constraints on laravel/framework and aws/aws-sdk-php before committing. On Laravel 9+ you may need --with-all-dependencies, a fork, or a version alias.
  • Install the package: composer require meema/laravel-media-converter.
  • Publish the config (provider or tag depends on version):
    php artisan vendor:publish --provider="Meema\MediaConverter\MediaConverterServiceProvider"
    
    This gives you config/media-converter.php, which is the first file to read.
  • Set the environment variables the config expects — typically AWS credentials, region, the MediaConvert service role ARN, and an S3 disk/bucket:
    AWS_ACCESS_KEY_ID=
    AWS_SECRET_ACCESS_KEY=
    AWS_DEFAULT_REGION=us-east-1
    AWS_MEDIACONVERT_ROLE_ARN=arn:aws:iam::123456789012:role/MediaConvertRole
    MEDIA_CONVERTER_DISK=s3
    
  • Run migrations if the package ships a jobs table. If it doesn't, create your own media_jobs/videos table with job_id, status, input, output, error.
  • Where to look first: config/media-converter.php, then the facade and src/MediaConverter.php. This is a small package — reading the source is faster and more reliable than searching for docs. Confirm the exact method signatures there rather than trusting blog posts.
  • First use case — upload → transcode → HLS: upload the source with Storage::disk('s3')->putFileAs(...), submit a conversion, persist the returned job ID, then confirm completion.
    use Meema\MediaConverter\Facades\MediaConvert;
    
    $job = MediaConvert::convert(
        'uploads/source.mp4',
        'outputs/'.$video->id.'/hls/master.m3u8'
    );
    
    $video->update([
        'media_job_id' => $job->id ?? $job,
        'status'       => 'processing',
    ]);
    
    The exact signature varies by version — verify against the facade before wiring it into a controller.

Implementation Patterns

1. Submit from a queued job, never from the HTTP request. The AWS API call plus any preset lookups can be slow and flaky. Dispatch a ShouldQueue job after the S3 upload is confirmed:

class SubmitConversion implements ShouldQueue
{
    public function __construct(public Video $video) {}

    public function handle(): void
    {
        $job = MediaConvert::convert(
            $this->video->source_path,
            $this->video->hls_output_path,
        );

        $this->video->update([
            'media_job_id' => $job->id ?? $job,
            'status'       => 'processing',
        ]);
    }
}

2. Track state on your own model. Treat the package as a thin AWS client and own the state machine: uploaded → queued → processing → complete | failed, plus output_url, duration, error_message. This keeps your UI decoupled from MediaConvert's status vocabulary and makes retries possible.

3. Sync statuses with a scheduled command. Poll job status from a command scheduled with withoutOverlapping():

Schedule::command('videos:sync-statuses')->everyFiveMinutes()->withoutOverlapping();

Batch only processing rows, update in chunks, and back off once a job is older than expected.

4. Prefer EventBridge over polling for production. MediaConvert emits MediaConvert Job State Change events. Route them through EventBridge → API Gateway → a Laravel webhook, verify a shared secret, and update the model. This avoids polling costs, rate limits, and eventual-consistency delays. The package does not wire this up for you.

5. Presets vs. inline settings. Use custom presets for repeatable renditions (consistent across environments); pass inline output-group settings for one-off jobs (thumbnails, single MP4). System presets are region-scoped and get deprecated, so pin custom ones.

6. Multi-output jobs. One MediaConvert job can emit HLS, DASH, MP4 renditions, and thumbnails. Store outputs as JSON on your model and expose relationships/accessors rather than hard-coding column names per rendition.

7. Local development and testing. Never hit AWS in tests. Fake the facade if the package supports it; otherwise bind a mocked MediaConvertClient in the container. Keep a tiny fixture MP4, and assert on the submitted job settings rather than the AWS response.

8. Integration tips.

  • Keep the S3 bucket private and serve playback via CloudFront + signed URLs.
  • Configure bucket CORS for your player domain.
  • Put the MediaConvert queue ARN in config so staging and production can use separate queues.
  • Log the AWS job ID on every submit — it's the only reliable correlation key in the AWS console.

Gotchas and Tips

  • Package age and dependency conflicts. A 2021 release means Illuminate and AWS SDK constraints can block Laravel 10/11. Check first; be prepared to fork or use a replace in composer.json.
  • Region endpoint errors. The MediaConvert API is region-specific. If you see “Unable to resolve endpoint” or signature errors, confirm AWS_DEFAULT_REGION and, if the config exposes it, set the regional endpoint explicitly.
  • The service role is the #1 failure cause. The role ARN must be assumable by mediaconvert.amazonaws.com and have S3 read on the input prefix and write on the output prefix. A wrong role surfaces as jobs stuck in SUBMITTED or failing with opaque errors.
  • S3 path format. Confirm whether the config expects disk-relative keys (uploads/a.mp4) or full URIs (s3://bucket/uploads/a.mp4). Mixing them causes AccessDenied.
  • Status is eventually consistent. Poll every 30–60 seconds, not every second. COMPLETE can lag behind the output actually appearing in S3.
  • Errors hide in errorMessage. On ERROR, log the job's errorMessage and the CloudWatch log group configured in job settings. Without CloudWatch logging enabled, failures are nearly undebuggable.
  • Config caching. Run php artisan config:cache (and config:clear locally) after changing env values; stale config is a common source of "it works in tinker but not in the app."
  • No retries or cancellation semantics built in. cancel only works before completion. Implement retry/backoff and idempotency yourself using the stored job ID.
  • Quotas and throttling. MediaConvert has concurrent-job limits per account/region. Catch LimitExceededException and requeue rather than failing the user's video.
  • Cost multiplies with renditions. Billing is per output minute — an HLS ladder with six renditions costs roughly six times the source duration. Cap renditions per plan tier.
  • Extension points to know: publishable config, the container binding for the underlying AWS client (swap for a mock or a custom wrapper), and the ability to pass raw output-group settings through the facade. If the package lacks a hook, wrap it in your own service class rather than editing vendor code.
  • Debugging toolkit: AWS SDK debug logging (AWS_DEBUG or an SDK middleware), Storage::disk('s3')->exists($path) checks after completion, and the AWS MediaConvert console filtered by job ID.
  • Small ecosystem. 56 stars and zero dependents means few Stack Overflow answers — budget time for reading src/ and pin the version in composer.json.
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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core