HLS
HLS
HTTP Live Streaming with adaptive bitrate, transcoding, and distributed support
Overview
github.com/xraph/forge/extensions/hls provides an HTTP Live Streaming (HLS) server with adaptive
bitrate streaming, multi-variant playlists, FFmpeg transcoding, and optional distributed mode. It
registers an HLS service in the DI container and mounts streaming and management endpoints on the
Forge HTTP router.
What It Registers
| Service | DI Key | Type |
|---|---|---|
| HLS service | hls | *Manager (satisfies HLS) |
Dependencies
- Required:
storageextension -- segments and playlists are stored via the storage manager. - Optional:
consensusextension -- required for distributed mode with leader election and stream ownership.
Quick Start
package main
import (
"context"
"github.com/xraph/forge"
"github.com/xraph/forge/extensions/hls"
"github.com/xraph/forge/extensions/storage"
)
func main() {
app := forge.NewApp(forge.AppConfig{Name: "video-app", Version: "1.0.0"})
// Storage extension is required for segment storage
app.RegisterExtension(storage.NewExtension(
storage.WithDefault("media"),
storage.WithLocalBackend("media", "/var/data/media"),
))
// HLS extension
app.RegisterExtension(hls.NewExtension(
hls.WithBasePath("/hls"),
hls.WithBaseURL("https://cdn.example.com/hls"),
hls.WithTranscoding(true,
hls.Profile360p,
hls.Profile720p,
hls.Profile1080p,
),
hls.WithDVRWindow(30), // 30 segments DVR window
))
ctx := context.Background()
app.Start(ctx)
defer app.Stop(ctx)
// Resolve the HLS service
hlsSvc, _ := forge.Inject[hls.HLS](app.Container())
// Create a live stream
stream, _ := hlsSvc.CreateStream(ctx, hls.StreamOptions{
Title: "Live Event",
Type: hls.StreamTypeLive,
TargetDuration: 6,
DVRWindowSize: 30,
TranscodeProfiles: []hls.TranscodeProfile{
hls.Profile360p,
hls.Profile720p,
},
})
// Start the live stream
hlsSvc.StartLiveStream(ctx, stream.ID)
// Ingest a segment (typically called by your media pipeline)
hlsSvc.IngestSegment(ctx, stream.ID, &hls.Segment{
StreamID: stream.ID,
VariantID: "720p",
SequenceNum: 1,
Duration: 6.0,
Data: segmentData,
})
// Get the master playlist URL
masterURL := fmt.Sprintf("/hls/%s/master.m3u8", stream.ID)
}VOD (Video on Demand)
// Create a VOD stream from an existing video file
stream, _ := hlsSvc.CreateVOD(ctx, hls.VODOptions{
Title: "Training Video",
SourceURL: "/path/to/video.mp4",
Profiles: []hls.TranscodeProfile{hls.Profile480p, hls.Profile720p, hls.Profile1080p},
})
// Or transcode an existing video
hlsSvc.TranscodeVideo(ctx, stream.ID, hls.TranscodeProfile{
Name: "720p",
Width: 1280,
Height: 720,
Bitrate: 2500000,
AudioBitrate: 128000,
})Using HLS in Your Services
type VideoService struct {
hls hls.HLS
logger forge.Logger
}
func NewVideoService(h hls.HLS, logger forge.Logger) *VideoService {
return &VideoService{hls: h, logger: logger}
}
func (vs *VideoService) StartLiveEvent(ctx context.Context, title string) (string, error) {
stream, err := vs.hls.CreateStream(ctx, hls.StreamOptions{
Title: title,
Type: hls.StreamTypeLive,
})
if err != nil {
return "", err
}
return stream.ID, vs.hls.StartLiveStream(ctx, stream.ID)
}
func (vs *VideoService) GetStreamStats(ctx context.Context, streamID string) (*hls.StreamStats, error) {
return vs.hls.GetStreamStats(ctx, streamID)
}HTTP Endpoints
Routes are mounted under BasePath (default /hls):
| Method | Path | Purpose |
|---|---|---|
| GET | /:streamID/master.m3u8 | Master playlist |
| GET | /:streamID/variants/:variantID/playlist.m3u8 | Media playlist |
| GET | /:streamID/variants/:variantID/segment_:num.ts | Media segment |
| POST | /streams | Create a stream |
| GET | /streams/:streamID | Get stream info |
| DELETE | /streams/:streamID | Delete a stream |
| GET | /streams | List streams |
| POST | /streams/:streamID/start | Start live streaming |
| POST | /streams/:streamID/stop | Stop live streaming |
| POST | /streams/:streamID/ingest | Ingest a segment |
| GET | /streams/:streamID/stats | Stream statistics |
Key Concepts
- Streams -- create live, VOD, or event streams. Each stream has a unique ID, multiple variants, and a master playlist.
- Variants -- each stream can have multiple quality variants (e.g. 360p, 720p, 1080p) with different bitrates and resolutions.
- Segments -- media is divided into time-based segments (default 6 seconds). Segments are stored via the storage extension.
- Transcoding -- FFmpeg-based transcoding converts ingested media into multiple quality variants.
- DVR window -- configurable sliding window of segments in live playlists for time-shifted viewing.
- Distributed mode -- scale HLS across nodes with consensus-based leader election and stream ownership.
Detailed Pages
How is this guide?