reel

package module
v0.0.0-...-aa6cde0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 8, 2026 License: GPL-3.0 Imports: 8 Imported by: 0

README

reel

AV1 encoding tool using the SVT-AV1 encoder library and FFmpeg/libav for parallel chunked encoding. Uses opinionated defaults so you can encode without dealing with encoder complexity.

Expectations

This repository is shared as is. reel is a personal encoding tool I built for my own workflow, hardware, and preferences. I've open sourced it because I believe in sharing but I'm not an active maintainer.

  • Experimental: This is an early stage project that is purely experimental at this point. I would recommend looking at av1an or xav for parallel chunked encoding.
  • Personal-first: Things will change and break as I iterate.
  • Best-effort only: This is a part-time hobby project and I work on it when I'm able to. I may be slow to respond to questions or may not respond at all.
  • “Vibe coded”: I’m not a Go developer and this project started as (and remains) a vibe-coding experiment. Expect rough edges.

Features

  • Parallel chunked encoding with shot-aware chunk planning
  • Default CVVDP target-quality mode with whole-chunk probes and adaptive CRF search
  • Automatic black bar crop detection
  • HDR10/HLG metadata preservation
  • Multi-track audio transcoding to Opus
  • Post-encode validation (codec, dimensions, duration, HDR)
  • Library API for embedding

Design Goals

reel encodes media libraries for home streaming watched at normal viewing distances. It is not an archival or reference quality encoding tool. The aim is "fast" target quality encodes that have more consistent quality across varied content compared to fixed CRF. Speed is a first class goal. When a tradeoff buys meaningful encode time at a quality cost that is invisible in normal viewing, reel takes it.

This is a deliberately different point on the speed/quality/size curve from typical target quality encoding tools which chase near optimal per-scene quality at the expense of more compute.

Requirements

  • Go 1.26+
  • libSvtAv1Enc (SVT-AV1 encoder shared library)
  • libopusenc shared library (for Opus audio encoding)
  • FFmpeg/libav development libraries: libavformat, libavcodec, libavutil, libswscale, libswresample
  • libvship + CUDA for the default CVVDP target-quality build, or build with -tags no_vship for fixed-CRF-only use. Build libvship with MITIGATE_MALLOC_ASYNC=on (e.g. make build BACKEND=Cuda MITIGATE_MALLOC_ASYNC=on): reel scores probes with one VSHIP handler per metric worker concurrently, and libvship's default cudaMallocAsync allocator races across coexisting handlers and silently corrupts scores without this flag.
# Ubuntu/Debian
sudo apt-get install libavformat-dev libavcodec-dev libavutil-dev libswscale-dev libswresample-dev libopusenc0 libsvtav1enc-dev

# Verify libopusenc is available
ldconfig -p | grep opusenc

# Verify libSvtAv1Enc is available
ldconfig -p | grep SvtAv1Enc

Install

go install -trimpath codeberg.org/five82/reel/cmd/reel@latest                # default target-quality CVVDP/VSHIP build
go install -trimpath -tags no_vship codeberg.org/five82/reel/cmd/reel@latest # fixed-CRF-only build without VSHIP

Or build from source:

git clone https://codeberg.org/five82/reel
cd reel
go build -trimpath -o reel ./cmd/reel                 # default target-quality CVVDP/VSHIP build
go build -trimpath -tags no_vship -o reel ./cmd/reel  # fixed-CRF-only build without VSHIP

Usage

reel encode -i input.mkv -o output/
reel encode -i /videos/ -o /encoded/

reel splits each video into chunks, encodes chunks in parallel with SVT-AV1, merges the encoded video, then muxes Opus audio, chapters, and metadata. Fixed-CRF mode keeps simple duration-based chunking. Target-quality mode uses shot detection plus target-aware packing with a shorter 12s maximum chunk cap, so one CRF decision usually covers a visually coherent region without creating unnecessary tiny chunks. Adaptive workers start conservatively, test higher concurrency by recent throughput, and back off on RAM or swap pressure. If a run is interrupted, run the same command again to resume from completed chunks.

Target-quality mode uses CVVDP through VSHIP/CUDA and is enabled in the default build, which requires libvship. The default search scores each probe over the whole chunk, starts from adaptive CRF priors, requires the score to meet the lower quality bound, and accepts tiny over-target scores to avoid wasting time chasing metric perfection. The converged probe is reused as the final chunk. Build with -tags no_vship to disable target-quality mode entirely and default to fixed-CRF mode.

Run reel encode --help for the full flag list, or see docs/USAGE.md.

Library Usage

reel can be used as a Go library:

import "codeberg.org/five82/reel"

encoder, err := reel.New(
    reel.WithCRF(26.25), // fixed-CRF mode; default is target-quality mode
)
if err != nil {
    log.Fatal(err)
}

result, err := encoder.Encode(ctx, "input.mkv", "output/", func(event reel.Event) error {
    switch e := event.(type) {
    case reel.EncodingProgressEvent:
        fmt.Printf("Progress: %.1f%%\n", e.Percent)
    case reel.EncodingCompleteEvent:
        fmt.Printf("Done: %.1f%% reduction\n", e.SizeReductionPercent)
    }
    return nil
})

Development

go build -trimpath ./...
go test ./...
golangci-lint run
./check-ci.sh          # Full CI check

Credit

Thanks to xav for the libav-based parallel chunked encoding approach.

Documentation

Overview

Package reel provides a Go library for AV1 video encoding with SVT-AV1.

Package reel provides a Go library for AV1 video encoding with SVT-AV1.

Reel is an opinionated AV1 encoder that handles the complexity of video encoding with sensible defaults, automatic crop detection, HDR metadata preservation, and post-encode validation.

Basic usage:

encoder, err := reel.New(
    reel.WithCRF(26),
)
if err != nil {
    log.Fatal(err)
}

result, err := encoder.Encode(ctx, "input.mkv", "output/", nil)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Encoded: %s, reduction: %.1f%%\n",
    result.OutputFile, result.SizeReductionPercent)

Index

Constants

View Source
const (
	EventTypeHardware           = "hardware"
	EventTypeInitialization     = "initialization"
	EventTypeStageProgress      = "stage_progress"
	EventTypeEncodingStarted    = "encoding_started"
	EventTypeEncodingConfig     = "encoding_config"
	EventTypeCropResult         = "crop_result"
	EventTypeEncodingProgress   = "encoding_progress"
	EventTypeValidationComplete = "validation_complete"
	EventTypeEncodingComplete   = "encoding_complete"
	EventTypeOperationComplete  = "operation_complete"
	EventTypeBatchStarted       = "batch_started"
	EventTypeFileProgress       = "file_progress"
	EventTypeBatchComplete      = "batch_complete"
	EventTypeWarning            = "warning"
	EventTypeError              = "error"
)

Event types for Spindle integration.

Variables

This section is empty.

Functions

func FindVideos

func FindVideos(dir string) ([]string, error)

FindVideos finds video files in a directory.

func NewTimestamp

func NewTimestamp() int64

NewTimestamp returns the current Unix timestamp.

Types

type BaseEvent

type BaseEvent struct {
	EventType string `json:"type"`
	Time      int64  `json:"timestamp"`
}

BaseEvent contains common fields for all events.

func (BaseEvent) Timestamp

func (e BaseEvent) Timestamp() int64

func (BaseEvent) Type

func (e BaseEvent) Type() string

type BatchCompleteEvent

type BatchCompleteEvent struct {
	BaseEvent
	SuccessfulCount           int     `json:"successful_count"`
	TotalFiles                int     `json:"total_files"`
	TotalSizeReductionPercent float64 `json:"total_size_reduction_percent"`
}

BatchCompleteEvent represents batch completion.

type BatchResult

type BatchResult struct {
	Results               []Result
	SuccessfulCount       int
	TotalFiles            int
	TotalSizeReduction    float64
	ValidationPassedCount int
}

BatchResult contains the result of a batch encode.

type BatchStartInfo

type BatchStartInfo = reporter.BatchStartInfo

BatchStartInfo contains batch start metadata.

type BatchSummary

type BatchSummary = reporter.BatchSummary

BatchSummary contains batch completion information.

type CropSummary

type CropSummary = reporter.CropSummary

CropSummary contains crop detection results.

type Encoder

type Encoder struct {
	// contains filtered or unexported fields
}

Encoder is the main entry point for video encoding.

func New

func New(opts ...Option) (*Encoder, error)

New creates a new Encoder with the given options.

func (*Encoder) Encode

func (e *Encoder) Encode(ctx context.Context, input, outputDir string, handler EventHandler) (*Result, error)

Encode encodes a single video file.

func (*Encoder) EncodeBatch

func (e *Encoder) EncodeBatch(ctx context.Context, inputs []string, outputDir string, handler EventHandler) (*BatchResult, error)

EncodeBatch encodes multiple video files.

func (*Encoder) EncodeWithReporter

func (e *Encoder) EncodeWithReporter(ctx context.Context, input, outputDir string, rep Reporter) (*Result, error)

EncodeWithReporter encodes a single video file using a custom Reporter. This provides direct access to all encoding events, unlike Encode which uses the EventHandler abstraction.

type EncodingCompleteEvent

type EncodingCompleteEvent struct {
	BaseEvent
	OutputFile                string  `json:"output_file"`
	OriginalSize              uint64  `json:"original_size"`
	EncodedSize               uint64  `json:"encoded_size"`
	SizeReductionPercent      float64 `json:"size_reduction_percent"`
	VideoOriginalSize         uint64  `json:"video_original_size,omitempty"`
	VideoEncodedSize          uint64  `json:"video_encoded_size,omitempty"`
	VideoSizeReductionPercent float64 `json:"video_size_reduction_percent,omitempty"`
}

EncodingCompleteEvent represents successful encode completion.

type EncodingConfigSummary

type EncodingConfigSummary = reporter.EncodingConfigSummary

EncodingConfigSummary contains encoding configuration.

type EncodingOutcome

type EncodingOutcome = reporter.EncodingOutcome

EncodingOutcome contains final encoding results.

type EncodingProgressEvent

type EncodingProgressEvent struct {
	BaseEvent
	Percent     float32 `json:"percent"`
	Speed       float32 `json:"speed"`
	RecentSpeed float32 `json:"recent_speed"`
	FPS         float32 `json:"fps"`
	ETASeconds  int64   `json:"eta_seconds"`
}

EncodingProgressEvent represents encoding progress updates.

type ErrorEvent

type ErrorEvent struct {
	BaseEvent
	Title      string `json:"title"`
	Message    string `json:"message"`
	Context    string `json:"context"`
	Suggestion string `json:"suggestion"`
}

ErrorEvent represents an error.

type Event

type Event interface {
	Type() string
	Timestamp() int64
}

Event is the interface for all reel events.

type EventHandler

type EventHandler func(Event) error

EventHandler is called with events during encoding.

type FileProgressContext

type FileProgressContext = reporter.FileProgressContext

FileProgressContext contains current file index within a batch.

type FileResult

type FileResult = reporter.FileResult

FileResult contains per-file encoding result.

type HardwareSummary

type HardwareSummary = reporter.HardwareSummary

HardwareSummary contains hardware information.

type InitializationSummary

type InitializationSummary = reporter.InitializationSummary

InitializationSummary describes the current file before encoding.

type NullReporter

type NullReporter = reporter.NullReporter

NullReporter is a no-op reporter that discards all updates.

type Option

type Option func(*config.Config)

Option configures the encoder.

func WithCRF

func WithCRF[T crfValue](crf T) Option

WithCRF sets a single fixed CRF value for all resolutions (1-70 in 0.25 steps, lower is better quality).

func WithCRFByResolution

func WithCRFByResolution[SD crfValue, HD crfValue, UHD crfValue](sd SD, hd HD, uhd UHD) Option

WithCRFByResolution sets resolution-specific fixed CRF values (1-70 in 0.25 steps, lower is better quality). SD applies to videos <1920 width, HD to >=1920 and <3840, UHD to >=3840.

func WithCVVDPDisplay

func WithCVVDPDisplay(path string) Option

WithCVVDPDisplay sets a VSHIP/CVVDP display JSON override for target-quality mode.

func WithDisableAutocrop

func WithDisableAutocrop() Option

WithDisableAutocrop disables automatic black bar detection.

func WithQualityMode

func WithQualityMode(mode string) Option

WithQualityMode selects target-quality (default) or fixed-CRF mode.

func WithTargetQuality

func WithTargetQuality(targetRange string) Option

WithTargetQuality sets the CVVDP JOD target range for target-quality mode.

type ProgressSnapshot

type ProgressSnapshot = reporter.ProgressSnapshot

ProgressSnapshot contains encoding progress information.

type Reporter

type Reporter = reporter.Reporter

Reporter defines the interface for progress reporting during encoding. Implement this interface to receive detailed events about encoding progress.

type ReporterError

type ReporterError = reporter.ReporterError

ReporterError contains error information.

type ReporterValidationStep

type ReporterValidationStep = reporter.ValidationStep

ReporterValidationStep represents a single validation check from the reporter. Note: This is distinct from the ValidationStep type in events.go which is used for JSON serialization. Use reporter.ValidationStep internally.

type Result

type Result struct {
	OutputFile                string
	OriginalSize              uint64
	EncodedSize               uint64
	SizeReductionPercent      float64
	VideoOriginalSize         uint64
	VideoEncodedSize          uint64
	VideoSizeReductionPercent float64
	ValidationPassed          bool
	EncodingSpeed             float32
}

Result contains the result of a single file encode.

type StageProgress

type StageProgress = reporter.StageProgress

StageProgress represents a generic stage update.

type ValidationCompleteEvent

type ValidationCompleteEvent struct {
	BaseEvent
	ValidationPassed bool             `json:"validation_passed"`
	ValidationSteps  []ValidationStep `json:"validation_steps"`
}

ValidationCompleteEvent represents validation completion.

type ValidationStep

type ValidationStep struct {
	Step    string `json:"step"`
	Passed  bool   `json:"passed"`
	Details string `json:"details"`
}

ValidationStep represents a single validation check.

type ValidationSummary

type ValidationSummary = reporter.ValidationSummary

ValidationSummary contains validation results.

type WarningEvent

type WarningEvent struct {
	BaseEvent
	Message string `json:"message"`
}

WarningEvent represents a warning message.

Directories

Path Synopsis
cmd
reel command
Package main provides the CLI entry point for Reel.
Package main provides the CLI entry point for Reel.
internal
audio
Package audio provides native libav decoding and libopusenc audio encoding.
Package audio provides native libav decoding and libopusenc audio encoding.
chunk
Package chunk provides types and functions for managing video encoding chunks.
Package chunk provides types and functions for managing video encoding chunks.
chunkplan
Package chunkplan builds shot-aware chunk boundaries for video encoding.
Package chunkplan builds shot-aware chunk boundaries for video encoding.
config
Package config provides configuration types and defaults for reel.
Package config provides configuration types and defaults for reel.
discovery
Package discovery provides file discovery for video processing.
Package discovery provides file discovery for video processing.
encode
Package encode provides the parallel chunk encoding pipeline.
Package encode provides the parallel chunk encoding pipeline.
encoder
Package encoder provides SVT-AV1 library-based encoding for chunked encoding.
Package encoder provides SVT-AV1 library-based encoding for chunked encoding.
keyframe
Package keyframe provides fixed-length chunk generation for video encoding.
Package keyframe provides fixed-length chunk generation for video encoding.
logging
Package logging provides file logging for reel CLI.
Package logging provides file logging for reel CLI.
media
Package media provides native libav media probing helpers.
Package media provides native libav media probing helpers.
perf
Package perf collects per-file pipeline timing and adaptive-worker history and writes a perf.json artifact into the work directory.
Package perf collects per-file pipeline timing and adaptive-worker history and writes a perf.json artifact into the work directory.
processing
Package processing provides video processing orchestration.
Package processing provides video processing orchestration.
quality
Package quality contains target-quality search and CVVDP helpers.
Package quality contains target-quality search and CVVDP helpers.
reporter
Package reporter provides progress reporting interfaces and implementations.
Package reporter provides progress reporting interfaces and implementations.
util
Package util provides utility functions for formatting and common operations.
Package util provides utility functions for formatting and common operations.
validation
Package validation provides post-encode validation checks.
Package validation provides post-encode validation checks.
video
Package video provides FFmpeg/libav based video probing and frame extraction.
Package video provides FFmpeg/libav based video probing and frame extraction.
worker
Package worker provides types and utilities for parallel chunk encoding.
Package worker provides types and utilities for parallel chunk encoding.
scripts
aligncheck command
aligncheck reproduces and locates the scoring frame-misalignment bug.
aligncheck reproduces and locates the scoring frame-misalignment bug.
chunkbench command
chunkbench runs shot detection and chunk planning without encoding.
chunkbench runs shot detection and chunk planning without encoding.
fullvalidate command
fullvalidate scores a finished Reel encode against its source with full-chunk CVVDP, giving ground-truth per-chunk JOD instead of the recorded scores the target-quality search reports about itself.
fullvalidate scores a finished Reel encode against its source with full-chunk CVVDP, giving ground-truth per-chunk JOD instead of the recorded scores the target-quality search reports about itself.
handlertest command
handlertest -- standing concurrency-safety check for VSHIP CVVDP scoring.
handlertest -- standing concurrency-safety check for VSHIP CVVDP scoring.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL