astiencoder
is an open source video encoder written in GO and based on ffmpeg C bindings.
Right now this project has only been tested on FFMpeg 4.0.2.
In most cases you won't need this project as the ffmpeg
binary is pretty awesome.
However, this project could be useful to you if you're looking to:
- understand how the video encoding process work
- integrate your video encoder in a GO ecosystem
- visualize your encoding workflow and statuses/stats of nodes in real time
- communicate with the encoder through an HTTP API + websocket to tweak behaviours in real time
- use native GO subtitle libraries like astisub
- build your own video encoder and take control of its workflow
At the root of the project, package astiencoder
provides the framework to build an Encoder.
When provided with a WorkflowBuilder
, it can build Workflows based on Jobs.
At this point, Workflows are made of Nodes that can start/pause/continue/stop any kind of work.
The Encoder has a built-in Server that serves both an HTTP API and WebSocket events to interact with Workflows and Nodes.
All internal Events can be handled with the proper EventHandler
.
In folder libav
, package astilibav
provides the proper nodes to use the ffmpeg
C bindings with the encoder:
At this point the way you connect those nodes is up to you since they implement 2 main interfaces:
type PktHandler interface {
HandlePkt(pkt *avcodec.Packet)
}
type FrameHandler interface {
HandleFrame(f *avutil.Frame)
}
In folder astiencoder
, package main
provides an out-of-the-box encoder using both packages astiencoder
and astilibav
.
It's a good place to start digging if you're looking to implement your own WorkflowBuilder
.
In order to use the ffmpeg
C bindings, you need to install ffmpeg. To do so, run the following command:
$ make install-ffmpeg
In some cases, you'll need to enable/disable libs explicitly. To do so, use the configure
placeholder. For instance this will install the libx264
as well:
$ make install-ffmpeg configure="--enable-libx264 --enable-gpl"
Simply run the following command:
$ go get github.com/asticode/go-astiencoder/...
Simply run the following command:
$ make version
It should print something like:
avcodec: 3805796
avdevice: 3801956
avfilter: 462948
avutil: 3673700
resample: GPL version 2 or later
swscale: 328036
The out-of-the-box encoder has 2 modes:
- by default it will spawn the server and wait for a new workflow to be added manually
- when provided with the
-j
flag, it will open the provided json-formatted job, transform it into a workflow, execute it and exit once everything is done
To run the default mode, simply run the following command:
$ make server
Whatever mode you're in, you can open the Web UI in order to either interact with your workflows or see their stats.
By default it's accessible at http://127.0.0.1:4000 but you can change it using the encoder configuration.
Click on the +
icon on the top right of the screen:
Provide a name and the .json
file containing your job:
Nice, you have added a new workflow!
On the left-hand side, you'll see the names of all the workflows you've added. Click once the slider on the right of its name to start the workflow:
Click a second time to pause it:
You can also start/pause/continue nodes individually by clicking on them:
Nodes use the same stats:
- Incoming rate: the number of incoming object received per second. This is either packets per second (
pps
) or frames per second (fps
). - Listen ratio: the percentage of time spent waiting for a new incoming object
- Dispatch ratio: the percentage of time spent waiting for all children to be available to process the output object.
- Work ratio: the percentage of time spent doing some actual work
That way you can monitor the efficiency of your workflow and see which node needs work.
Examples are located in the examples
folder and consists of json-formatted jobs.
If you want to run a specific example, run the following command:
$ make example=<name of the example>
File outputs will be written in the examples/tmp
folder.
WARNING: for the following examples you will need specific ffmpeg libs enabled. Again, in order to do so, use the configure
placeholder as mentioned here:
- encode:
--enable-libx264 --enable-gpl
If you're using the Encoder, you'll need to use the WorkflowBuilder
interface:
type WorkflowBuilder interface {
BuildWorkflow(j Job, w *Workflow) error
}
Otherwise, I'd recommend to get inspiration from the out-of-the-box encoder's workflow builder.
Right now this project is using these bindings.
Here's why:
- the base project is not maintained anymore
- this project is a hard fork of #1 but has gone a very different route
- this project is a fork of #1 but I'm experiencing lots of panics
- this project is the best fork of #1 even though the last commit is not recent
- this project is a fork of #4 with interesting additional commits
- this project is a fork of #4 with interesting additional commits
- this project has a very nice set of examples
Therefore I've forked #4, added useful commits from other forks and removed deprecated functions so that it works properly in FFMpeg 4.0.2.
If you're using make
, you're not supposed to add CGO flags manually, it will do it for you.
Otherwise you need to provide the proper CGO_CFLAGS
, CGO_LDFLAGS
and PKG_CONFIG_PATH
environment variables when running your GO code.
Let say the absolute path to your current dir is /path/to
, here are their respective values:
CGO_CFLAGS
: -I/path/to/vendor_c/includeCGO_LDFLAGS
: -L/path/to/vendor_c/libPKG_CONFIG_PATH
: /path/to/vendor_c/lib/pkgconfig
- copy (remux)
- mjpeg (thumbnails)
- basic encode (h264 + aac)
- stats
- web ui
- proper tests
- audio resampling
- packaging (dash + hls + smooth)
- add plugin in snickers
- many others :D
Contributions are more than welcome! Simply fork this project, make changes in a specific branch such as patch-1
for instance and submit a PR.