Predictable, Production-Ready Adaptive Bitrate (ABR) Video Packaging for Go (HLS & DASH CMAF)
23
stars
46
commits
Go
primary language
Aug 31, 2026
updated
Predictable, Production-Ready Adaptive Bitrate (ABR) Video Packaging for Go
mosaic is a robust Go library for adaptive bitrate video packaging. It probes input media with FFprobe, computes an aspect-preserving ABR ladder, applies bitrate optimizations, and generates standardized HLS (fMP4) and DASH CMAF streams using FFmpeg.
📖 Full Online Documentation & Guides: https://farshidrezaei.github.io/mosaic/
Designed for server-side encoding workloads, background workers, and transcoding pipelines where predictability, clean abstractions, and zero external dependencies are critical.
master.m3u8, variant playlists, fMP4 segments) and DASH (manifest.mpd, init.m4s, chunk.m4s) streams.90°, 180°, 270°), physically transposes frames when needed, and resets output metadata so mobile videos display correctly everywhere.0.0% to 100.0%), encoded time, current bitrate, and speed.filter_complex graphs (split -> scale -> setsar=1) for optimal 1-pass encoding performance and SAR consistency.1.25+4.4+ (with libx264 and aac support)go get github.com/farshidrezaei/mosaic
# Install directly via Go
go install github.com/farshidrezaei/mosaic/cmd/mosaic@latest
# Or run via Docker (FFmpeg pre-installed)
docker run --rm -v $(pwd):/workspace ghcr.io/farshidrezaei/mosaic -i input.mp4 -o ./output/hls
# Package local or remote video into HLS fMP4 with mobile orientation normalization
mosaic -i video.mp4 -o ./output/hls
# Package into DASH CMAF with 4 CPU threads and NVENC GPU acceleration
mosaic -i video.mp4 -o ./output/dash -f dash --threads 4 --gpu nvenc
package main
import (
"context"
"fmt"
"log"
"github.com/farshidrezaei/mosaic"
)
func main() {
job := mosaic.Job{
Input: "input.mp4",
OutputDir: "./output/hls",
Profile: mosaic.ProfileVOD,
ProgressHandler: func(info mosaic.ProgressInfo) {
fmt.Printf("\r[%5.1f%%] time=%s bitrate=%s speed=%s",
info.Percentage, info.CurrentTime, info.Bitrate, info.Speed)
},
}
usage, err := mosaic.EncodeHls(
context.Background(),
job,
mosaic.WithNormalizeOrientation(), // Handles mobile/rotated video
mosaic.WithThreads(4),
)
if err != nil {
log.Fatalf("Encoding failed: %v", err)
}
fmt.Printf("\nDone! CPU User Time: %.2fs | Peak RSS: %d KB\n", usage.UserTime, usage.MaxMemory)
}
package main
import (
"context"
"fmt"
"log"
"github.com/farshidrezaei/mosaic"
)
func main() {
job := mosaic.Job{
Input: "input.mp4",
OutputDir: "./output/dash",
Profile: mosaic.ProfileVOD,
ProgressHandler: func(info mosaic.ProgressInfo) {
fmt.Printf("\r[%5.1f%%] time=%s bitrate=%s speed=%s",
info.Percentage, info.CurrentTime, info.Bitrate, info.Speed)
},
}
_, err := mosaic.EncodeDash(
context.Background(),
job,
mosaic.WithNormalizeOrientation(),
mosaic.WithBFrames(2),
mosaic.WithScaleBitrateWithFPS(),
)
if err != nil {
log.Fatalf("DASH encoding failed: %v", err)
}
fmt.Println("\nDASH packaging complete -> ./output/dash/manifest.mpd")
}
Input Media ──► probe ──► ladder ──► optimize ──► encoder ──► FFmpeg (CMAF)
probe.Input extracts video dimensions, framerate, duration, audio presence, and rotation metadata.ladder.Build constructs a ladder preserving the original display aspect ratio.optimize.Apply caps bitrates based on resolution/FPS and trims redundant, closely-spaced renditions.Mosaic provides composable functional options to tailor the encoding process:
| Option | Description |
|---|---|
mosaic.WithNormalizeOrientation(bool...) | Probes rotation metadata, transposes video if rotated, and clears output rotation tags. |
mosaic.WithThreads(n) | Sets CPU encoding thread count (0 = FFmpeg auto-detection). |
mosaic.WithBFrames(n) | Sets number of B-frames for non-baseline profiles (default 0). |
mosaic.WithScaleBitrateWithFPS(bool...) | Proportionally scales bitrate caps for high-framerate videos (>30 FPS). |
mosaic.WithNVENC() | Uses NVIDIA hardware encoding (h264_nvenc). |
mosaic.WithVAAPI() | Uses Intel/AMD hardware encoding (h264_vaapi). |
mosaic.WithVideoToolbox() | Uses Apple VideoToolbox hardware encoding (h264_videotoolbox). |
mosaic.WithGPU(config.GPUType) | Selects a specific GPU backend explicitly. |
mosaic.WithLogLevel(level) | Sets FFmpeg log level (quiet, error, warning, info, debug). |
mosaic.WithLogger(logger) | Sets a custom *slog.Logger for internal library logs. |
Unlike legacy pipelines that letterbox non-16:9 videos into fixed frames, Mosaic calculates each rendition's width dynamically based on display dimensions:
| Input Resolution | Aspect Ratio | Generated Renditions |
|---|---|---|
1920x1080 | 16:9 Landscape | 1920x1080 (5000k), 1280x720 (3000k), 640x360 (1000k) |
1080x1080 | 1:1 Square | 1080x1080 (5000k), 720x720 (3000k), 360x360 (1000k) |
1080x1920 | 9:16 Portrait | 608x1080 (5000k), 404x720 (3000k), 202x360 (1000k) |
1280x718 | Custom Landscape | 642x360 (1000k) |
426x240 | Low Resolution | 426x240 (1000k) (no upscaling) |
The ProgressHandler receives parsed FFmpeg progress information on every tick:
type ProgressInfo struct {
Percentage float64 // Exact percentage (0.0% to 100.0%)
CurrentTime string // Encoded timestamp (e.g., "00:01:23.456000")
Bitrate string // Current encoding bitrate (e.g., "2450.3kbits/s")
Speed string // Encoding speed factor (e.g., "1.85x")
}
Complete, runnable examples are available in the examples/ directory:
examples/simple_hls: Standard HLS VOD packaging with progress reporting.examples/advanced_dash: DASH CMAF with B-Frames, FPS scaling, and custom thread control.examples/live_streaming: Low-latency live streaming profile (2s segments) for HLS & DASH.examples/orientation_normalization: Standalone and pipeline rotation normalization for mobile videos.examples/progress_monitoring: Terminal progress bar with percentage, speed, bitrate, and resource usage.examples/multi_gpu: Multi-backend GPU hardware acceleration (NVENC / VAAPI / VideoToolbox).Mosaic is tested with a 100% dependency-injected architecture, enforcing strict code hygiene and race detection:
# Run all tests with race detector
GOCACHE=/tmp/go-build go test -v -race ./...
# Static analysis
GOCACHE=/tmp/go-build go vet ./...
# Linter (Mandatory - zero issues policy)
golangci-lint run
Contributions are very welcome! Whether you are fixing a bug, adding new encoder profiles, or improving documentation:
CONTRIBUTING.md for development rules and contracts.MIT License. See LICENSE for details.
46 commits
Go
99.7%
Predictable, Production-Ready Adaptive Bitrate (ABR) Video Packaging for Go (HLS & DASH CMAF)
23
stars
46
commits
Go
primary language
Aug 31, 2026
updated
Predictable, Production-Ready Adaptive Bitrate (ABR) Video Packaging for Go
mosaic is a robust Go library for adaptive bitrate video packaging. It probes input media with FFprobe, computes an aspect-preserving ABR ladder, applies bitrate optimizations, and generates standardized HLS (fMP4) and DASH CMAF streams using FFmpeg.
📖 Full Online Documentation & Guides: https://farshidrezaei.github.io/mosaic/
Designed for server-side encoding workloads, background workers, and transcoding pipelines where predictability, clean abstractions, and zero external dependencies are critical.
master.m3u8, variant playlists, fMP4 segments) and DASH (manifest.mpd, init.m4s, chunk.m4s) streams.90°, 180°, 270°), physically transposes frames when needed, and resets output metadata so mobile videos display correctly everywhere.0.0% to 100.0%), encoded time, current bitrate, and speed.filter_complex graphs (split -> scale -> setsar=1) for optimal 1-pass encoding performance and SAR consistency.1.25+4.4+ (with libx264 and aac support)go get github.com/farshidrezaei/mosaic
# Install directly via Go
go install github.com/farshidrezaei/mosaic/cmd/mosaic@latest
# Or run via Docker (FFmpeg pre-installed)
docker run --rm -v $(pwd):/workspace ghcr.io/farshidrezaei/mosaic -i input.mp4 -o ./output/hls
# Package local or remote video into HLS fMP4 with mobile orientation normalization
mosaic -i video.mp4 -o ./output/hls
# Package into DASH CMAF with 4 CPU threads and NVENC GPU acceleration
mosaic -i video.mp4 -o ./output/dash -f dash --threads 4 --gpu nvenc
package main
import (
"context"
"fmt"
"log"
"github.com/farshidrezaei/mosaic"
)
func main() {
job := mosaic.Job{
Input: "input.mp4",
OutputDir: "./output/hls",
Profile: mosaic.ProfileVOD,
ProgressHandler: func(info mosaic.ProgressInfo) {
fmt.Printf("\r[%5.1f%%] time=%s bitrate=%s speed=%s",
info.Percentage, info.CurrentTime, info.Bitrate, info.Speed)
},
}
usage, err := mosaic.EncodeHls(
context.Background(),
job,
mosaic.WithNormalizeOrientation(), // Handles mobile/rotated video
mosaic.WithThreads(4),
)
if err != nil {
log.Fatalf("Encoding failed: %v", err)
}
fmt.Printf("\nDone! CPU User Time: %.2fs | Peak RSS: %d KB\n", usage.UserTime, usage.MaxMemory)
}
package main
import (
"context"
"fmt"
"log"
"github.com/farshidrezaei/mosaic"
)
func main() {
job := mosaic.Job{
Input: "input.mp4",
OutputDir: "./output/dash",
Profile: mosaic.ProfileVOD,
ProgressHandler: func(info mosaic.ProgressInfo) {
fmt.Printf("\r[%5.1f%%] time=%s bitrate=%s speed=%s",
info.Percentage, info.CurrentTime, info.Bitrate, info.Speed)
},
}
_, err := mosaic.EncodeDash(
context.Background(),
job,
mosaic.WithNormalizeOrientation(),
mosaic.WithBFrames(2),
mosaic.WithScaleBitrateWithFPS(),
)
if err != nil {
log.Fatalf("DASH encoding failed: %v", err)
}
fmt.Println("\nDASH packaging complete -> ./output/dash/manifest.mpd")
}
Input Media ──► probe ──► ladder ──► optimize ──► encoder ──► FFmpeg (CMAF)
probe.Input extracts video dimensions, framerate, duration, audio presence, and rotation metadata.ladder.Build constructs a ladder preserving the original display aspect ratio.optimize.Apply caps bitrates based on resolution/FPS and trims redundant, closely-spaced renditions.Mosaic provides composable functional options to tailor the encoding process:
| Option | Description |
|---|---|
mosaic.WithNormalizeOrientation(bool...) | Probes rotation metadata, transposes video if rotated, and clears output rotation tags. |
mosaic.WithThreads(n) | Sets CPU encoding thread count (0 = FFmpeg auto-detection). |
mosaic.WithBFrames(n) | Sets number of B-frames for non-baseline profiles (default 0). |
mosaic.WithScaleBitrateWithFPS(bool...) | Proportionally scales bitrate caps for high-framerate videos (>30 FPS). |
mosaic.WithNVENC() | Uses NVIDIA hardware encoding (h264_nvenc). |
mosaic.WithVAAPI() | Uses Intel/AMD hardware encoding (h264_vaapi). |
mosaic.WithVideoToolbox() | Uses Apple VideoToolbox hardware encoding (h264_videotoolbox). |
mosaic.WithGPU(config.GPUType) | Selects a specific GPU backend explicitly. |
mosaic.WithLogLevel(level) | Sets FFmpeg log level (quiet, error, warning, info, debug). |
mosaic.WithLogger(logger) | Sets a custom *slog.Logger for internal library logs. |
Unlike legacy pipelines that letterbox non-16:9 videos into fixed frames, Mosaic calculates each rendition's width dynamically based on display dimensions:
| Input Resolution | Aspect Ratio | Generated Renditions |
|---|---|---|
1920x1080 | 16:9 Landscape | 1920x1080 (5000k), 1280x720 (3000k), 640x360 (1000k) |
1080x1080 | 1:1 Square | 1080x1080 (5000k), 720x720 (3000k), 360x360 (1000k) |
1080x1920 | 9:16 Portrait | 608x1080 (5000k), 404x720 (3000k), 202x360 (1000k) |
1280x718 | Custom Landscape | 642x360 (1000k) |
426x240 | Low Resolution | 426x240 (1000k) (no upscaling) |
The ProgressHandler receives parsed FFmpeg progress information on every tick:
type ProgressInfo struct {
Percentage float64 // Exact percentage (0.0% to 100.0%)
CurrentTime string // Encoded timestamp (e.g., "00:01:23.456000")
Bitrate string // Current encoding bitrate (e.g., "2450.3kbits/s")
Speed string // Encoding speed factor (e.g., "1.85x")
}
Complete, runnable examples are available in the examples/ directory:
examples/simple_hls: Standard HLS VOD packaging with progress reporting.examples/advanced_dash: DASH CMAF with B-Frames, FPS scaling, and custom thread control.examples/live_streaming: Low-latency live streaming profile (2s segments) for HLS & DASH.examples/orientation_normalization: Standalone and pipeline rotation normalization for mobile videos.examples/progress_monitoring: Terminal progress bar with percentage, speed, bitrate, and resource usage.examples/multi_gpu: Multi-backend GPU hardware acceleration (NVENC / VAAPI / VideoToolbox).Mosaic is tested with a 100% dependency-injected architecture, enforcing strict code hygiene and race detection:
# Run all tests with race detector
GOCACHE=/tmp/go-build go test -v -race ./...
# Static analysis
GOCACHE=/tmp/go-build go vet ./...
# Linter (Mandatory - zero issues policy)
golangci-lint run
Contributions are very welcome! Whether you are fixing a bug, adding new encoder profiles, or improving documentation:
CONTRIBUTING.md for development rules and contracts.MIT License. See LICENSE for details.
46 commits
Go
99.7%