MediaEncoder
Output / mux: compose an output from one or more stream views, choosing per stream whether to re-encode or stream-copy, then write it to disk.
A MediaEncoder holds only references to the streams you map (which keep their
Media alive) — no long-lived native memory. save() is stateless
and re-runnable: it builds the output context, transcodes, and tears everything down
within the call, so the same encoder can be saved to several paths.
Methods
Section titled “Methods”addVideo(VideoStream $stream, VideoCodec $codec, ?int $crf = null, ?string $preset = null, ?int $bitrate = null): static
Section titled “addVideo(VideoStream $stream, VideoCodec $codec, ?int $crf = null, ?string $preset = null, ?int $bitrate = null): static”Map a video stream into the output. $codec is a
VideoCodec — e.g. VideoCodec::H264 to re-encode, or
VideoCodec::Copy to remux without re-encoding. Chainable.
Optional quality controls (all ignored when $codec is Copy):
| Argument | Type | Meaning |
|---|---|---|
$crf | ?int | Constant Rate Factor — quality, lower = better. Encoder-specific range (e.g. 0–51 for H.264/H.265). With crf set and no bitrate, encoding is pure constant-quality. |
$preset | ?string | Encoder speed/quality trade-off, e.g. "ultrafast" … "veryslow" for x264/x265. |
$bitrate | ?int | Target video bitrate in bits/sec. |
Throws EncodingException if the chosen encoder doesn’t support
a given option (e.g. an unknown preset, or crf on an encoder without it).
addAudio(AudioStream $stream, AudioCodec $codec, ?int $bitrate = null): static
Section titled “addAudio(AudioStream $stream, AudioCodec $codec, ?int $bitrate = null): static”Map an audio stream into the output. $codec is an
AudioCodec. Optional $bitrate sets the target audio
bitrate in bits/sec (ignored for Copy). Chainable.
save(string $path): void
Section titled “save(string $path): void”Write the configured output to $path; the container is inferred from the extension.
- Requires at least one mapping — video-only and audio-only are both valid.
- Throws
EncoderNotFoundExceptionif a chosen encoder isn’t built into this FFmpeg. - Throws
EncodingExceptionon any other failure, carrying->operation+->avError.
Examples
Section titled “Examples”Re-encode video, copy audio
Section titled “Re-encode video, copy audio”use FFmpeg\{Media, MediaEncoder};use FFmpeg\Codec\{VideoCodec, AudioCodec};
$media = Media::open('input.mov');
(new MediaEncoder()) ->addVideo($media->videoStream(), VideoCodec::H264) ->addAudio($media->audioStream(), AudioCodec::Copy) ->save('output.mp4');Remux only (no re-encode) into a different container
Section titled “Remux only (no re-encode) into a different container”(new MediaEncoder()) ->addVideo($media->videoStream(), VideoCodec::Copy) ->addAudio($media->audioStream(), AudioCodec::Copy) ->save('output.mkv');Audio-only extract
Section titled “Audio-only extract”(new MediaEncoder()) ->addAudio($media->audioStream(), AudioCodec::AAC) ->save('audio.m4a');Control quality and bitrate
Section titled “Control quality and bitrate”use FFmpeg\Codec\{VideoCodec, AudioCodec};
(new MediaEncoder()) // near-visually-lossless H.264, fast encode ->addVideo($media->videoStream(), VideoCodec::H264, crf: 18, preset: 'veryfast') // 128 kbps AAC ->addAudio($media->audioStream(), AudioCodec::AAC, bitrate: 128_000) ->save('output.mp4');- Output stream order is stable: video first, then audio.
- Re-encoding picks a pixel/sample format the chosen encoder accepts and resamples / rescales as needed (sws for video, swr + a sample FIFO for audio).
Copyrequires the target container to accept the source codec; otherwise re-encode.
See also
Section titled “See also”An Artisan Build project.
Built on FFmpeg — an independent binding, not affiliated with or endorsed by the FFmpeg project.
Proudly sponsored by Tighten.