Fluent API with fromDisk support
Basic usage
use Foxws\Shaka\Facades\Shaka;
// Default disk
$result = Shaka::open('input.mp4')
->addVideoStream('input.mp4', 'video.mp4')
->addAudioStream('input.mp4', 'audio.mp4')
->withMpdOutput('manifest.mpd')
->export();
Using different disks
// From S3, save to a different disk (e.g., local, s3, etc.)
$result = Shaka::fromDisk('s3')
->open('videos/input.mp4')
->addVideoStream('videos/input.mp4', 'video.mp4')
->withMpdOutput('manifest.mpd')
->export()
->toDisk('export')
->save();
// Helper method
$result = Shaka::openFromDisk('s3', 'videos/input.mp4')
->addVideoStream('videos/input.mp4', 'video.mp4')
->export()
->toDisk('export')
->save();
Available methods
Disk management
| Method |
What it does |
fromDisk(string $disk) |
Set the disk to read from |
openFromDisk(string $disk, $paths) |
Set the disk and open files in one call |
getDisk() |
Get the current disk instance |
| Method |
What it does |
open($paths) |
Open one or more media files |
get() |
Get the MediaCollection |
streams() |
Get the auto-generated Stream objects |
Stream configuration
| Method |
What it does |
addVideoStream(string $input, string $output, array $options = []) |
Add a video stream |
addAudioStream(string $input, string $output, array $options = []) |
Add an audio stream |
addTextStream(string $input, string $output, array $options = []) |
Add a text/caption/subtitle stream |
addStream(Stream|array $stream) |
Add a custom stream, with full control |
Output configuration
| Method |
What it does |
withMpdOutput(string $path) |
Set the DASH manifest output |
withBaseUrls(string|array $urls) |
Set the DASH <BaseURL> element(s) under <MPD> |
withHlsMasterPlaylist(string $path) |
Set the HLS master playlist output |
withSegmentDuration(int $seconds) |
Set the segment duration |
withAESEncryption(string $keyFilename = 'key', ProtectionScheme|string|null $protectionScheme = 'cbc1', ?string $label = null): EncryptionKey |
Turn on AES-128 encryption. Returns an EncryptionKey, not $this — this breaks the fluent chain. |
withKeyRotationDuration(int $seconds) |
Turn on key rotation for encryption |
toDisk(string $disk) |
Set the target disk for output |
toPath(string $path) |
Set the target output path (subdirectory) |
withVisibility(string $visibility) |
Set file visibility (e.g., public, private) |
Execution & utilities
| Method |
What it does |
export() |
Run the packaging operation (returns a result object) |
save(?string $path = null) |
Save outputs to disk (optionally to a specific path) |
getCommand() |
Get the final command string, for debugging |
dd() |
Dump the final command and stop the script |
afterSaving(callable $callback) |
Register a callback to run after saving |
Dynamic URL resolvers
DynamicHLSPlaylist:
| Method |
What it does |
new DynamicHLSPlaylist(?string $disk) |
Create an HLS playlist processor |
open(string $path) |
Open a playlist file |
setKeyUrlResolver(callable $resolver) |
Set the resolver for encryption key URLs |
setMediaUrlResolver(callable $resolver) |
Set the resolver for media segment URLs |
setPlaylistUrlResolver(callable $resolver) |
Set the resolver for sub-playlist URLs |
get() |
Get the processed playlist content |
all() |
Get every processed playlist (master + segments) |
toResponse($request) |
Return as an HTTP response |
DynamicDASHManifest:
| Method |
What it does |
new DynamicDASHManifest(?string $disk) |
Create a DASH manifest processor |
open(string $path) |
Open a manifest file |
setMediaUrlResolver(callable $resolver) |
Set the resolver for media segment URLs |
setInitUrlResolver(callable $resolver) |
Set the resolver for initialization segment URLs |
get() |
Get the processed manifest content |
toResponse($request) |
Return as an HTTP response |
See URL Resolvers for full documentation of both classes.
Common patterns
Adding captions/subtitles (WebVTT)
Shaka::fromDisk('s3')
->open('videos/source.mp4')
->addVideoStream('videos/source.mp4', 'video_1080p.mp4', [
'bandwidth' => '5000000',
])
->addAudioStream('videos/source.mp4', 'audio.mp4')
->addTextStream('captions/english.vtt', 'english.vtt', [
'language' => 'en',
])
->withMpdOutput('manifest.mpd')
->withSegmentDuration(6)
->export();
Adaptive bitrate streaming
Shaka::fromDisk('s3')
->open('videos/source.mp4')
->addVideoStream('videos/source.mp4', 'video_1080p.mp4', [
'bandwidth' => '5000000',
])
->addVideoStream('videos/source.mp4', 'video_720p.mp4', [
'bandwidth' => '3000000',
])
->addVideoStream('videos/source.mp4', 'video_480p.mp4', [
'bandwidth' => '1500000',
])
->addAudioStream('videos/source.mp4', 'audio.mp4')
->withMpdOutput('manifest.mpd')
->withSegmentDuration(6)
->export();
HLS with encryption
Shaka::fromDisk('s3')
->open('secure/video.mp4')
->addVideoStream('secure/video.mp4', 'video.m3u8')
->addAudioStream('secure/video.mp4', 'audio.m3u8')
->withHlsMasterPlaylist('master.m3u8')
->withEncryption([
'keys' => 'label=:key_id=abc:key=def',
'key_server_url' => 'https://example.com/license',
])
->export();
See AES Encryption for the recommended withAESEncryption() API.
Multiple files
Shaka::fromDisk('videos')
->open(['intro.mp4', 'main.mp4', 'outro.mp4'])
->addVideoStream('intro.mp4', 'intro_video.mp4')
->addVideoStream('main.mp4', 'main_video.mp4')
->addVideoStream('outro.mp4', 'outro_video.mp4')
->withMpdOutput('manifest.mpd')
->export();
Error handling
try {
$result = Shaka::fromDisk('s3')
->open('video.mp4')
->addVideoStream('video.mp4', 'output.mp4')
->withMpdOutput('manifest.mpd')
->export();
logger()->info('Success', $result->getOutput());
} catch (\Foxws\Shaka\Exceptions\RuntimeException $e) {
logger()->error('Packaging failed', ['error' => $e->getMessage()]);
} catch (\InvalidArgumentException $e) {
logger()->error('Invalid input', ['error' => $e->getMessage()]);
}
Configuration
config/laravel-shaka.php
return [
'packager' => [
'binaries' => env('PACKAGER_PATH', '/usr/local/bin/packager'),
],
'timeout' => 60 * 60 * 4, // 4 hours
'log_channel' => env('PACKAGER_LOG_CHANNEL', false),
'temporary_files_root' => env('PACKAGER_TEMPORARY_FILES_ROOT', storage_path('app/packager/temp')),
'concurrency_workers' => env('PACKAGER_CONCURRENCY_WORKERS', 30), // Max concurrent S3 uploads (default: 30)
];
concurrency_workers
- The maximum number of concurrent S3 uploads when copying packaged files to an S3-backed disk.
- Ignored for local disks.
- Default: 30.
- Only raise it after measuring: it bounds an async promise pool (
GuzzleHttp\Promise\EachPromise), so throughput scales with concurrency until you saturate either the destination's write throughput or the local disk's read speed for segment files. Against a local/self-hosted S3-compatible store (low latency, high bandwidth), higher values pay off faster than against real AWS S3 over the internet — there's no universally correct number, so watch upload duration and destination-side load before pushing past 30-50.
See the full Configuration page for every available option.
Artisan commands
# Verify packager installation
php artisan shaka:info
Direct driver usage
use Foxws\Shaka\Support\Packager\ShakaPackager;
$driver = ShakaPackager::create();
$version = $driver->getVersion();
$driver->setTimeout(7200);
CommandBuilder direct usage
use Foxws\Shaka\Support\Packager\CommandBuilder;
use Foxws\Shaka\Support\Packager\Packager;
$builder = CommandBuilder::make()
->addVideoStream('input.mp4', 'output.mp4')
->withMpdOutput('manifest.mpd');
$packager = app(Packager::class);
$result = $packager->packageWithBuilder($builder);
Stream objects
use Foxws\Shaka\Support\Packager\Stream;
use Foxws\Shaka\Support\Filesystem\Media;
$media = Media::make('videos', 'input.mp4');
$videoStream = Stream::video($media)
->setOutput('video.mp4')
->addOption('bandwidth', '5000000');
$audioStream = Stream::audio($media)
->setOutput('audio.mp4');
$commandString = $videoStream->toCommandString();
Examples location
- Basic examples:
examples/PackagerExamples.php
- Fluent API examples:
examples/FluentBuilderExamples.php
- fromDisk examples:
examples/FromDiskExamples.php
Testing
// Unit tests
vendor/bin/pest tests/Unit/ShakaPackagerTest.php
vendor/bin/pest tests/Unit/PackagerTest.php
vendor/bin/pest tests/Unit/FromDiskTest.php