Documentation
¶
Overview ¶
Package goshl provides an HLS transcoding service for on-demand video streaming.
goshl handles the complete HLS workflow including media probing, adaptive bitrate transcoding, playlist generation, and segment delivery. It supports hardware acceleration (NVIDIA NVENC, Apple VideoToolbox) and provides a distributed architecture through pluggable Storage and Coordinator interfaces.
Architecture ¶
The library is built around three core interfaces that must be implemented:
- Storage: Persists metadata, segments, sprites, and subtitles
- Coordinator: Manages job queues and segment readiness notifications
- PathGenerator: Generates URLs for playlists, segments, and assets
Basic Usage ¶
controller := goshl.NewController(goshl.Options{
Storage: myStorage,
Coordinator: myCoordinator,
PathGen: myPathGenerator,
HWAccel: true, // Enable hardware acceleration
})
// Start the transcoding worker pools
if err := controller.Start(ctx); err != nil {
log.Fatal(err)
}
defer controller.Stop()
// Generate master playlist for a media file
playlist, err := controller.MasterPlaylist(ctx, "file:///path/to/video.mp4")
HLS Workflow ¶
When a client requests content:
- MasterPlaylist probes the source and returns available renditions
- Client selects a variant and requests VariantPlaylist
- Client requests individual Segments, which triggers transcoding if needed
- Transcoded segments are cached in Storage for subsequent requests
Segment-on-Demand ¶
Segments are transcoded lazily when first requested. The Segment method:
- Returns immediately if the segment exists in storage
- Otherwise, enqueues a transcoding job and waits for completion
- Jobs transcode multiple segments at once (configurable via SegmentsPerJob)
Index ¶
- Constants
- Variables
- type Accelerator
- type AudioRendition
- type AudioStream
- type CacheInvalidator
- type Controller
- func (c *Controller) HWAccelConfig() domain.HWAccelConfig
- func (c *Controller) Invalidate(ctx context.Context, sourceURL string) error
- func (c *Controller) MasterPlaylist(ctx context.Context, sourceURL string) (string, error)
- func (c *Controller) MediaKey(ctx context.Context, sourceURL string) (string, error)
- func (c *Controller) Metadata(ctx context.Context, sourceURL string) (*Metadata, error)
- func (c *Controller) Preview(ctx context.Context, sourceURL string, config *PreviewConfig) ([]byte, error)
- func (c *Controller) Segment(ctx context.Context, sourceURL string, streamType StreamType, ...) ([]byte, error)
- func (c *Controller) Sprite(ctx context.Context, sourceURL string, index int) ([]byte, error)
- func (c *Controller) SpriteVTT(ctx context.Context, sourceURL string) ([]byte, error)
- func (c *Controller) Start(ctx context.Context) error
- func (c *Controller) Stop()
- func (c *Controller) SubtitlePlaylist(ctx context.Context, sourceURL, trackID string) (string, error)
- func (c *Controller) SubtitleVTT(ctx context.Context, sourceURL string, trackID string) ([]byte, error)
- func (c *Controller) Thumbnail(ctx context.Context, sourceURL string, config *ThumbnailConfig) ([]byte, error)
- func (c *Controller) VariantPlaylist(ctx context.Context, sourceURL string, streamType StreamType, ...) (string, error)
- type Coordinator
- type DecodeMode
- type Event
- type EventType
- type HWAccelConfig
- type Job
- type Metadata
- type Observer
- type ObserverFunc
- type Options
- type PathGenerator
- type PlaybackMethod
- type PreviewConfig
- type Segment
- type SegmentData
- type SegmentState
- type SegmentStatus
- type SourceRevisionResolver
- type Storage
- type StreamType
- type SubtitleStream
- type ThumbnailConfig
- type VideoRendition
- type VideoStream
Constants ¶
const ( // StreamVideo represents a video stream. StreamVideo = domain.StreamVideo // StreamAudio represents an audio stream. StreamAudio = domain.StreamAudio StreamSubtitle = domain.StreamSubtitle // AccelNone disables hardware acceleration and uses software encoding. AccelNone = domain.AccelNone // AccelCUDA selects NVIDIA CUDA/NVENC acceleration. AccelCUDA = domain.AccelCUDA // AccelVideoToolbox selects Apple VideoToolbox acceleration. AccelVideoToolbox = domain.AccelVideoToolbox // AccelVAAPI selects VAAPI acceleration. AccelVAAPI = domain.AccelVAAPI // AccelQSV selects Intel Quick Sync Video acceleration. AccelQSV = domain.AccelQSV SegmentStateReady = domain.SegmentStateReady SegmentStateError = domain.SegmentStateError DecodeSafe = domain.DecodeSafe DecodeDevice = domain.DecodeDevice DirectPlay = domain.DirectPlay DirectStream = domain.DirectStream Transcode = domain.Transcode EventMetadataCacheHit = domain.EventMetadataCacheHit EventMetadataCacheMiss = domain.EventMetadataCacheMiss EventMetadataProbed = domain.EventMetadataProbed EventSegmentCacheHit = domain.EventSegmentCacheHit EventSegmentCacheMiss = domain.EventSegmentCacheMiss EventLockWait = domain.EventLockWait EventJobEnqueued = domain.EventJobEnqueued EventJobStarted = domain.EventJobStarted EventJobCompleted = domain.EventJobCompleted EventJobFailed = domain.EventJobFailed EventJobAckFailed = domain.EventJobAckFailed EventSegmentReady = domain.EventSegmentReady EventSegmentFailed = domain.EventSegmentFailed EventSegmentNotifyFailed = domain.EventSegmentNotifyFailed EventHardwareSelected = domain.EventHardwareSelected EventHardwareFallback = domain.EventHardwareFallback EventLockReleaseFailed = domain.EventLockReleaseFailed )
Variables ¶
var ( ErrInvalidOptions = errors.New("invalid goshl options") ErrInvalidStreamType = errors.New("invalid stream type") ErrRenditionNotFound = errors.New("rendition not found") ErrSegmentOutOfRange = errors.New("segment index out of range") ErrSegmentTimeout = errors.New("segment wait timed out") ErrMetadataTimeout = errors.New("metadata wait timed out") ErrCacheInvalidationUnsupported = errors.New("storage does not support cache invalidation") ErrInvalidPreviewConfig = errors.New("invalid preview configuration") ErrInvalidThumbnailConfig = errors.New("invalid thumbnail configuration") )
var ( // ErrLockHeld is returned by Coordinator.AcquireLock when the lock is held by another instance. ErrLockHeld = domain.ErrLockHeld )
Functions ¶
This section is empty.
Types ¶
type Accelerator ¶ added in v0.0.10
type Accelerator = domain.Accelerator
Accelerator identifies a hardware acceleration backend.
type AudioRendition ¶ added in v0.0.12
type AudioRendition = domain.AudioRendition
type AudioStream ¶ added in v0.0.6
type AudioStream = domain.AudioStream
AudioStream contains audio stream information.
type CacheInvalidator ¶ added in v0.0.12
type Controller ¶
type Controller struct {
// contains filtered or unexported fields
}
Controller is the main entry point for HLS transcoding operations. It coordinates media probing, playlist generation, and on-demand transcoding.
A Controller must be started with Start before processing requests, and stopped with Stop when shutting down to ensure clean worker termination.
func NewController ¶
func NewController(opts Options) *Controller
NewController creates a new Controller with the given options. It panics if required options (Storage, Coordinator, PathGen) are nil.
The controller is not started automatically; call Start to begin processing transcoding jobs.
func NewControllerWithContext ¶ added in v0.0.12
func NewControllerWithContext(ctx context.Context, opts Options) (*Controller, error)
func (*Controller) HWAccelConfig ¶ added in v0.0.10
func (c *Controller) HWAccelConfig() domain.HWAccelConfig
HWAccelConfig returns the hardware acceleration configuration selected by the controller.
func (*Controller) Invalidate ¶ added in v0.0.12
func (c *Controller) Invalidate(ctx context.Context, sourceURL string) error
func (*Controller) MasterPlaylist ¶
MasterPlaylist returns the HLS master playlist for a media source.
The playlist advertises all available video renditions (based on source resolution and bitrate) and audio tracks. On first call for a source, it probes the media file using ffprobe and caches the metadata.
The returned string is a complete M3U8 playlist ready to serve to clients.
func (*Controller) Preview ¶ added in v0.0.4
func (c *Controller) Preview(ctx context.Context, sourceURL string, config *PreviewConfig) ([]byte, error)
Preview returns an animated GIF preview of the video.
The preview is generated by sampling frames from sprite sheets and combining them into an animated GIF. This provides a quick visual overview of the video content suitable for hover previews.
If config is nil, DefaultPreviewConfig is used. The generated preview is cached in storage for subsequent requests.
Returns GIF image data.
func (*Controller) Segment ¶
func (c *Controller) Segment(ctx context.Context, sourceURL string, streamType StreamType, renditionName string, index int) ([]byte, error)
Segment returns a transcoded media segment.
If the segment exists in storage, it returns immediately. Otherwise, it:
- Acquires a distributed lock to prevent duplicate transcoding
- Double-checks segment existence after acquiring lock
- Subscribes to segment readiness notifications via Coordinator
- Enqueues a transcoding job covering this segment and nearby segments
- Waits for the worker to complete transcoding (up to SegmentTimeout)
- Returns the transcoded segment data
Parameters:
- sourceURL: The media source URL
- streamType: Either StreamVideo or StreamAudio
- renditionName: The rendition identifier (e.g., "1080p", "aac_stereo")
- index: Zero-based segment index
Returns the raw MPEG-TS segment data, or an error if transcoding fails or times out.
func (*Controller) Sprite ¶
Sprite returns a sprite sheet image containing multiple video thumbnails.
Each sprite sheet contains a grid of thumbnails extracted from the video. The index parameter selects which sprite sheet to return (videos are divided into multiple sheets based on duration).
Returns JPEG image data.
func (*Controller) SpriteVTT ¶
SpriteVTT returns a WebVTT file mapping timestamps to thumbnail sprite images.
The VTT file references sprite sheet images (containing multiple thumbnails) with spatial coordinates for each timestamp. This enables video preview thumbnails during seek operations.
Sprite sheets and VTT data are generated on first request and cached.
func (*Controller) Start ¶
func (c *Controller) Start(ctx context.Context) error
Start initializes the video and audio transcoding worker pools. It subscribes to the Coordinator for incoming jobs and begins processing.
Start must be called before any transcoding can occur. The provided context controls the lifetime of background workers; canceling it triggers shutdown.
Returns an error if the worker pools fail to subscribe to the Coordinator.
func (*Controller) Stop ¶
func (c *Controller) Stop()
Stop gracefully shuts down the transcoding worker pools. It waits for any in-progress transcoding jobs to complete before returning. Always call Stop when shutting down to prevent resource leaks.
func (*Controller) SubtitlePlaylist ¶ added in v0.0.12
func (*Controller) SubtitleVTT ¶
func (c *Controller) SubtitleVTT(ctx context.Context, sourceURL string, trackID string) ([]byte, error)
SubtitleVTT extracts and returns subtitles in WebVTT format.
The lang parameter specifies the subtitle track language code (e.g., "en", "es"). If the requested language is not found in the source media, an error is returned.
Subtitles are extracted from the source on first request and cached.
func (*Controller) Thumbnail ¶ added in v0.0.5
func (c *Controller) Thumbnail(ctx context.Context, sourceURL string, config *ThumbnailConfig) ([]byte, error)
func (*Controller) VariantPlaylist ¶
func (c *Controller) VariantPlaylist(ctx context.Context, sourceURL string, streamType StreamType, renditionName string) (string, error)
VariantPlaylist returns the HLS media playlist for a specific rendition.
Parameters:
- sourceURL: The media source URL
- streamType: Either StreamVideo or StreamAudio
- renditionName: The rendition identifier (e.g., "1080p", "720p", "aac_stereo")
The playlist contains segment references with durations calculated from the source keyframe positions. Segment URLs are generated via PathGenerator.
type Coordinator ¶
type Coordinator = domain.Coordinator
Coordinator manages the distributed transcoding workflow. It handles job queuing across worker pools and notifies waiting clients when segments become available. For single-instance deployments, an in-memory implementation suffices. For distributed systems, consider Redis or a message queue.
type DecodeMode ¶ added in v0.0.12
type DecodeMode = domain.DecodeMode
type HWAccelConfig ¶ added in v0.0.12
type HWAccelConfig = domain.HWAccelConfig
type ObserverFunc ¶ added in v0.0.12
type ObserverFunc = domain.ObserverFunc
type Options ¶
type Options struct {
// Storage is required. Handles persistence of metadata, segments, and assets.
Storage Storage
// Coordinator is required. Manages job distribution and segment notifications.
Coordinator Coordinator
// PathGen is required. Generates URLs for playlists and segments.
PathGen PathGenerator
// HWAccel enables hardware-accelerated encoding when available.
// Automatically detects NVENC (NVIDIA) or VideoToolbox (Apple).
// Falls back to software encoding if no hardware support is found.
HWAccel bool
// HWAccelMode explicitly selects a hardware accelerator.
// When set, it takes precedence over HWAccel auto-detection.
HWAccelMode Accelerator
// SegmentTimeout is the maximum time to wait for a segment to be transcoded.
// Default: 30 seconds.
SegmentTimeout time.Duration
// TargetDuration is the target HLS segment duration in seconds.
// Actual duration varies based on keyframe positions.
// Default: 6.0 seconds.
TargetDuration float64
// SegmentsPerJob is the number of segments transcoded per job.
// Higher values improve throughput but increase latency for first segment.
// Default: 4.
SegmentsPerJob int
// VideoPoolSize is the number of concurrent video transcoding workers.
// Default: 2.
VideoPoolSize int
// AudioPoolSize is the number of concurrent audio transcoding workers.
// Default: 4.
AudioPoolSize int
// DefaultPreviewConfig sets default parameters for animated preview generation.
// Defaults: MaxFrames=40, Frameduration=250ms, Width=480.
DefaultPreviewConfig PreviewConfig
// DefaultThumbnailConfig sets default parameters for thumbnail generation.
// Defaults: Position=0.1 (10% into video), Width=480.
DefaultThumbnailConfig ThumbnailConfig
JobTimeout time.Duration
CacheVersion string
SourceRevision SourceRevisionResolver
Observer Observer
HWAccelDecodeMode DecodeMode
AllowHardwareFallback bool
}
Options configures the Controller behavior and dependencies.
type PathGenerator ¶
type PathGenerator = domain.PathGenerator
PathGenerator creates URLs for HLS resources. These URLs are embedded in playlists and must be routable back to the appropriate Controller methods.
type PlaybackMethod ¶ added in v0.0.12
type PlaybackMethod = domain.PlaybackMethod
type PreviewConfig ¶ added in v0.0.4
type PreviewConfig = domain.PreviewConfig
PreviewConfig configures animated preview generation parameters.
type SegmentData ¶ added in v0.0.2
type SegmentData = domain.SegmentData
SegmentData encapsulates information about a specific media segment.
type SegmentState ¶ added in v0.0.12
type SegmentState = domain.SegmentState
type SegmentStatus ¶ added in v0.0.3
type SegmentStatus = domain.SegmentStatus
SegmentStatus represents the processing state of a segment.
type SourceRevisionResolver ¶ added in v0.0.12
type Storage ¶
Storage defines the interface for persisting transcoded content and metadata. Implementations should handle concurrent access and may use any backing store (filesystem, S3, Redis, etc.).
type StreamType ¶
type StreamType = domain.StreamType
StreamType identifies the type of media stream (video or audio).
type SubtitleStream ¶ added in v0.0.6
type SubtitleStream = domain.SubtitleStream
SubtitleStream contains subtitle stream information.
type ThumbnailConfig ¶ added in v0.0.5
type ThumbnailConfig = domain.ThumbnailConfig
ThumbnailConfig configures thumbnail generation parameters.
type VideoRendition ¶ added in v0.0.12
type VideoRendition = domain.VideoRendition
type VideoStream ¶ added in v0.0.6
type VideoStream = domain.VideoStream
VideoStream contains video stream information.