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 AudioStream
- type Controller
- func (c *Controller) HWAccelConfig() domain.HWAccelConfig
- func (c *Controller) MasterPlaylist(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) SubtitleVTT(ctx context.Context, sourceURL string, lang 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 Job
- type Metadata
- type Options
- type PathGenerator
- type PreviewConfig
- type SegmentData
- type SegmentStatus
- type Storage
- type StreamType
- type SubtitleStream
- type ThumbnailConfig
- type VideoStream
Constants ¶
const ( // StreamVideo represents a video stream. StreamVideo = domain.StreamVideo // StreamAudio represents an audio stream. StreamAudio = domain.StreamAudio // 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 )
Variables ¶
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 AudioStream ¶ added in v0.0.6
type AudioStream = domain.AudioStream
AudioStream contains audio stream information.
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 (*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) 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) SubtitleVTT ¶
func (c *Controller) SubtitleVTT(ctx context.Context, sourceURL string, lang 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 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
}
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 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 SegmentStatus ¶ added in v0.0.3
type SegmentStatus = domain.SegmentStatus
SegmentStatus represents the processing state of a segment.
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 VideoStream ¶ added in v0.0.6
type VideoStream = domain.VideoStream
VideoStream contains video stream information.