Skip to content

Latest commit

Β 

History

46 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Mosaic

Mosaic Logo

Predictable, Production-Ready Adaptive Bitrate (ABR) Video Packaging for Go

Documentation Portal

Go Reference Go Version Build Status Latest Release License: MIT


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.


⚑ Highlights

  • Standard CMAF Output: Generates HLS (master.m3u8, variant playlists, fMP4 segments) and DASH (manifest.mpd, init.m4s, chunk.m4s) streams.
  • Aspect-Preserving ABR Ladders: Automatically preserves the source display aspect ratio β€” landscape, square (1:1), portrait (9:16), or ultra-wide inputs never get distorted or letterboxed with black bars.
  • Orientation Normalization: Probes display matrices and rotation tags (90Β°, 180Β°, 270Β°), physically transposes frames when needed, and resets output metadata so mobile videos display correctly everywhere.
  • Real-Time Progress Tracking: Accurately computes encoding percentage (0.0% to 100.0%), encoded time, current bitrate, and speed.
  • Hardware Acceleration: Out-of-the-box support for NVIDIA NVENC, Intel/AMD VAAPI, and Apple VideoToolbox.
  • Single-Pass Filter Complex: Both HLS and DASH use unified filter_complex graphs (split -> scale -> setsar=1) for optimal 1-pass encoding performance and SAR consistency.
  • High Framerate Bitrate Scaling: Optional automatic bitrate adjustments for high-framerate content (>30 FPS).
  • Configurable B-Frames: Tune B-frame counts across profiles for maximum compression efficiency.
  • Zero Third-Party Dependencies: Built strictly with Go standard library + FFmpeg/FFprobe CLI tooling.
  • Fully Testable Architecture: Interface-driven command executor allows 100% unit testing without calling live FFmpeg.

πŸ“‹ Requirements

  • Go: 1.25+
  • FFmpeg: 4.4+ (with libx264 and aac support)
  • FFprobe: Typically installed alongside FFmpeg

πŸ“¦ Installation

As a Go Library

go get github.com/farshidrezaei/mosaic

As a Standalone CLI Tool

# 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

πŸ› οΈ CLI Quick Start

# 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

πŸš€ Quick Start

1. HLS Packaging

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)
}

2. DASH CMAF Packaging

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")
}

🧭 Core Workflow

Input Media ──► probe ──► ladder ──► optimize ──► encoder ──► FFmpeg (CMAF)
  1. Probe: probe.Input extracts video dimensions, framerate, duration, audio presence, and rotation metadata.
  2. Ladder: ladder.Build constructs a ladder preserving the original display aspect ratio.
  3. Optimize: optimize.Apply caps bitrates based on resolution/FPS and trims redundant, closely-spaced renditions.
  4. Encoder: Generates an optimal single-pass FFmpeg command graph and streams real-time progress.

πŸŽ›οΈ Functional Options

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.

πŸ“ Aspect Ratio & Ladder Preservation

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)

πŸ“Š Real-Time Progress Monitoring

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")
}

πŸ“‚ Examples

Complete, runnable examples are available in the examples/ directory:


πŸ§ͺ Testing & Quality Assurance

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

πŸ“š Documentation Map

🀝 Contributing & Community

Contributions are very welcome! Whether you are fixing a bug, adding new encoder profiles, or improving documentation:

  1. Check out CONTRIBUTING.md for development rules and contracts.
  2. Explore Good First Issues for beginner-friendly tasks.
  3. Join the conversation on GitHub Discussions.

🌟 Star History

Star History Chart


πŸ“„ License

MIT License. See LICENSE for details.

Releases

Packages

Contributors

Languages