A .NET Standard 2.0 library that assembles encoded video and raw audio into an MP4. FFmpeg copies the video without recompressing it and encodes audio as MP3 or AAC.
Used by UnityRuntimeCameraRecorder for audio/video muxing and MP4 finalization. The DLL itself does not depend on Unity or a GPU vendor.
Windows, Linux or macOS with a compatible .NET runtime. Linux/macOS execution has not yet been tested.
Install FFmpeg separately. Its build must support H.264/HEVC input, MKV/MP4 output and the selected MP3 or AAC audio encoder.
Download FFmpeg from the official download page, extract or install it, and supply its bin directory in MediaWriterSettings.FfmpegPath. The directory must contain ffmpeg.exe on Windows or ffmpeg on Linux and macOS. Keep FFprobe, required companion libraries and license files in the same directory.
Start a writer with output paths, video format, FPS ceiling and audio sample rate/channel count. Send complete encoded video packets with monotonic timestamps in microseconds, and interleaved float32 PCM audio.
Feed video first. Check write results: false means data was rejected. Stop producers before calling FinishCapture(), then poll IsFinalizationCompleted before calling CompleteFinalization() and Dispose().
During capture, FFmpeg writes a video-only intermediate MKV while a separate
writer saves float32 PCM audio to a sidecar file. Finalization combines both
files into the MP4. The intermediate MKV and audio sidecar are deleted after
success and retained on failure for recovery.
Rejected audio blocks are replaced by silence at the same position. If their
cumulative duration exceeds two seconds, CaptureFailure reports an error and
the Unity recorder stops capture. The temporary files remain available for
recovery.
For Unity camera and audio capture, use UnityRuntimeCameraRecorder.
With the .NET 10 SDK, run dotnet build FFmpegMediaWriter.csproj -c Release.
Output: bin/Release/netstandard2.0/FFmpegMediaWriter.dll.
Our code uses MIT. FFmpeg's license and codec patent rights are separate.
Media Recorder supplies these settings; FFmpegMediaWriter encodes the final audio using FFmpeg's native aac encoder.
| Setting | Low | Medium | High | Highest |
|---|---|---|---|---|
| Codec | AAC | AAC | AAC | AAC |
| Target bitrate | 96 kbit/s | 128 kbit/s | 192 kbit/s | 192 kbit/s |
| Sample rate / channels | 48000 Hz / stereo | Same | Same | Same |
Capture accepts interleaved float32 PCM at the Unity input format and saves it independently of FFmpeg's video capture process. Finalization resamples or mixes the sidecar audio and encodes AAC. Video is copied without re-encoding. The measured audio bitrate may differ from its target.
API: AudioCodec, AudioBitRate (bits/s), OutputAudioSampleRate, OutputAudioChannels. Zero output rate/channels retain the input format. Standalone writer defaults remain MP3 192000 bit/s; the table describes Media Recorder profiles. The FFmpeg executable must include aac.
Source: FFmpeg AAC encoder documentation. The quality-to-bitrate mapping is our profile policy, not an FFmpeg preset. HDR video is not supported today by the Media Recorder pipeline; AAC has no HDR setting.
For encoders with B-frames, set EncodedVideoHasPresentationTimestamps = true and pass each access unit with its source monotonic presentation timestamp. The writer adds MPEG-TS PTS/DTS headers (H.264 or HEVC) without changing the elementary payload, allowing FFmpeg to remux decode-order packets correctly. This mode assumes a fixed requested frame cadence with at most 2 B-frames; DTS advances at that cadence and PTS preserves captured presentation gaps. The default remains the legacy raw elementary stream/wall-clock path for existing consumers. Final audio is encoded independently.