PHPackages                             modularavel/cloudflare-stream-video - 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. modularavel/cloudflare-stream-video

ActiveLibrary

modularavel/cloudflare-stream-video
===================================

A Laravel package that provides an idiomatic, strongly typed interface to the Cloudflare Stream Video API. Upload, manage, and stream videos with signed URLs, watermark overlays, and webhook-driven processing.

0.1.0(yesterday)11↑2900%[3 PRs](https://github.com/modularavel/cloudflare-stream-video/pulls)MITPHPPHP ^8.3CI passing

Since Jul 28Pushed todayCompare

[ Source](https://github.com/modularavel/cloudflare-stream-video)[ Packagist](https://packagist.org/packages/modularavel/cloudflare-stream-video)[ Docs](https://github.com/modularavel/cloudflare-stream-video)[ GitHub Sponsors](https://github.com/modularavel)[ RSS](/packages/modularavel-cloudflare-stream-video/feed)WikiDiscussions main Synced today

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

 [![Cloudflare Stream Video Package Banner](arts/modularavel-cloudflare-stream-video.png)](arts/modularavel-cloudflare-stream-video.png)

Cloudflare Stream Video Package
===============================

[](#cloudflare-stream-video-package)

 [![Packagist](https://camo.githubusercontent.com/194dd0ebb62724eed1d5f09b5d4e28b40f4e15e0afd47ae69eb996fae1eaff5e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d6f64756c61726176656c2f636c6f7564666c6172652d73747265616d2d766964656f2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/modularavel/cloudflare-stream-video) [![PHP from Packagist](https://camo.githubusercontent.com/bb6a7b020ba0822bca2781d6b06b7784103647f3c63dcd65daa2ce2cd63d676d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6d6f64756c61726176656c2f636c6f7564666c6172652d73747265616d2d766964656f2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/modularavel/cloudflare-stream-video) [![Laravel versions](https://camo.githubusercontent.com/b781ca8c7b9374a68856c363a15d820de58c52d3c4ecb75d8d2eb9f7586dbb13/68747470733a2f2f62616467652e6c61726176656c2e636c6f75642f62616467652f6d6f64756c61726176656c2f636c6f7564666c6172652d73747265616d2d766964656f3f7374796c653d666c6174)](https://packagist.org/packages/modularavel/cloudflare-stream-video) [![GitHub Workflow Status (main)](https://camo.githubusercontent.com/b0ea25c8358608d0ae4267aec6e1ea31f2c14e444150582f84628f07f06719d5/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6d6f64756c61726176656c2f636c6f7564666c6172652d73747265616d2d766964656f2f74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d5465737473267374796c653d666c61742d737175617265)](https://github.com/modularavel/cloudflare-stream-video/actions) [![Total Downloads](https://camo.githubusercontent.com/a68f227f113e30184d564cf82e99fe26d83689f9828894021d3abe311c1a8863/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6d6f64756c61726176656c2f636c6f7564666c6172652d73747265616d2d766964656f2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/modularavel/cloudflare-stream-video)

A Laravel package that provides an idiomatic, strongly typed interface to the [Cloudflare Stream Video API](https://developers.cloudflare.com/stream/). Upload, manage, and stream videos with signed URLs, watermark overlays, and webhook-driven processing — all from within your Laravel application.

Features
--------

[](#features)

- **Video Management** — Upload (TUS), copy from URL, direct upload, list, get, update, and delete videos
- **Signed Playback URLs** — HMAC-SHA256 signed tokens for restricted video access
- **Watermark Management** — Create, list, update, delete watermarks; apply/remove watermarks on videos
- **Webhook Integration** — Receive Cloudflare Stream processing notifications, process them asynchronously via queued jobs, and broadcast completion events
- **Blade Player Component** — Responsive iframe embed component with signed URL support
- **Artisan Commands** — CLI commands for video import, sync, signed URL generation, and watermark management
- **Config Publishing** — All configuration, views, translations, and assets are publishable

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

[](#installation)

You can install the package via Composer:

```
composer require modularavel/cloudflare-stream-video
```

### Publishing Resources

[](#publishing-resources)

You may publish all of the package's resources at once:

```
php artisan vendor:publish --tag="cloudflare-stream-video"
```

Or, publish each resource individually:

#### Configuration

[](#configuration)

```
php artisan vendor:publish --tag="cloudflare-stream-video-config"
```

After publishing, edit `config/cloudflare-stream-video.php` to configure your Cloudflare account.

#### Migrations

[](#migrations)

```
php artisan vendor:publish --tag="cloudflare-stream-video-migrations"
php artisan migrate
```

This will create:

- `cloudflare_stream_videos` — Local cache of Cloudflare Stream videos
- `cloudflare_stream_webhooks` — Audit log for webhook deliveries

#### Views

[](#views)

```
php artisan vendor:publish --tag="cloudflare-stream-video-views"
```

#### Translations

[](#translations)

```
php artisan vendor:publish --tag="cloudflare-stream-video-lang"
```

#### Public Assets

[](#public-assets)

```
php artisan vendor:publish --tag="cloudflare-stream-video-assets"
```

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

[](#configuration-1)

After publishing the config file, edit `config/cloudflare-stream-video.php` to match your Cloudflare account credentials and preferences. Environment variables (with `CLOUDFLARE_STREAM_` prefix) take precedence over config file values.

### 🔑 Required Settings

[](#-required-settings)

🔧 Key🌿 Env Variable📝 Description`account_id``CLOUDFLARE_STREAM_ACCOUNT_ID`Your Cloudflare account identifier`api_token``CLOUDFLARE_STREAM_API_TOKEN`API token with "Stream Edit" or "Stream Read" permissions### ⚙️ Optional Settings

[](#️-optional-settings)

🔧 Key🌿 Env Variable💡 Default📝 Description`timeout``CLOUDFLARE_STREAM_TIMEOUT``120`HTTP request timeout in seconds`defaults`—`[]`Default key-value pairs merged into every API request body`require_signed_urls``CLOUDFLARE_STREAM_REQUIRE_SIGNED_URLS``false`Whether videos require signed URLs for playback`signing_key``CLOUDFLARE_STREAM_SIGNING_KEY``''`HMAC-SHA256 signing key for signed URL generation`customer_domain``CLOUDFLARE_STREAM_CUSTOMER_DOMAIN``''`Custom Cloudflare Stream customer domain for signed URLs`watermark.default_position`—`'bottom-right'`Default watermark position on the video frame`watermark.default_opacity`—`1.0`Default watermark opacity (0.0–1.0)`watermark.default_width`—`0`Default watermark width in pixels`watermark.default_height`—`0`Default watermark height in pixels`webhook.secret``CLOUDFLARE_STREAM_WEBHOOK_SECRET``''`Secret used to verify incoming webhook signatures`webhook.route``CLOUDFLARE_STREAM_WEBHOOK_ROUTE``'cloudflare-stream-video/webhook'`Route path for receiving webhook notifications### 🔐 Environment Example

[](#-environment-example)

```
CLOUDFLARE_STREAM_ACCOUNT_ID=your-account-id
CLOUDFLARE_STREAM_API_TOKEN=your-api-token
CLOUDFLARE_STREAM_SIGNING_KEY=your-64-character-signing-key
CLOUDFLARE_STREAM_WEBHOOK_SECRET=your-webhook-secret
```

Usage
-----

[](#usage)

### Basic Video Operations

[](#basic-video-operations)

The `CloudflareStreamVideo` facade (or inject `CloudflareStreamVideoInterface`) provides the full API surface.

#### Upload a Video (TUS)

[](#upload-a-video-tus)

```
use Modularavel\CloudflareStreamVideo\Facades\CloudflareStreamVideo;

// Upload a local video file using the TUS resumable protocol.
$video = CloudflareStreamVideo::upload('/path/to/video.mp4', [
    'meta' => ['name' => 'My Awesome Video', 'source' => 'laravel'],
    'maxDurationSeconds' => 3600,
]);

echo $video->uid;    // e.g. "cab807e0c477d01baq20f66c3d1dfc26cf"
echo $video->status; // e.g. "ready"
```

#### Copy a Video from a URL

[](#copy-a-video-from-a-url)

```
// Fetch and process a video from a publicly accessible URL.
$video = CloudflareStreamVideo::copy('https://example.com/video.mp4', [
    'meta' => ['name' => 'Imported Video'],
]);
```

#### Create a Direct Upload

[](#create-a-direct-upload)

```
// Generate a one-time upload URL for client-side use.
$upload = CloudflareStreamVideo::createDirectUpload([
    'maxDurationSeconds' => 300,
    'expiry' => now()->addHours(1)->toIso8601String(),
]);

// Pass $upload->uploadUrl to your frontend client.
// The upload URL is valid until expiry or until the video is uploaded.
```

#### List Videos

[](#list-videos)

```
// Retrieve all videos with optional filtering.
$videos = CloudflareStreamVideo::listVideos([
    'status' => 'ready',
    'limit' => 100,
]);

foreach ($videos as $video) {
    echo $video->uid . ' - ' . $video->status;
}
```

#### Get a Single Video

[](#get-a-single-video)

```
$video = CloudflareStreamVideo::getVideo('cab807e0c477d01baq20f66c3d1dfc26cf');

echo $video->uid;
echo $video->status;
echo $video->duration;
echo $video->getHlsUrl();   // e.g. "https://customer.cloudflarestream.com/.../manifest/video.m3u8"
echo $video->getDashUrl();  // e.g. "https://customer.cloudflarestream.com/.../manifest/video.mpd"
echo $video->getEmbedUrl(); // e.g. "https://embed.videodelivery.net/embed/iframe/..."
```

#### Update a Video

[](#update-a-video)

```
$video = CloudflareStreamVideo::updateVideo('cab807e0c477d01baq20f66c3d1dfc26cf', [
    'meta' => ['name' => 'Updated Title', 'tags' => 'tutorial,php'],
    'requireSignedURLs' => true,
]);
```

#### Delete a Video

[](#delete-a-video)

```
$deleted = CloudflareStreamVideo::deleteVideo('cab807e0c477d01baq20f66c3d1dfc26cf');
```

### Signed URLs

[](#signed-urls)

When a signing key is configured, you can generate signed playback URLs and tokens.

```
use Modularavel\CloudflareStreamVideo\Facades\CloudflareStreamVideo;

// Generate a full signed embed URL (valid for 2 hours by default).
$signedUrl = CloudflareStreamVideo::signedEmbedUrl(
    'cab807e0c477d01baq20f66c3d1dfc26cf',
    now()->addHours(2)->toDateTimeString(),
);

// Generate only the signed token (for use in custom embed URLs or HLS/DASH manifests).
$token = CloudflareStreamVideo::signedToken(
    'cab807e0c477d01baq20f66c3d1dfc26cf',
    now()->addHours(2)->toDateTimeString(),
);
```

### Watermarking

[](#watermarking)

Watermarks are overlay images (typically PNG or SVG with transparency) that can be applied to videos during playback. They are managed per-account and associated with videos via their UID.

#### Create a Watermark

[](#create-a-watermark)

```
use Modularavel\CloudflareStreamVideo\Facades\CloudflareStreamVideo;

$watermark = CloudflareStreamVideo::createWatermark(
    name: 'Brand Logo',
    url: 'https://example.com/watermark.png',
    position: 'bottom-right',
    opacity: 0.8,
    width: 200,
    height: 50,
);

echo $watermark->uid; // e.g. "wm-brand-123"
```

#### List All Watermarks

[](#list-all-watermarks)

```
$watermarks = CloudflareStreamVideo::listWatermarks();

foreach ($watermarks as $wm) {
    echo $wm->uid . ' - ' . $wm->name;
}
```

#### Get a Single Watermark

[](#get-a-single-watermark)

```
$watermark = CloudflareStreamVideo::getWatermark('wm-brand-123');
```

#### Update a Watermark

[](#update-a-watermark)

```
$watermark = CloudflareStreamVideo::updateWatermark('wm-brand-123', [
    'opacity' => 0.5,
    'position' => 'top-left',
]);
```

#### Delete a Watermark

[](#delete-a-watermark)

```
$deleted = CloudflareStreamVideo::deleteWatermark('wm-brand-123');
```

#### Apply a Watermark to a Video

[](#apply-a-watermark-to-a-video)

```
$video = CloudflareStreamVideo::applyWatermark(
    'cab807e0c477d01baq20f66c3d1dfc26cf',
    'wm-brand-123',
);
```

#### Remove a Watermark from a Video

[](#remove-a-watermark-from-a-video)

```
$video = CloudflareStreamVideo::removeWatermark('cab807e0c477d01baq20f66c3d1dfc26cf');
```

### Webhook Integration

[](#webhook-integration)

Cloudflare Stream can send webhook notifications when video processing events occur (e.g. `video.ready`, `video.error`). The package provides a webhook endpoint, a background job for async processing, and an event for broadcasting completion.

#### Setup

[](#setup)

1. **Configure the webhook secret** in your `.env`:

```
CLOUDFLARE_STREAM_WEBHOOK_SECRET=your-webhook-secret
```

2. **Configure the webhook route** (optional, defaults to `cloudflare-stream-video/webhook`):

```
CLOUDFLARE_STREAM_WEBHOOK_ROUTE=cloudflare-stream-video/webhook
```

3. **Register the webhook URL** in the Cloudflare Stream dashboard under **Notifications** -&gt; **Webhooks**. The URL will be:

```
https://your-app.com/cloudflare-stream-video/webhook

```

#### Handling Webhook Events

[](#handling-webhook-events)

The package dispatches a `StreamVideoProcessed` event whenever a webhook is received. You can listen for this event in your application:

```
// In a service provider or event subscriber:
use Modularavel\CloudflareStreamVideo\Events\StreamVideoProcessed;

Event::listen(StreamVideoProcessed::class, function (StreamVideoProcessed $event) {
    // $event->eventType  — e.g. "video.ready", "video.error"
    // $event->videoUid   — the Cloudflare video UID
    // $event->payload    — the full raw webhook payload

    if ($event->eventType === 'video.ready') {
        // Video encoding completed — update your database, notify users, etc.
        $video = Video::where('cloudflare_uid', $event->videoUid)->first();
        if ($video) {
            $video->update(['status' => 'ready']);
        }
    }

    if ($event->eventType === 'video.error') {
        // Video encoding failed — log the error, notify admins, etc.
        Log::error('Cloudflare Stream encoding failed for video: ' . $event->videoUid, [
            'payload' => $event->payload,
        ]);
    }
});
```

#### Webhook Payload Structure

[](#webhook-payload-structure)

Cloudflare Stream sends webhook payloads with the following structure:

```
{
    "event_type": "video.ready",
    "result": {
        "uid": "cab807e0c477d01baq20f66c3d1dfc26cf",
        "status": {
            "state": "ready",
            "pctComplete": "100"
        },
        "meta": { "name": "My Video" }
    }
}
```

#### Webhook Signature Verification

[](#webhook-signature-verification)

The webhook controller verifies incoming requests using HMAC-SHA256 signatures. The signature is sent in the `X-Cloudflare-Signature` header as a hex-encoded HMAC digest of the raw request body.

If no `CLOUDFLARE_STREAM_WEBHOOK_SECRET` is configured, signature verification is skipped (not recommended for production).

#### Webhook Database Table

[](#webhook-database-table)

The package includes a migration that creates the `cloudflare_stream_webhooks` table for auditing webhook deliveries:

```
php artisan vendor:publish --tag="cloudflare-stream-video-migrations"
php artisan migrate
```

The table stores:

- `event_type` — the Cloudflare Stream event type
- `video_uid` — the video identifier from the payload
- `payload` — the raw JSON payload (nullable)
- `processed` — boolean flag indicating whether the background job has processed the webhook

### Blade Player Component

[](#blade-player-component)

The package includes a responsive Blade component for embedding Cloudflare Stream videos.

#### Basic Usage

[](#basic-usage)

```
{{-- Simple unsigned embed --}}

```

#### Signed Mode

[](#signed-mode)

```
{{-- Signed embed with expiry --}}

```

#### Custom Dimensions and Styling

[](#custom-dimensions-and-styling)

```

```

The component renders a responsive iframe wrapper with the Cloudflare Stream embed player. When `signed` is `true`, the component generates a signed embed URL using the configured signing key.

### Artisan Commands

[](#artisan-commands)

#### Placeholder Command

[](#placeholder-command)

```
php artisan cloudflare-stream-video:placeholder
```

A basic command that confirms the package is installed and working.

#### Import Video from URL

[](#import-video-from-url)

```
php artisan cloudflare-stream-video:import https://example.com/video.mp4

# With metadata
php artisan cloudflare-stream-video:import https://example.com/video.mp4 \
    --meta="name=My Video" \
    --meta="source=laravel"
```

#### Sync Videos

[](#sync-videos)

```
php artisan cloudflare-stream-video:sync
```

Syncs videos from Cloudflare Stream with your local database.

#### Generate Signed URL

[](#generate-signed-url)

```
php artisan cloudflare-stream-video:sign video-uid-123

# With custom expiry
php artisan cloudflare-stream-video:sign video-uid-123 --expires=2030-01-01T00:00:00Z

# With details output
php artisan cloudflare-stream-video:sign video-uid-123 --details
```

#### Watermark Management

[](#watermark-management)

```
# Create a watermark
php artisan cloudflare-stream-video:watermark create \
    --name="Brand Logo" \
    --url="https://example.com/watermark.png" \
    --position="bottom-right" \
    --opacity=0.8

# List all watermarks
php artisan cloudflare-stream-video:watermark list

# Get a watermark by UID
php artisan cloudflare-stream-video:watermark get --watermark-uid=wm-brand-123

# Update a watermark
php artisan cloudflare-stream-video:watermark update \
    --watermark-uid=wm-brand-123 \
    --opacity=0.5

# Delete a watermark
php artisan cloudflare-stream-video:watermark delete --watermark-uid=wm-brand-123

# Apply a watermark to a video
php artisan cloudflare-stream-video:watermark apply \
    --video-uid=cab807e0c477d01baq20f66c3d1dfc26cf \
    --watermark-uid=wm-brand-123

# Remove a watermark from a video
php artisan cloudflare-stream-video:watermark remove \
    --video-uid=cab807e0c477d01baq20f66c3d1dfc26cf
```

🧪 Testes
--------

[](#-testes)

 [![Cloudflare Stream Video Package Tests](arts/tests.webp)](arts/tests.webp)

O pacote conta com **86 testes** e **150 assertions** usando Pest PHP:

```
# Rodar o conjunto completo de testes
composer test

# Rodar apenas testes unitários
composer test:unit

# Rodar verificação de estilo (Pint)
composer lint:check

# Rodar análise estática (PHPStan)
composer analyse
```

📚 Contribute
------------

[](#-contribute)

We welcome your contributions! Please check out our [contributing guide](.github/CONTRIBUTING.md) for details.

---

🔒 Security Policy
-----------------

[](#-security-policy)

Report security vulnerabilities responsibly through our [security policy](.github/SECURITY.md).

---

👨‍💻 Author
----------

[](#‍-author)

| | --- | |

[![Casimiro Rocha](https://github.com/casimirorocha.png?width=100)
**Casimiro Rocha**](https://github.com/casimirorocha)[📧 contato@crsistemas.dev.br](mailto:contato@crsistemas.dev.br)

 |---

📄 License
---------

[](#-license)

This project is licensed under the [MIT License](LICENSE.md) — see the LICENSE.md file for details.

---

✨ Support
---------

[](#-support)

If you've found this package useful, please ⭐ the repository to show your support!

---

 Made with ❤️ by [Modularavel](https://github.com/modularavel)

 **Version 0.1.0**

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance100

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity38

Early-stage or recently created project

 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

1d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/149928614?v=4)[modularavel](/maintainers/modularavel)[@modularavel](https://github.com/modularavel)

---

Top Contributors

[![casimirorocha](https://avatars.githubusercontent.com/u/6707152?v=4)](https://github.com/casimirorocha "casimirorocha (9 commits)")

---

Tags

laravelmodularavelcloudflare-stream-video

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/modularavel-cloudflare-stream-video/health.svg)

```
[![Health](https://phpackages.com/badges/modularavel-cloudflare-stream-video/health.svg)](https://phpackages.com/packages/modularavel-cloudflare-stream-video)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M348](/packages/psalm-plugin-laravel)[api-platform/laravel

API Platform support for Laravel

58174.6k17](/packages/api-platform-laravel)

PHPackages © 2026

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