The Missing Piece in Go Media Processing
Most Go media libraries eventually run into the same problem.
The Missing Piece in Go Media Processing

Most Go media libraries eventually run into the same problem.
They don’t actually ship with a decoder.
Instead, they depend on a system-installed FFmpeg package, shared libraries, platform-specific DLLs, or external binaries that must exist on the target machine.
Everything works during development. Then deployment begins.
Suddenly you’re debugging missing DLLs on Windows, mismatched FFmpeg versions on Linux, Homebrew differences on macOS, container images that don’t contain the required libraries, or production machines where upgrading a package unexpectedly breaks media processing.
So there is a real need in something different.
The Goal
I wanted a decoder that:
- Works from pure Go code
- Produces a single distributable binary
- Requires no FFmpeg installation
- Requires no runtime shared libraries
- Supports modern codecs such as AV1, H.264, H.265, VP8, VP9, Opus, AAC, MP3, and others
- Can read from files, memory buffers, HTTP streams, pipes, SSH streams, and any Go reader
The result is **gopeg**.
Instead of relying on whatever media stack happens to be installed on a machine, the required FFmpeg components and dav1d decoder are statically linked into the application during build time.
When the binary is produced, everything needed for decoding is already inside it.
Why This Matters
A surprising amount of engineering time is spent solving deployment problems rather than application problems.
A typical workflow often looks like this:
- Install FFmpeg
- Install matching shared libraries
- Package them correctly
- Ensure production machines have compatible versions
- Hope future operating system updates don’t break anything
The application becomes dependent on external state.
With static linking, the deployment story becomes much simpler.
go build
Ship the binary. And that’s it.
No external codec packages. No DLL distribution. No runtime library discovery. No “works on my machine.”
Streaming Support
Another design goal was flexibility.
The decoder does not need direct file access.
It can operate on arbitrary streams:
resp, _ := http.Get(url)
dec, err := gopeg.NewDecoder(resp.Body)
Or:
dec, err := gopeg.NewDecoder(os.Stdin)
Or even data arriving through an SSH connection or custom transport.
For seekable sources, additional metadata such as duration can be extracted more accurately.
For non-seekable streams, decoding still works normally and media can be processed as data arrives.
Modern Codec Support
The decoder currently supports common video and audio formats through FFmpeg and dav1d integration.
Examples include:
- AV1
- H.264
- H.265 / HEVC
- VP8
- VP9
- AAC
- Opus
- MP3
- FLAC
For AV1 specifically, dav1d is used because it remains one of the fastest and most widely respected AV1 software decoders available.
Simplicity Over Abstraction
One thing I wanted to avoid was building an enormous framework.
The API is intentionally straightforward.
Open a source:
dec, err := gopeg.NewDecoder(file)
Read metadata:
meta := dec.Meta()
Decode frames:
for {
frame, err := dec.DecodeFrame()
if err != nil {
panic(err)
}
if frame == nil {
break
}
// process frame
}
No background workers. No hidden processes. No external binaries. Just decoding.
Final Thoughts
FFmpeg is an incredible piece of software, but depending on a system FFmpeg installation creates operational complexity that many applications don’t actually need.
For my use cases, a statically linked approach made more sense.
The result is a media decoder that is easy to embed, easy to deploy, and predictable across environments.
Build once.
Ship one binary.
Decode media anywhere.
If that sounds useful, check out the gopeg project and let me know what formats or features you’d like to see next.
메타데이터
- post_id
- bc1908875a7c
- slug
- how-i-built-a-runtime-dependency-free-video-decoding-library-in-go-bc1908875a7c
- url
- https://medium.com/@d1nch8g_91775/how-i-built-a-runtime-dependency-free-video-decoding-library-in-go-bc1908875a7c
- canonical_url
- https://medium.com/@d1nch8g_91775/how-i-built-a-runtime-dependency-free-video-decoding-library-in-go-bc1908875a7c
- author_url
- https://medium.com/@d1nch8g_91775
- status
- ok
- fetched_at
- 2026-06-09 15:37:30