astiav
is a Golang library providing C bindings for ffmpeg
It's only compatible with ffmpeg
n7.0
.
Its main goals are to:
- provide a better GO idiomatic API
- standard error pattern
- typed constants and flags
- struct-based functions
- ...
- provide the GO version of ffmpeg examples
- be fully tested
go-astiav
without using the v2
golang pattern. You can see the list of breaking changes here.
Examples are located in the examples directory and mirror as much as possible the ffmpeg examples.
name | astiav | ffmpeg |
---|---|---|
BitStream Filtering | see | X |
Custom IO Demuxing | see | see |
Custom IO Muxing | see | X |
Demuxing/Decoding | see | see |
Filtering | see | see |
Frame data manipulation | see | X |
Hardware Decoding/Filtering | see | see |
Hardware Encoding | see | see |
Remuxing | see | see |
Resampling audio | see | see |
Scaling video | see | see |
Transcoding | see | see |
Tip: you can use the video sample located in the testdata
directory for your tests
NB: errors are not checked below for readibility purposes, however you should!
First off, all use cases are different and it's impossible to provide patterns that work in every situation. That's why ffmpeg
's doc or source code should be your ultimate source of truth regarding how to use this library. That's why all methods of this library have been documented with a link referencing the documentation of the C function they use.
However it's possible to give rules of thumb and patterns that fit most use cases and can kickstart most people. Here's a few of them:
Let's take the FormatContext.ReadFrame()
pattern as an example. The pattern is similar with frames.
// You can allocate the packet once and reuse the same object in the for loop below
pkt := astiav.AllocPacket()
// However, once you're done using the packet, you need to make sure to free it
defer pkt.Free()
// Loop
for {
// We'll use a closure to ease unreferencing the packet
func() {
// Read frame using the same packet every time
formatContext.ReadFrame(pkt)
// However make sure to unreference the packet once you're done with what
// have been "injected" by the .ReadFrame() method
defer pkt.Unref()
// Here you can do whatever you feel like with your packet
}()
}
If you don't know how to install ffmpeg
, you can use the following to install it from source:
$ make install-ffmpeg
ffmpeg
will be built from source in a directory named tmp
and located in you working directory
For your GO code to pick up ffmpeg
dependency automatically, you'll need to add the following environment variables:
(don't forget to replace {{ path to your working directory }}
with the absolute path to your working directory)
export CGO_LDFLAGS="-L{{ path to your working directory }}/tmp/n7.0/lib/",
export CGO_CFLAGS="-I{{ path to your working directory }}/tmp/n7.0/include/",
export PKG_CONFIG_PATH="{{ path to your working directory }}/tmp/n7.0/lib/pkgconfig",
Building on Windows requires msys2 / mingw64 gcc toolchain. Read the Quickstart guide to install Msys2.
Once complete run the Mingw64 shell from the installation folder, run the below commands:
# Update Packages
pacman -Syu
# Install Requirements to Build
pacman -S --noconfirm --needed git diffutils mingw-w64-x86_64-toolchain pkg-config make yasm
# Clone the repository using git
git clone https://github.com/asticode/go-astiav
cd go-astiav
Then once you clone this repository, follow along the build instructions above.
Notes: For
pkg-config
usepkgconfiglite
from choco. Remember to setCGO
andPKG_CONFIG
env vars properly to point to the folder where ffmpeg was built.
After maintaining for several years the most starred fork of goav, I've decided to write from scratch my own C bindings to fix most of the problems I still encountered using goav
.