Skip to main content

Usage

Basic Packaging

use Foxws\Streamer\Facades\Streamer;

Streamer::open('input.mp4')
->addVideoStream('input.mp4', 'video.mp4')
->addAudioStream('input.mp4', 'audio.mp4')
->withHlsMasterPlaylist('master.m3u8')
->export()
->save();

Cross-Disk Workflows

Read from one disk, write to another:

Streamer::fromDisk('s3')
->open('videos/input.mp4')
->addVideoStream('videos/input.mp4', 'video.mp4')
->addAudioStream('videos/input.mp4', 'audio.mp4')
->withHlsMasterPlaylist('master.m3u8')
->export()
->toDisk('export')
->toPath('streams/')
->withVisibility('public')
->save();

Encryption

withAESEncryption() returns an EncryptionKey value object (not $this), so it breaks the fluent chain — call it on its own line:

// AES-128 encryption with auto-generated key
$streamer = Streamer::open('input.mp4')
->addVideoStream('input.mp4', 'video.mp4')
->addAudioStream('input.mp4', 'audio.mp4')
->withHlsMasterPlaylist('master.m3u8');

$encryptionKey = $streamer->withAESEncryption();

$streamer->export()->save();

// With key rotation (rotates every 60 seconds)
$streamer = Streamer::open('input.mp4')
->addVideoStream('input.mp4', 'video.mp4')
->addAudioStream('input.mp4', 'audio.mp4')
->withHlsMasterPlaylist('master.m3u8');

$encryptionKey = $streamer->withAESEncryption('key', 'cenc');
$streamer->withKeyRotationDuration(60);

$streamer->export()->toDisk('s3')->save();

See the AES Encryption Guide for protection schemes, codec-specific examples, and key management.

Dynamic URL Resolvers

Serve HLS and DASH content with signed URLs — useful for S3, CDNs, or multi-tenant apps.

HLS:

use Foxws\Streamer\Http\DynamicHLSPlaylist;
use Illuminate\Support\Facades\Storage;

return (new DynamicHLSPlaylist('s3'))
->open("videos/{$video->id}/master.m3u8")
->setKeyUrlResolver(fn (string $key) => Storage::disk('s3')->temporaryUrl(
"videos/{$video->id}/{$key}",
now()->addHour(),
))
->setMediaUrlResolver(fn (string $file) => Storage::disk('s3')->temporaryUrl(
"videos/{$video->id}/{$file}",
now()->addHours(2),
))
->setPlaylistUrlResolver(fn (string $playlist) => route('video.playlist', [
'video' => $video,
'playlist' => $playlist,
]))
->toResponse(request());

DASH:

use Foxws\Streamer\Http\DynamicDASHManifest;
use Illuminate\Support\Facades\Storage;

return (new DynamicDASHManifest('s3'))
->open("videos/{$video->id}/manifest.mpd")
->setMediaUrlResolver(fn (string $file) => Storage::disk('s3')->temporaryUrl(
"videos/{$video->id}/{$file}",
now()->addHours(2),
))
->setInitUrlResolver(fn (string $file) => Storage::disk('s3')->temporaryUrl(
"videos/{$video->id}/{$file}",
now()->addHours(2),
))
->toResponse(request());

See URL Resolvers for more details.

Events

Listen to streaming lifecycle events:

EventPayload
StreamingStartedMediaCollection $mediaCollection, array $options
StreamingCompletedStreamerResult $result, float $executionTime
StreamingFailedException $exception, float $executionTime

Post-Export Inspection

After saving, you can inspect the result:

$exporter = Streamer::open('input.mp4')
->addVideoStream('input.mp4', 'video.mp4')
->addAudioStream('input.mp4', 'audio.mp4')
->withHlsMasterPlaylist('master.m3u8')
->export();

$exporter->afterSaving(function ($exporter, $result) {
$summary = $exporter->getCopySummary();
// ['total' => 12, 'copied' => 12, 'failed' => 0, 'totalSize' => 8421376]

$keys = $result->getUploadedEncryptionKeys();
});

$exporter->toDisk('s3')->save();

API Reference

Streamer Facade → MediaOpener

MethodDescription
fromDisk($disk)Set the source filesystem disk
open($paths)Open one or more media files
openFromDisk($disk, $paths)Set disk and open files in one call
get()Get the MediaCollection
export()Start the export chain (returns MediaExporter)
dynamicHLSPlaylist(?string $disk)Create a DynamicHLSPlaylist instance
dynamicDASHManifest(?string $disk)Create a DynamicDASHManifest instance
cleanupTemporaryFiles()Delete all temporary directories

Stream Configuration (via MediaOpenerStreamer)

MethodDescription
addVideoStream($input, $output, $options)Add a video stream
addAudioStream($input, $output, $options)Add an audio stream
addTextStream($input, $output, $options)Add a text/subtitle stream
addStream(Stream|array $stream)Add a Stream value object or raw stream descriptor (in, stream, output, …)
withHlsMasterPlaylist($path)Set HLS output
withMpdOutput($path)Set DASH/MPD output
withSegmentDuration(int $seconds)Set segment duration
withManifestFormat(array $formats)Set manifest formats (e.g. ['dash', 'hls'])
withResolutions(array $resolutions)Set encoding resolutions
withVideoCodecs(array $codecs)Set video codecs (e.g. ['h264', 'hw:vp9'])
withAudioCodecs(array $codecs)Set audio codecs (e.g. ['aac', 'opus'])
withSegmentPerFile(bool $enabled)Enable segment-per-file output
withLowLatencyDashMode(bool $enabled)Enable low-latency DASH
withStreamingMode(string $mode)Set mode ('vod' or 'live')
withEncryption(array $config)Set raw encryption config
withAESEncryption($keyFilename, $scheme, $label)Auto-generate AES encryption key, returns EncryptionKey (not $this)
withKeyRotationDuration(int $seconds)Enable key rotation (requires 'cenc' or 'cbcs')
withOption($key, $value)Set a custom pipeline option
withOptions(array $options)Set multiple custom pipeline options
getCommand()Get the built config array (for debugging)

MediaExporter (returned by export())

MethodDescription
toDisk($disk)Set target disk for output
toPath(string $path)Set target subdirectory
withVisibility(string $visibility)Set file visibility ('public', 'private')
afterSaving(callable $callback)Register post-save callback
save(?string $path)Execute packaging and copy files to disk
getCommand()Get the built config array
dd()Dump config and die
getCopySummary()Get {total, copied, failed, totalSize}
getCopiedFiles()Get array of successfully copied files
getFailedFiles()Get array of failed file copies
hasCopyFailures()Check if any files failed to copy

DynamicHLSPlaylist

MethodDescription
open(string $path)Open a playlist file
setKeyUrlResolver(callable)Resolve encryption key URLs
setMediaUrlResolver(callable)Resolve media segment URLs
setPlaylistUrlResolver(callable)Resolve sub-playlist URLs
get()Get processed playlist content
all()Get all processed playlists (master + variants)
toResponse($request)Return as application/vnd.apple.mpegurl response

DynamicDASHManifest

MethodDescription
open(string $path)Open a manifest file
setMediaUrlResolver(callable)Resolve media segment URLs
setInitUrlResolver(callable)Resolve initialization segment URLs
get()Get processed manifest content
toResponse($request)Return as application/dash+xml response

Configuration

Key options in config/streamer.php:

OptionDefaultDescription
streamer.streamer_binary'shaka-streamer'Path to the Shaka Streamer binary
timeout14400 (4h)Process timeout in seconds
temporary_files_rootstorage_path('app/streamer/temp')Directory for temporary files
cache_files_root'/dev/shm'Fast storage for small files (keys, manifests)
log_channelnullLog channel for streamer output

See Configuration for all options and environment variables.