Extending
Macros
Opener and MediaFactory are macroable, and the Media facade forwards MediaFactory macros:
use Foxws\Media\Opener;
Opener::macro('poster', fn (float $at = 5.0) => $this->ffmpeg()->frame(at: $at));
Media::fromDisk('videos')->open('clip.mp4')->poster()->save('poster.jpg');
Other executables
A package can run its own executable through the same runner as ffmpeg, with progress, cancelling, events, logging, redacted keys and Media::fake() support. Implement Foxws\Media\Executables\Binary, usually on an enum:
use Foxws\Media\Executables\Binary;
use Illuminate\Support\Facades\Config;
enum EncoderExecutable: string implements Binary
{
case Encoder = 'encoder';
public function identifier(): string
{
return $this->value;
}
public function configuredPath(): string
{
return Config::string('encoder.path', 'encoder');
}
public function environmentKey(): string
{
return 'ENCODER_PATH';
}
public function versionArguments(): array
{
return ['--version'];
}
}
Register it in a service provider, so media:info and about list it:
use Foxws\Media\Executables\Executables;
$this->app->make(Executables::class)->register(EncoderExecutable::Encoder);
Then run it with Foxws\Media\Process\Runner:
$result = app(Runner::class)->run(EncoderExecutable::Encoder, ['--input', $path], environment: ['ENCODER_LOG' => '1']);
In tests, $fake->respondUsing(EncoderExecutable::Encoder, fn (array $arguments) => 'output') fakes its output, and the assertions accept any Binary.
Packager drivers
Packaging drivers implement Foxws\Media\Packaging\Packager: package() receives a PackagingSpec with the streams, settings and encryption, and writes into a temporary directory that's exported like any other output, and command() returns the redacted command line for the builder's command():
use Foxws\Media\Packaging\PackagerManager;
$this->app->make(PackagerManager::class)->extend('custom', fn () => new CustomPackager);
Pick it per export with ->using('custom'), or for every export with MEDIA_PACKAGER=custom. Driver-specific settings are passed through withOption() and withOptions().
