This repository contains the FFmpeg Sidecar for Gotedo Impress—a high-performance media processing microservice designed to interface directly with custom-built FFmpeg dynamic libraries.
At its core is a high-performance, embedded C and FFmpeg streaming library designed for native desktop applications (e.g., Wails, Electron, CGO bridges) that need to deliver local media files to webview frontend players via Media Source Extensions (MSE) over WebSockets or HTTP streams.
To maintain compliance with the GPL/LGPL license requirements (due to the use of FFmpeg) while keeping the parent application closed-source, this sidecar runs as an isolated background process and communicates with the main application strictly over network boundaries (via gRPC or WebSockets). Consequently, this sidecar and its complete build system are fully open-source.
Gotedo Impress is a presentation software from the Gotedo Platform which enables easy multi-projector management of media presentations in churches or businesses. Media types supported by Gotedo Impress include: a wide range of video formats, a wide range of image formats, PowerPoint presentations, Document files such Microsoft Word files, PDF files, etc.
At the core of Gotedo Impress is the ability to manage media on multiple projectors or monitors independently and simultaneously. For example, you can have a Bible verse displayed on Projector A, a video playing on Projector B, and a PowerPoint slideshow live on Projector C. Gotedo Impress will give you the ability to control each media on each projector independently and simultaneously.
Gotedo Impress is free to use by individual users, churches, and businesses. You can learn more about Gotedo at https://about.gotedo.com/en/products/gotedo-impress.
Dockerfile and compiler configuration flags (builder.sh) used to build FFmpeg, fulfilling the "Corresponding Source" requirements of copyleft licenses.The engine acts as an dynamic demuxing, remuxing, and transcoding pipeline. It converts arbitrary local media containers (MKV, MP4, MOV, AVI) on the fly into fragmented MP4 (fMP4) atoms and pushes them in real-time to the frontend.
+-----------------------------------------------------------------------------------------+
| NATIVE C PIPELINE |
| |
| +------------------+ +-----------------------+ +----------------------------+ |
| | Input Media File | --> | Demuxer (libavformat) | --> | Video Passthrough / H.264 | |
| +------------------+ +-----------------------+ | Encoder (libx264) | |
| +----------------------------+ |
| | |
| v |
| +------------------+ +-----------------------+ +----------------------------+ |
| | WebSocket Bridge | <-- | 64KB AVIO Memory Buffer|<-- | fMP4 Muxer | |
| | (Go/CGO Callback)| +-----------------------+ | (empty_moov + frag_keyframe| |
| +------------------+ +----------------------------+ |
| | ^ |
| | | |
| | +-----------------------+ +----------------------------+ |
| +-------------> | Resampler (swresample)| --> | Audio Transcoder | |
| | (48kHz FLTP Stereo) | | (AAC + AVAudioFifo) | |
| +-----------------------+ +----------------------------+ |
+-----------------------------------------------------------------------------------------+
|
v (Binary WebSockets)
+-----------------------------------------------------------------------------------------+
| WEBVIEW FRONTEND (MSE) |
| |
| +--------------------+ +--------------------+ +-------------------------------+ |
| | WebSocket Receiver | -> | SourceBuffer Queue | -> | HTML5 Media Player () | |
| +--------------------+ +--------------------+ +-------------------------------+ |
+-----------------------------------------------------------------------------------------+
To minimize CPU overhead and prevent unbounded memory growth on long videos, the C pipeline incorporates a Wall-Clock Pacing Controller. It limits media delivery to a fixed 10-second read-ahead runway (READ_AHEAD_US) ahead of the client's current playback head.
Time (s)
0s 5s 10s 15s 20s 25s
---|-------------|-------------|-------------|-------------|-------------|--->
^ ^
Player Playhead Buffer Runway
(currentTime = 5s) (Max Read-Ahead = 15s)
| |
+===========================+
10-second Active Buffer
(Pipeline sleeps if > 15s)
Buffer Runway (Seconds)
12s | /---\ /---\ (Read-Ahead Ceiling: 10s)
10s |-------------------/-------X-----/-------X--------------------------------
8s | / \ / \
6s | / | \
4s | / | \ (Paced Consumption Zone)
2s | / | \
0s +---------+--------------------+----------------+-------------------------
0s 10s 20s Playback Time (s)
Legend:
/ = Demuxer/Muxer actively processing frames
X = Pacing Throttle Triggered (av_usleep pause)
\ = Frontend consuming buffer during playback
AV_CODEC_ID_H264), the engine bypasses video re-encoding completely, maintaining 0% CPU usage and zero quality loss.preset=veryfast, tune=zerolatency, profile=main) for non-H.264 formats (VP9, HEVC, AV1).AVAudioFifo ring buffer to guarantee perfect A/V synchronization.AVIOContext memory buffer that prevents atom shredding across WebSocket frames, resolving browser MEDIA_ERR_DECODE (Code 3) errors.__atomic_load_n/__atomic_store_n), preventing race conditions with av_read_frame.moov initialization headers upon seeking to safely reset browser MSE engines without reloading the player.fMP4 trailer at EOF to prevent end-of-video truncation.C-MUX, C-READ, C-SEEK, C-PROBE) with environment-based stripping (-DPRODUCTION) to separate development traces from production builds.video/mp4; codecs="avc1.4d401f, mp4a.40.2".__atomic_*) or GCC/Clang built-ins.libavformat, libavcodec, libswresample, libswscale, and libavutil (v5.0+ recommended).| Feature / Architecture | Chosen Approach | Trade-off / Alternative | Engineering Rationale |
|---|---|---|---|
| Video Processing | Hybrid Passthrough + Re-encode Fallback | Universal Full Re-encoding | Preserves battery life and zero CPU usage on H.264 files while guaranteeing playback compatibility for foreign codecs. |
| Muxing Memory Buffer | 64KB AVIOContext Buffer | 4KB Default Buffer | Eliminates MSE bitstream corruption (MEDIA_ERR_DECODE) caused by splitting video keyframes across tiny WebSocket chunks. |
| Threading Model | Single Loop with Atomic Flags | Multi-threaded Lock/Mutex | Avoids deadlock scenarios inside FFmpeg functions like av_read_frame() while maintaining sub-millisecond reaction times to user inputs. |
| Audio Resampling | Dynamic FIFO Alignment (AVAudioFifo) | Fixed Sample Pushing | Prevents sample dropping under load, which causes micro-desyncs that crash browser audio pipelines over long playback sessions. |
| Stream Termination | Mid-Stream EOF Trailer Write | Termination on EOF | Writing the trailer at EOF pushes the trailing 3–5 seconds of P/B frames before idling, preventing early video cutoffs. |
// Decoder and Pipeline Context
typedef struct DemuxDecContext {
AVFormatContext *fmt_ctx;
int video_stream_idx;
AVCodecContext *video_dec_ctx;
int audio_stream_idx;
AVCodecContext *audio_dec_ctx;
SwrContext *swr_ctx;
// Thread-safe control flags
volatile int paused;
volatile int64_t seek_target_ms;
volatile int seek_requested;
volatile int stop_requested;
volatile int eof_flushed;
} DemuxDecContext;
#include "decoder.h"
int main() {
DemuxDecContext dec_ctx = {0};
uintptr_t go_user_token = 1; // Passed to callback functions
// 1. Open media file and probe streams
if (open_input_and_decoders(&dec_ctx, "/path/to/media.mp4") < 0) {
return -1;
}
// 2. Launch the streaming pipeline (blocking execution loop)
// Runs until stop_requested is set or stream completes
run_streaming_mux_and_play(&dec_ctx, go_user_token);
// 3. Clean up context resources
free_demux_dec_context(&dec_ctx);
return 0;
}
// Pause playback
set_dec_ctx_paused(&dec_ctx, 1);
// Resume playback
set_dec_ctx_paused(&dec_ctx, 0);
// Request seek to 45.5 seconds (45500 ms)
request_seek_on_dec_ctx(&dec_ctx, 45500);
// Stop streaming loop cleanly
request_stop_on_dec_ctx(&dec_ctx);
To enable debug logs during development and strip them out for production builds, pass the compile tag via CGO_CFLAGS:
# Development Build (With detailed C-MUX / C-READ logs)
go build -tags development .
# Production Build (Debug logs stripped at compile-time)
CGO_CFLAGS="-DPRODUCTION" go build -tags production .
package main
/*
#include "decoder.h"
*/
import "C"
import (
"unsafe"
"[github.com/gorilla/websocket](https://github.com/gorilla/websocket)"
)
//export goStreamWriteCallback
func goStreamWriteCallback(buf *C.uint8_t, bufSize C.int, userToken C.uintptr_t) {
gobuf := C.GoBytes(unsafe.Pointer(buf), bufSize)
// Retrieve active WebSocket session using userToken
session := getSession(uintptr(userToken))
if session != nil && session.WS != nil {
session.WS.WriteMessage(websocket.BinaryMessage, gobuf)
}
}
// Initialize MSE Pipeline in Webview
const mediaSource = new MediaSource();
const videoElement = document.querySelector('video');
videoElement.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', () => {
const mimeCodec = 'video/mp4; codecs="avc1.4d401f, mp4a.40.2"';
const sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
sourceBuffer.mode = 'segments';
const ws = new WebSocket('ws://localhost:8080/stream');
ws.binaryType = 'arraybuffer';
const chunkQueue: ArrayBuffer[] = [];
let isAppending = false;
const processQueue = () => {
if (!sourceBuffer.updating && chunkQueue.length > 0) {
isAppending = true;
const chunk = chunkQueue.shift();
sourceBuffer.appendBuffer(chunk);
}
};
sourceBuffer.addEventListener('updateend', () => {
isAppending = false;
processQueue();
});
ws.onmessage = (event: MessageEvent) => {
chunkQueue.push(event.data as ArrayBuffer);
processQueue();
};
});
Before building, ensure your host system has the following installed:
The build system is entirely self-contained. It compiles the task runner locally so you do not have to install global build utilities on your system.
Install Go on your computer. Follow the instructions at: https://go.dev/doc/install.
Install Git on your computer. Follow the instructions at: https://git-scm.com/install.
Install Docker on your computer. Following the instructions at: https://docs.docker.com/desktop/setup/install/windows-install.
Clone this repository:
git clone https://github.com/Gotedo/gotedo-impress-ffmpeg-sidecar.git
From the root of this repository, run the following command to download and compile the task utility locally inside your workspace:
#1. Go into the directory of the downloaded repository.
cd gotedo-impress-ffmpeg-sidecar
# 2. Initialize the Go module
go mod tidy
# 3. Compile and install 'go-task' into the local repository
```bash
GOBIN="$(pwd)/bin" go install github.com/go-task/task/v3/cmd/task@latest
$env:GOBIN = "$PWD\bin"; go install github.com/go-task/task/v3/cmd/task@latest
*(This compiles the `task` executable and places it securely under `./bin/` which is ignored by Git).*
### 3. Compile FFmpeg (All Targets)
To trigger the complete cross-compilation pipeline (this will pull the toolchains, run an APT caching proxy to speed up dependencies, and build FFmpeg for Linux, macOS, and Windows):
```bash
./bin/task build:ffmpeg
By default, running the build task compiles libraries for all supported platforms: windows,linux,darwin across amd64,arm64 architectures.
You can target a specific operating system and architecture by passing environmental overrides to the task runner:
GOOS_VAR="windows" ARCH_VAR="amd64" ./bin/task build:ffmpeg
GOOS_VAR="darwin" ARCH_VAR="arm64" ./bin/task build:ffmpeg
GOOS_VAR="linux,windows" ARCH_VAR="amd64" ./bin/task build:ffmpeg
Once a build successfully finishes, compiled outputs, header files, and shared binaries are deposited into the local dist/ directory structured by platform:
dist/
├── linux/
│ ├── amd64/ # Shared .so libraries and headers
│ └── arm64/
├── darwin/
│ ├── amd64/ # Shared .dylib libraries and headers
│ └── arm64/
└── windows/
└── amd64/ # Shared .dll binaries, .lib files, and headers
The compilation environment caches heavy dependencies (like toolchains and package managers) to keep subsequent builds extremely fast. If you need to wipe these caches and force a completely clean build, run:
# Wipe the build caching structures
rm -rf build_cache/ dist/
To run integration tests for this sidecar, do:
./bin/task build IS_TEST=true
The code in this repository (the sidecar interface, wrappers, and build configurations) is open-source. The compiled binaries produced by this build system link against FFmpeg, which is licensed under the GNU Lesser General Public License (LGPL) v2.1 or the GNU General Public License (GPL) v3 depending on compilation flags used (e.g. --enable-gpl).
By keeping this sidecar repository open-source and providing full build instructions (via the local Dockerfile and Taskfile.yml), we fully satisfy our open-source compliance commitments.
102 commits
C
53.1%
Dockerfile
31.9%
Go
15.0%
This repository contains the FFmpeg Sidecar for Gotedo Impress—a high-performance media processing microservice designed to interface directly with custom-built FFmpeg dynamic libraries.
At its core is a high-performance, embedded C and FFmpeg streaming library designed for native desktop applications (e.g., Wails, Electron, CGO bridges) that need to deliver local media files to webview frontend players via Media Source Extensions (MSE) over WebSockets or HTTP streams.
To maintain compliance with the GPL/LGPL license requirements (due to the use of FFmpeg) while keeping the parent application closed-source, this sidecar runs as an isolated background process and communicates with the main application strictly over network boundaries (via gRPC or WebSockets). Consequently, this sidecar and its complete build system are fully open-source.
Gotedo Impress is a presentation software from the Gotedo Platform which enables easy multi-projector management of media presentations in churches or businesses. Media types supported by Gotedo Impress include: a wide range of video formats, a wide range of image formats, PowerPoint presentations, Document files such Microsoft Word files, PDF files, etc.
At the core of Gotedo Impress is the ability to manage media on multiple projectors or monitors independently and simultaneously. For example, you can have a Bible verse displayed on Projector A, a video playing on Projector B, and a PowerPoint slideshow live on Projector C. Gotedo Impress will give you the ability to control each media on each projector independently and simultaneously.
Gotedo Impress is free to use by individual users, churches, and businesses. You can learn more about Gotedo at https://about.gotedo.com/en/products/gotedo-impress.
Dockerfile and compiler configuration flags (builder.sh) used to build FFmpeg, fulfilling the "Corresponding Source" requirements of copyleft licenses.The engine acts as an dynamic demuxing, remuxing, and transcoding pipeline. It converts arbitrary local media containers (MKV, MP4, MOV, AVI) on the fly into fragmented MP4 (fMP4) atoms and pushes them in real-time to the frontend.
+-----------------------------------------------------------------------------------------+
| NATIVE C PIPELINE |
| |
| +------------------+ +-----------------------+ +----------------------------+ |
| | Input Media File | --> | Demuxer (libavformat) | --> | Video Passthrough / H.264 | |
| +------------------+ +-----------------------+ | Encoder (libx264) | |
| +----------------------------+ |
| | |
| v |
| +------------------+ +-----------------------+ +----------------------------+ |
| | WebSocket Bridge | <-- | 64KB AVIO Memory Buffer|<-- | fMP4 Muxer | |
| | (Go/CGO Callback)| +-----------------------+ | (empty_moov + frag_keyframe| |
| +------------------+ +----------------------------+ |
| | ^ |
| | | |
| | +-----------------------+ +----------------------------+ |
| +-------------> | Resampler (swresample)| --> | Audio Transcoder | |
| | (48kHz FLTP Stereo) | | (AAC + AVAudioFifo) | |
| +-----------------------+ +----------------------------+ |
+-----------------------------------------------------------------------------------------+
|
v (Binary WebSockets)
+-----------------------------------------------------------------------------------------+
| WEBVIEW FRONTEND (MSE) |
| |
| +--------------------+ +--------------------+ +-------------------------------+ |
| | WebSocket Receiver | -> | SourceBuffer Queue | -> | HTML5 Media Player () | |
| +--------------------+ +--------------------+ +-------------------------------+ |
+-----------------------------------------------------------------------------------------+
To minimize CPU overhead and prevent unbounded memory growth on long videos, the C pipeline incorporates a Wall-Clock Pacing Controller. It limits media delivery to a fixed 10-second read-ahead runway (READ_AHEAD_US) ahead of the client's current playback head.
Time (s)
0s 5s 10s 15s 20s 25s
---|-------------|-------------|-------------|-------------|-------------|--->
^ ^
Player Playhead Buffer Runway
(currentTime = 5s) (Max Read-Ahead = 15s)
| |
+===========================+
10-second Active Buffer
(Pipeline sleeps if > 15s)
Buffer Runway (Seconds)
12s | /---\ /---\ (Read-Ahead Ceiling: 10s)
10s |-------------------/-------X-----/-------X--------------------------------
8s | / \ / \
6s | / | \
4s | / | \ (Paced Consumption Zone)
2s | / | \
0s +---------+--------------------+----------------+-------------------------
0s 10s 20s Playback Time (s)
Legend:
/ = Demuxer/Muxer actively processing frames
X = Pacing Throttle Triggered (av_usleep pause)
\ = Frontend consuming buffer during playback
AV_CODEC_ID_H264), the engine bypasses video re-encoding completely, maintaining 0% CPU usage and zero quality loss.preset=veryfast, tune=zerolatency, profile=main) for non-H.264 formats (VP9, HEVC, AV1).AVAudioFifo ring buffer to guarantee perfect A/V synchronization.AVIOContext memory buffer that prevents atom shredding across WebSocket frames, resolving browser MEDIA_ERR_DECODE (Code 3) errors.__atomic_load_n/__atomic_store_n), preventing race conditions with av_read_frame.moov initialization headers upon seeking to safely reset browser MSE engines without reloading the player.fMP4 trailer at EOF to prevent end-of-video truncation.C-MUX, C-READ, C-SEEK, C-PROBE) with environment-based stripping (-DPRODUCTION) to separate development traces from production builds.video/mp4; codecs="avc1.4d401f, mp4a.40.2".__atomic_*) or GCC/Clang built-ins.libavformat, libavcodec, libswresample, libswscale, and libavutil (v5.0+ recommended).| Feature / Architecture | Chosen Approach | Trade-off / Alternative | Engineering Rationale |
|---|---|---|---|
| Video Processing | Hybrid Passthrough + Re-encode Fallback | Universal Full Re-encoding | Preserves battery life and zero CPU usage on H.264 files while guaranteeing playback compatibility for foreign codecs. |
| Muxing Memory Buffer | 64KB AVIOContext Buffer | 4KB Default Buffer | Eliminates MSE bitstream corruption (MEDIA_ERR_DECODE) caused by splitting video keyframes across tiny WebSocket chunks. |
| Threading Model | Single Loop with Atomic Flags | Multi-threaded Lock/Mutex | Avoids deadlock scenarios inside FFmpeg functions like av_read_frame() while maintaining sub-millisecond reaction times to user inputs. |
| Audio Resampling | Dynamic FIFO Alignment (AVAudioFifo) | Fixed Sample Pushing | Prevents sample dropping under load, which causes micro-desyncs that crash browser audio pipelines over long playback sessions. |
| Stream Termination | Mid-Stream EOF Trailer Write | Termination on EOF | Writing the trailer at EOF pushes the trailing 3–5 seconds of P/B frames before idling, preventing early video cutoffs. |
// Decoder and Pipeline Context
typedef struct DemuxDecContext {
AVFormatContext *fmt_ctx;
int video_stream_idx;
AVCodecContext *video_dec_ctx;
int audio_stream_idx;
AVCodecContext *audio_dec_ctx;
SwrContext *swr_ctx;
// Thread-safe control flags
volatile int paused;
volatile int64_t seek_target_ms;
volatile int seek_requested;
volatile int stop_requested;
volatile int eof_flushed;
} DemuxDecContext;
#include "decoder.h"
int main() {
DemuxDecContext dec_ctx = {0};
uintptr_t go_user_token = 1; // Passed to callback functions
// 1. Open media file and probe streams
if (open_input_and_decoders(&dec_ctx, "/path/to/media.mp4") < 0) {
return -1;
}
// 2. Launch the streaming pipeline (blocking execution loop)
// Runs until stop_requested is set or stream completes
run_streaming_mux_and_play(&dec_ctx, go_user_token);
// 3. Clean up context resources
free_demux_dec_context(&dec_ctx);
return 0;
}
// Pause playback
set_dec_ctx_paused(&dec_ctx, 1);
// Resume playback
set_dec_ctx_paused(&dec_ctx, 0);
// Request seek to 45.5 seconds (45500 ms)
request_seek_on_dec_ctx(&dec_ctx, 45500);
// Stop streaming loop cleanly
request_stop_on_dec_ctx(&dec_ctx);
To enable debug logs during development and strip them out for production builds, pass the compile tag via CGO_CFLAGS:
# Development Build (With detailed C-MUX / C-READ logs)
go build -tags development .
# Production Build (Debug logs stripped at compile-time)
CGO_CFLAGS="-DPRODUCTION" go build -tags production .
package main
/*
#include "decoder.h"
*/
import "C"
import (
"unsafe"
"[github.com/gorilla/websocket](https://github.com/gorilla/websocket)"
)
//export goStreamWriteCallback
func goStreamWriteCallback(buf *C.uint8_t, bufSize C.int, userToken C.uintptr_t) {
gobuf := C.GoBytes(unsafe.Pointer(buf), bufSize)
// Retrieve active WebSocket session using userToken
session := getSession(uintptr(userToken))
if session != nil && session.WS != nil {
session.WS.WriteMessage(websocket.BinaryMessage, gobuf)
}
}
// Initialize MSE Pipeline in Webview
const mediaSource = new MediaSource();
const videoElement = document.querySelector('video');
videoElement.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', () => {
const mimeCodec = 'video/mp4; codecs="avc1.4d401f, mp4a.40.2"';
const sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
sourceBuffer.mode = 'segments';
const ws = new WebSocket('ws://localhost:8080/stream');
ws.binaryType = 'arraybuffer';
const chunkQueue: ArrayBuffer[] = [];
let isAppending = false;
const processQueue = () => {
if (!sourceBuffer.updating && chunkQueue.length > 0) {
isAppending = true;
const chunk = chunkQueue.shift();
sourceBuffer.appendBuffer(chunk);
}
};
sourceBuffer.addEventListener('updateend', () => {
isAppending = false;
processQueue();
});
ws.onmessage = (event: MessageEvent) => {
chunkQueue.push(event.data as ArrayBuffer);
processQueue();
};
});
Before building, ensure your host system has the following installed:
The build system is entirely self-contained. It compiles the task runner locally so you do not have to install global build utilities on your system.
Install Go on your computer. Follow the instructions at: https://go.dev/doc/install.
Install Git on your computer. Follow the instructions at: https://git-scm.com/install.
Install Docker on your computer. Following the instructions at: https://docs.docker.com/desktop/setup/install/windows-install.
Clone this repository:
git clone https://github.com/Gotedo/gotedo-impress-ffmpeg-sidecar.git
From the root of this repository, run the following command to download and compile the task utility locally inside your workspace:
#1. Go into the directory of the downloaded repository.
cd gotedo-impress-ffmpeg-sidecar
# 2. Initialize the Go module
go mod tidy
# 3. Compile and install 'go-task' into the local repository
```bash
GOBIN="$(pwd)/bin" go install github.com/go-task/task/v3/cmd/task@latest
$env:GOBIN = "$PWD\bin"; go install github.com/go-task/task/v3/cmd/task@latest
*(This compiles the `task` executable and places it securely under `./bin/` which is ignored by Git).*
### 3. Compile FFmpeg (All Targets)
To trigger the complete cross-compilation pipeline (this will pull the toolchains, run an APT caching proxy to speed up dependencies, and build FFmpeg for Linux, macOS, and Windows):
```bash
./bin/task build:ffmpeg
By default, running the build task compiles libraries for all supported platforms: windows,linux,darwin across amd64,arm64 architectures.
You can target a specific operating system and architecture by passing environmental overrides to the task runner:
GOOS_VAR="windows" ARCH_VAR="amd64" ./bin/task build:ffmpeg
GOOS_VAR="darwin" ARCH_VAR="arm64" ./bin/task build:ffmpeg
GOOS_VAR="linux,windows" ARCH_VAR="amd64" ./bin/task build:ffmpeg
Once a build successfully finishes, compiled outputs, header files, and shared binaries are deposited into the local dist/ directory structured by platform:
dist/
├── linux/
│ ├── amd64/ # Shared .so libraries and headers
│ └── arm64/
├── darwin/
│ ├── amd64/ # Shared .dylib libraries and headers
│ └── arm64/
└── windows/
└── amd64/ # Shared .dll binaries, .lib files, and headers
The compilation environment caches heavy dependencies (like toolchains and package managers) to keep subsequent builds extremely fast. If you need to wipe these caches and force a completely clean build, run:
# Wipe the build caching structures
rm -rf build_cache/ dist/
To run integration tests for this sidecar, do:
./bin/task build IS_TEST=true
The code in this repository (the sidecar interface, wrappers, and build configurations) is open-source. The compiled binaries produced by this build system link against FFmpeg, which is licensed under the GNU Lesser General Public License (LGPL) v2.1 or the GNU General Public License (GPL) v3 depending on compilation flags used (e.g. --enable-gpl).
By keeping this sidecar repository open-source and providing full build instructions (via the local Dockerfile and Taskfile.yml), we fully satisfy our open-source compliance commitments.
102 commits
C
53.1%
Dockerfile
31.9%
Go
15.0%