Upgrading
Upgrading from 2.x
3.0 is built on foxws/laravel-media. The package now only adds Shaka Packager, as a driver for laravel-media's packaging builder. Opening media, disks, temporary files, running processes, uploads, encryption keys, signed playlists, events and fakes come from laravel-media.
Requirements
- Laravel 13 (12 is no longer supported), PHP 8.4.
foxws/laravel-media^0.3.4 is installed with the package.
Packaging
The Shaka facade, MediaOpener, Packager, MediaExporter and CommandBuilder are gone. Open media with laravel-media and call shaka(), then pass the directory to save():
// 2.x
$packager = Shaka::fromDisk('media')->open('videos/clip.mp4');
try {
$packager
->addVideoStream('videos/clip.mp4', 'video.mp4')
->addAudioStream('videos/clip.mp4', 'audio.mp4')
->withMpdOutput('index.mpd')
->withHlsMasterPlaylist('master.m3u8')
->export()
->toDisk('s3')
->toPath('streams/clip/')
->save();
} finally {
$packager->cleanupTemporaryFiles();
}
// 3.0
Media::fromDisk('media')
->open('videos/clip.mp4')
->shaka()
->addVideoStream('videos/clip.mp4', 'video.mp4')
->addAudioStream('videos/clip.mp4', 'audio.mp4')
->withDashManifest('index.mpd')
->withHlsPlaylist('master.m3u8')
->toDisk('s3')
->save('streams/clip');
cleanupTemporaryFiles()is no longer needed: laravel-media deletes temporary files after every queue job and request.export()is gone:toDisk(),withVisibility(),afterSaving()andsave()are on the builder.save()returns anExportResult(the disk and the saved paths, manifests first) instead of the opener.- The first argument of
add*Stream()is optional: it defaults to the first opened file. A path you didn't open is read from the same disk, instead of being passed to Shaka Packager as a local path. addStream()and theStreamvalue object are removed. UseaddVideoStream(),addAudioStream()oraddTextStream(), and pass descriptor fields asoptions.
Methods
| 2.x | 3.0 |
|---|---|
withMpdOutput() |
withDashManifest() |
withHlsMasterPlaylist(), withHlsPlaylistType() |
withHlsPlaylist($path, HlsPlaylistType::Vod) |
withSegmentDuration(), withFragmentDuration() |
segmentDuration(), fragmentDuration() |
withDefaultLanguage(), withDefaultTextLanguage() |
defaultLanguage(), defaultTextLanguage() |
withAllowCodecSwitching(), withAllowApproximateSegmentTimeline() |
allowCodecSwitching(), approximateSegmentTimeline(), or both with forVod() |
withAESEncryption($keyFile, $scheme, $label) |
withEncryption(keyFile: $keyFile, scheme: ProtectionScheme::Cbcs, label: $label) |
withProtectionScheme(), withHlsKeyUri() |
withEncryption(scheme: ..., keyUri: ...) |
withKeyRotationDuration(), withCryptoPeriodDuration() |
withKeyRotation() |
withClearLead() |
unchanged |
withBaseUrls(), withHlsBaseUrl(), the live DASH and encryption options |
methods on ShakaOptions, passed with withOptions(), mostly the same names without with (see Usage) |
withProtectionSystems('Widevine,PlayReady') |
protectionSystems(ProtectionSystem::Widevine, ProtectionSystem::PlayReady) |
withUtcTimings('scheme=value') |
utcTimings(['scheme' => 'value']) |
withEnableWidevineEncryption(), withKeyServerUrl(), withContentId(), withPolicy() |
widevine($keyServerUrl, $contentId, $policy) |
withEnablePlayreadyEncryption(), withPlayreadyServerUrl(), withProgramIdentifier() |
playready($serverUrl, $programIdentifier) |
withSigner() with withAesSigningKey() and withAesSigningIv(), or withRsaSigningKeyPath(), withSigningCredentials() |
aesSigning($signer, $key, $iv) or rsaSigning($signer, $keyPath) |
withCaFile(), withClientCertFile(), withClientCertPrivateKeyFile(), withClientCertPrivateKeyPassword() |
keyServerTls(...) |
withMaxSdPixels(), withMaxHdPixels(), withMaxUhd1Pixels() |
maxPixels(sd: ..., hd: ..., uhd1: ...) |
withEnableRawKeyDecryption(), withEnableWidevineDecryption() |
decrypt(), decrypt(widevine: true) |
withEnableRawKeyEncryption(), withKeys() |
set by withEncryption() |
withOption() |
unchanged; removeOption() is withOption($name, null) |
getCommand(), dd() |
command() |
withAESEncryption() returned the key; withEncryption() generates one unless you pass an EncryptionKey, and $result->encryptionKey() returns it after save(). getEncryptionKeys() is gone: with key rotation, Shaka Packager derives the later keys from that one.
Serving streams
Shaka::dynamicHLSPlaylist() and Shaka::dynamicDASHManifest() are replaced by laravel-media's:
// 2.x
Shaka::dynamicHLSPlaylist('s3')->setMediaUrlResolver($resolver)->open('streams/clip/master.m3u8')->toResponse($request);
// 3.0
Media::fromDisk('s3')->open('streams/clip/master.m3u8')->hlsPlaylist()->resolveMediaUrlsUsing($resolver)->toResponse($request);
setKeyUrlResolver(), setMediaUrlResolver() and setPlaylistUrlResolver() are now resolveKeyUrlsUsing(), resolveMediaUrlsUsing() and resolvePlaylistUrlsUsing(). Resolvers receive the file's path on the disk.
Events and exceptions
PackagingStarted,PackagingCompletedandPackagingFailedare removed. Listen to laravel-media'sProcessStarted,ProcessCompletedandProcessFailed, orExportCompletedandExportFailed(withwithContext()).- Shaka Packager failures throw laravel-media's
ProcessFailedException, withisRetryable(), instead ofRuntimeException. A missing binary throws laravel-media'sExecutableNotFoundException. - Invalid options and field names throw
InvalidArgumentException.
Configuration
config/laravel-shaka.php is now config/shaka.php, published with the shaka-config tag:
| 2.x | 3.0 |
|---|---|
packager.binaries (PACKAGER_PATH) |
binary (SHAKA_PACKAGER_BINARY) |
timeout (PACKAGER_TIMEOUT) |
timeout (SHAKA_PACKAGER_TIMEOUT) |
segment_duration, packager_options |
segmentDuration() and withOptions() per run |
log_channel, temporary_files_*, cache_files_*, the S3 upload options |
laravel-media's config/media.php |
force_generic_input |
removed: inputs with unsafe names are always linked under a plain name |
php artisan shaka:info is replaced by php artisan media:info, which lists packager.
Tests
Replace Process::fake() with FakeShaka::respond(Media::fake()). See Testing.
