Documentation
¶
Overview ¶
Package hls is parser & generator library for Apple HLS.
Index ¶
- Constants
- Variables
- func Decode(data bytes.Buffer, strict bool) (Playlist, ListType, error)
- func DecodeFrom(reader io.Reader, strict bool) (Playlist, ListType, error)
- func FullTimeParse(value string) (time.Time, error)
- func StrictTimeParse(value string) (time.Time, error)
- type Alternative
- type Key
- type ListType
- type Map
- type MasterPlaylist
- func (p *MasterPlaylist) Append(uri string, chunklist *MediaPlaylist, params VariantParams)
- func (p *MasterPlaylist) Decode(data bytes.Buffer, strict bool) error
- func (p *MasterPlaylist) DecodeFrom(reader io.Reader, strict bool) error
- func (p *MasterPlaylist) Encode() *bytes.Buffer
- func (p *MasterPlaylist) ResetCache()
- func (p *MasterPlaylist) SetVersion(ver int)
- func (p *MasterPlaylist) String() string
- func (p *MasterPlaylist) Version() int
- type MediaPlaylist
- func (p *MediaPlaylist) Append(seg *MediaSegment) error
- func (p *MediaPlaylist) AppendWithAutoExtend(seg *MediaSegment) error
- func (p *MediaPlaylist) Close()
- func (p *MediaPlaylist) Count() int
- func (p *MediaPlaylist) Decode(data bytes.Buffer, strict bool) error
- func (p *MediaPlaylist) DecodeFrom(reader io.Reader, strict bool) error
- func (p *MediaPlaylist) DurationAsInt(yes bool)
- func (p *MediaPlaylist) Encode() *bytes.Buffer
- func (p *MediaPlaylist) ExtendCapacity() (err error)
- func (p *MediaPlaylist) Remove() (err error)
- func (p *MediaPlaylist) ResetCache()
- func (p *MediaPlaylist) SetDefaultKey(method, uri, iv, keyformat, keyformatversions string) error
- func (p *MediaPlaylist) SetDefaultMap(uri string, limit, offset int)
- func (p *MediaPlaylist) SetDiscontinuity() error
- func (p *MediaPlaylist) SetIframeOnly()
- func (p *MediaPlaylist) SetKey(method, uri, iv, keyformat, keyformatversions string) error
- func (p *MediaPlaylist) SetMap(uri string, limit, offset int) error
- func (p *MediaPlaylist) SetProgramDateTime(value time.Time) error
- func (p *MediaPlaylist) SetRange(limit, offset int) error
- func (p *MediaPlaylist) SetSCTE35(scte35 *SCTE) error
- func (p *MediaPlaylist) SetVersion(ver int)
- func (p *MediaPlaylist) SetWinSize(winsize int) error
- func (p *MediaPlaylist) Slide(seg *MediaSegment) (err error)
- func (p *MediaPlaylist) String() string
- func (p *MediaPlaylist) Version() int
- func (p *MediaPlaylist) WinSize() int
- type MediaSegment
- type MediaType
- type Playlist
- type SCTE
- type SCTE35CueType
- type SCTE35Syntax
- type Variant
- type VariantParams
- type Widevine
Examples ¶
Constants ¶
const ( // DateTime is the format for EXT-X-PROGRAM-DATE-TIME defined in section 3.4.5. DateTime = time.RFC3339Nano )
Variables ¶
var ErrPlaylistFull = errors.New("playlist is full")
ErrPlaylistFull is the error surfaced if a playlist is full. Consider extending the capacity in that situation.
var TimeParse = FullTimeParse
TimeParse globally apply and/or override Time Parser function. Available variants:
- FullTimeParse - implements full featured ISO/IEC 8601:2004
- StrictTimeParse - implements only RFC3339 Nanoseconds format
Functions ¶
func DecodeFrom ¶
DecodeFrom detects type of playlist and decodes it. It accepts data conformed with io.Reader.
func FullTimeParse ¶
FullTimeParse implements ISO/IEC 8601:2004.
Types ¶
type Alternative ¶
type Alternative struct {
GroupID string
URI string
Type string
Language string
Name string
Default bool
Autoselect string
Forced string
Characteristics string
Subtitles string
}
Alternative represents EXT-X-MEDIA tag in variants.
type Map ¶
type Map struct {
URI string
Limit int // <n> is length in bytes for the file under URI
Offset int // [@o] is offset from the start of the file under URI
}
Map represents specifies how to obtain the Media Initialization Section required to parse the applicable Media Segments. It applies to every Media Segment that appears after it in the Playlist until the next EXT-X-MAP tag or until the end of the playlist. It realizes the EXT-MAP tag.
type MasterPlaylist ¶
type MasterPlaylist struct {
Variants []*Variant
Args string // optional arguments placed after URI (URI?Args)
CypherVersion string // non-standard tag for Widevine (see also WV struct)
// contains filtered or unexported fields
}
MasterPlaylist represents a master playlist which combines media playlists for multiple bitrates.
URI lines in the playlist identify media playlists. Sample of Master Playlist file: #EXTM3U #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1280000 http://example.com/low.m3u8 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2560000 http://example.com/mid.m3u8 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=7680000 http://example.com/hi.m3u8 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=65000,CODECS="mp4a.40.5" http://example.com/audio-only.m3u8
Example ¶
Create new master playlist Add media playlist Encode structures to HLS
package main
import (
"fmt"
"github.com/ShevaXu/hls"
)
func main() {
m := hls.NewMasterPlaylist()
p, _ := hls.NewMediaPlaylist(3, 5)
for i := 0; i < 5; i++ {
p.Append(hls.QuickSegment(fmt.Sprintf("test%d.ts", i), "", 5.0))
}
m.Append("chunklist1.m3u8", p, hls.VariantParams{ProgramID: 123, Bandwidth: 1500000, Resolution: "576x480"})
m.Append("chunklist2.m3u8", p, hls.VariantParams{ProgramID: 123, Bandwidth: 1500000, Resolution: "576x480"})
fmt.Printf("%s", m)
}
Output: #EXTM3U #EXT-X-VERSION:3 #EXT-X-STREAM-INF:PROGRAM-ID=123,BANDWIDTH=1500000,RESOLUTION=576x480 chunklist1.m3u8 #EXT-X-STREAM-INF:PROGRAM-ID=123,BANDWIDTH=1500000,RESOLUTION=576x480 chunklist2.m3u8
func NewMasterPlaylist ¶
func NewMasterPlaylist() *MasterPlaylist
NewMasterPlaylist creates a new empty master playlist.
func (*MasterPlaylist) Append ¶
func (p *MasterPlaylist) Append(uri string, chunklist *MediaPlaylist, params VariantParams)
Append appends variant to master playlist. This operation does reset playlist cache.
func (*MasterPlaylist) Decode ¶
func (p *MasterPlaylist) Decode(data bytes.Buffer, strict bool) error
Decode parses a master playlist passed from the buffer. If `strict` parameter is true then it returns first syntax error.
func (*MasterPlaylist) DecodeFrom ¶
func (p *MasterPlaylist) DecodeFrom(reader io.Reader, strict bool) error
DecodeFrom parses a master playlist passed from the io.Reader stream. If `strict` parameter is true then it returns first syntax error.
func (*MasterPlaylist) Encode ¶
func (p *MasterPlaylist) Encode() *bytes.Buffer
Encode generates the output in M3U8 format.
func (*MasterPlaylist) ResetCache ¶
func (p *MasterPlaylist) ResetCache()
ResetCache resets the underlying bytes buffer.
func (*MasterPlaylist) SetVersion ¶
func (p *MasterPlaylist) SetVersion(ver int)
SetVersion sets the playlist version number, note the version maybe changed automatically by other Set methods.
func (*MasterPlaylist) String ¶
func (p *MasterPlaylist) String() string
String returns the encoded buffer in string format, which implements the Stringer interface for Printf-like func.
func (*MasterPlaylist) Version ¶
func (p *MasterPlaylist) Version() int
Version returns the current playlist version number
type MediaPlaylist ¶
type MediaPlaylist struct {
TargetDuration float64
SeqNo int // EXT-X-MEDIA-SEQUENCE
Segments []*MediaSegment
Args string // optional arguments placed after URIs (URI?Args)
Iframe bool // EXT-X-I-FRAMES-ONLY
Closed bool // is this VOD (closed) or Live (sliding) playlist?
MediaType MediaType
Key *Key // EXT-X-KEY is optional encryption key displayed before any segments (default key for the playlist)
Map *Map // EXT-X-MAP is optional tag specifies how to obtain the Media Initialization Section (default map for the playlist)
W *Widevine // Widevine related tags outside of M3U8 specs
// contains filtered or unexported fields
}
MediaPlaylist represents a single bitrate playlist aka media playlist.
It related to both a simple media playlists and a sliding window media playlists. URI lines in the Playlist point to media segments.
Simple Media Playlist file sample:
#EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:5220 #EXTINF:5219.2, http://media.example.com/entire.ts #EXT-X-ENDLIST
Sample of Sliding Window Media Playlist, using HTTPS:
#EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:8 #EXT-X-MEDIA-SEQUENCE:2680 #EXTINF:7.975, https://priv.example.com/fileSequence2680.ts #EXTINF:7.941, https://priv.example.com/fileSequence2681.ts #EXTINF:7.975, https://priv.example.com/fileSequence2682.ts
Example ¶
Create new media playlist Add two segments to media playlist Print it
package main
import (
"fmt"
"github.com/ShevaXu/hls"
)
func main() {
p, _ := hls.NewMediaPlaylist(0, 2)
p.Append(hls.QuickSegment("test01.ts", "", 5.0))
p.Append(hls.QuickSegment("test02.ts", "", 6.0))
fmt.Printf("%s\n", p)
}
Output: #EXTM3U #EXT-X-VERSION:3 #EXT-X-MEDIA-SEQUENCE:0 #EXT-X-TARGETDURATION:6 #EXTINF:5.000, test01.ts #EXTINF:6.000, test02.ts
func NewMediaPlaylist ¶
func NewMediaPlaylist(winsize, capacity int) (*MediaPlaylist, error)
NewMediaPlaylist creates a new media playlist structure. winsize defines how much items will displayed on playlist generation; capacity is total size of a playlist (and its underlying arrray).
func (*MediaPlaylist) Append ¶
func (p *MediaPlaylist) Append(seg *MediaSegment) error
Append appends a MediaSegment to the tail of chunk slice for a media playlist. This operation does reset playlist cache.
func (*MediaPlaylist) AppendWithAutoExtend ¶
func (p *MediaPlaylist) AppendWithAutoExtend(seg *MediaSegment) error
AppendWithAutoExtend appends a MediaSegment and auto extend the capacity if 2/3 full.
func (*MediaPlaylist) Close ¶
func (p *MediaPlaylist) Close()
Close adds end-list to the playlist.
Example ¶
Create new media playlist Add two segments to media playlist Print it
package main
import (
"fmt"
"github.com/ShevaXu/hls"
)
func main() {
p, _ := hls.NewMediaPlaylist(0, 2)
p.Append(hls.QuickSegment("test01.ts", "", 5.0))
p.Append(hls.QuickSegment("test02.ts", "", 6.0))
p.Close()
fmt.Printf("%s\n", p)
}
Output: #EXTM3U #EXT-X-VERSION:3 #EXT-X-MEDIA-SEQUENCE:0 #EXT-X-TARGETDURATION:6 #EXTINF:5.000, test01.ts #EXTINF:6.000, test02.ts #EXT-X-ENDLIST
func (*MediaPlaylist) Count ¶
func (p *MediaPlaylist) Count() int
Count returns the number of items that are currently in the media playlist.
func (*MediaPlaylist) Decode ¶
func (p *MediaPlaylist) Decode(data bytes.Buffer, strict bool) error
Decode parses a media playlist passed from the buffer. If `strict` parameter is true then return first syntax error.
func (*MediaPlaylist) DecodeFrom ¶
func (p *MediaPlaylist) DecodeFrom(reader io.Reader, strict bool) error
DecodeFrom parses a media playlist passed from the io.Reader stream. If `strict` parameter is true then it returns first syntax error.
Example ¶
package main
import (
"bufio"
"fmt"
"os"
"github.com/ShevaXu/hls"
)
func main() {
f, _ := os.Open("sample-playlists/media-playlist-with-oatcls-scte35.m3u8")
p, _, _ := hls.DecodeFrom(bufio.NewReader(f), true)
pp := p.(*hls.MediaPlaylist)
fmt.Print(pp)
}
Output: #EXTM3U #EXT-X-VERSION:3 #EXT-X-MEDIA-SEQUENCE:0 #EXT-X-TARGETDURATION:10 #EXT-OATCLS-SCTE35:/DAlAAAAAAAAAP/wFAUAAAABf+/+ANgNkv4AFJlwAAEBAQAA5xULLA== #EXT-X-CUE-OUT:15 #EXTINF:8.844, media0.ts #EXT-X-CUE-OUT-CONT:ElapsedTime=8.844,Duration=15,SCTE35=/DAlAAAAAAAAAP/wFAUAAAABf+/+ANgNkv4AFJlwAAEBAQAA5xULLA== #EXTINF:6.156, media1.ts #EXT-X-CUE-IN #EXTINF:3.844, media2.ts
func (*MediaPlaylist) DurationAsInt ¶
func (p *MediaPlaylist) DurationAsInt(yes bool)
DurationAsInt sets if the TargetDuration should be format to int.
Example ¶
Example of parsing a playlist with EXT-X-DISCONTINIUTY tag and output it with integer segment durations.
package main
import (
"bufio"
"fmt"
"os"
"github.com/ShevaXu/hls"
)
func main() {
f, _ := os.Open("sample-playlists/media-playlist-with-discontinuity.m3u8")
p, _, _ := hls.DecodeFrom(bufio.NewReader(f), true)
pp := p.(*hls.MediaPlaylist)
pp.DurationAsInt(true)
fmt.Printf("%s", pp)
}
Output: #EXTM3U #EXT-X-VERSION:3 #EXT-X-MEDIA-SEQUENCE:0 #EXT-X-TARGETDURATION:10 #EXTINF:10, ad0.ts #EXTINF:8, ad1.ts #EXT-X-DISCONTINUITY #EXTINF:10, movieA.ts #EXTINF:10, movieB.ts
func (*MediaPlaylist) Encode ¶
func (p *MediaPlaylist) Encode() *bytes.Buffer
Encode generate output in M3U8 format. It marshals `winsize` elements from bottom of the `segments` queue.
func (*MediaPlaylist) ExtendCapacity ¶
func (p *MediaPlaylist) ExtendCapacity() (err error)
ExtendCapacity extend current capacity to double, and move tail to pos of last end When Generate Vod Playlist, if append failed, can call this extend function to contine
func (*MediaPlaylist) Remove ¶
func (p *MediaPlaylist) Remove() (err error)
Remove current segment from the head of chunk slice form a media playlist. Useful for sliding playlists. This operation does reset playlist cache.
func (*MediaPlaylist) ResetCache ¶
func (p *MediaPlaylist) ResetCache()
ResetCache resets the playlist cache, so that next call on Encode() will regenerate playlist from the chunk slice.
func (*MediaPlaylist) SetDefaultKey ¶
func (p *MediaPlaylist) SetDefaultKey(method, uri, iv, keyformat, keyformatversions string) error
SetDefaultKey sets the encryption key appeared once in header of the playlist (pointer to MediaPlaylist.Key). The tag set applies for the whole list. It is useful when keys are not changed during playback.
func (*MediaPlaylist) SetDefaultMap ¶
func (p *MediaPlaylist) SetDefaultMap(uri string, limit, offset int)
SetDefaultMap sets the default Media Initialization Section values for playlist (pointer to MediaPlaylist.Map). It sets EXT-X-MAP tag for the whole playlist.
func (*MediaPlaylist) SetDiscontinuity ¶
func (p *MediaPlaylist) SetDiscontinuity() error
SetDiscontinuity sets the discontinuity-flag for the current media segment. EXT-X-DISCONTINUITY indicates an encoding discontinuity between the media segment that follows it and the one that preceded it (i.e. file format, number and type of tracks, encoding parameters, encoding sequence, timestamp sequence).
func (*MediaPlaylist) SetIframeOnly ¶
func (p *MediaPlaylist) SetIframeOnly()
SetIframeOnly marks medialist as consists of only I-frames (Intra frames). The tag set applies for the whole list.
func (*MediaPlaylist) SetKey ¶
func (p *MediaPlaylist) SetKey(method, uri, iv, keyformat, keyformatversions string) error
SetKey sets a encryption key for the current segment of media playlist (pointer to Segment.Key).
func (*MediaPlaylist) SetMap ¶
func (p *MediaPlaylist) SetMap(uri string, limit, offset int) error
SetMap sets a map for the current segment of media playlist (pointer to Segment.Map).
func (*MediaPlaylist) SetProgramDateTime ¶
func (p *MediaPlaylist) SetProgramDateTime(value time.Time) error
SetProgramDateTime sets the program date and time for the current media segment. EXT-X-PROGRAM-DATE-TIME tag associates the first sample of a media segment with an absolute date and/or time. It applies only to the current media segment. Date/time format is YYYY-MM-DDThh:mm:ssZ (ISO8601) and includes time zone.
func (*MediaPlaylist) SetRange ¶
func (p *MediaPlaylist) SetRange(limit, offset int) error
SetRange sets the limit and offset for the current media segment (EXT-X-BYTERANGE support for protocol version 4).
func (*MediaPlaylist) SetSCTE35 ¶
func (p *MediaPlaylist) SetSCTE35(scte35 *SCTE) error
SetSCTE35 sets the SCTE cue format for the current media segment
func (*MediaPlaylist) SetVersion ¶
func (p *MediaPlaylist) SetVersion(ver int)
SetVersion sets the playlist version number, note the version maybe changed automatically by other Set methods.
func (*MediaPlaylist) SetWinSize ¶
func (p *MediaPlaylist) SetWinSize(winsize int) error
SetWinSize overwrites the playlist's window size.
func (*MediaPlaylist) Slide ¶
func (p *MediaPlaylist) Slide(seg *MediaSegment) (err error)
Slide first removes one chunk from the head if winsize full, then appends one chunk to the tail. Useful for sliding/live playlists. This operation does reset cache.
func (*MediaPlaylist) String ¶
func (p *MediaPlaylist) String() string
String returns the encoded buffer in string format, which implements the Stringer interface for Printf-like func.
func (*MediaPlaylist) Version ¶
func (p *MediaPlaylist) Version() int
Version returns the current playlist version number
func (*MediaPlaylist) WinSize ¶
func (p *MediaPlaylist) WinSize() int
WinSize returns the playlist's window size.
type MediaSegment ¶
type MediaSegment struct {
SeqID int
Title string // optional second parameter for EXTINF tag
URI string
Duration float64 // first parameter for EXTINF tag; duration must be integers if protocol version is less than 3 but we are always keep them float
Limit int // EXT-X-BYTERANGE <n> is length in bytes for the file under URI
Offset int // EXT-X-BYTERANGE [@o] is offset from the start of the file under URI
Key *Key // EXT-X-KEY displayed before the segment and means changing of encryption key (in theory each segment may have own key)
Map *Map // EXT-X-MAP displayed before the segment
Discontinuity bool // EXT-X-DISCONTINUITY indicates an encoding discontinuity between the media segment that follows it and the one that preceded it (i.e. file format, number and type of tracks, encoding parameters, encoding sequence, timestamp sequence)
SCTE *SCTE // SCTE-35 used for Ad signaling in HLS
ProgramDateTime time.Time // EXT-X-PROGRAM-DATE-TIME tag associates the first sample of a media segment with an absolute date and/or time
}
MediaSegment represents a media segment included in a media playlist. Media segment may be encrypted. Widevine supports own tags for encryption metadata.
func QuickSegment ¶
func QuickSegment(uri, title string, duration float64) *MediaSegment
QuickSegment returns a segment ready to append.
type Playlist ¶
type Playlist interface {
Encode() *bytes.Buffer
Decode(bytes.Buffer, bool) error
DecodeFrom(reader io.Reader, strict bool) error
String() string
}
Playlist abstracts various playlist types.
type SCTE ¶
type SCTE struct {
Syntax SCTE35Syntax // Syntax defines the format of the SCTE-35 cue tag
CueType SCTE35CueType // CueType defines whether the cue is a start, mid, end (if applicable)
Cue string
ID string
Time float64
Elapsed float64
}
SCTE holds custom, non EXT-X-DATERANGE, SCTE-35 tags
type SCTE35CueType ¶
type SCTE35CueType int
SCTE35CueType defines the type of cue point, used by readers and writers to write a different syntax
const ( SCTE35CueStart SCTE35CueType = iota // SCTE35CueStart indicates an out cue point SCTE35CueMid // SCTE35CueMid indicates a segment between start and end cue points SCTE35CueEnd // SCTE35CueEnd indicates an in cue point )
Cue types defined
type SCTE35Syntax ¶
type SCTE35Syntax int
SCTE35Syntax defines the format of the SCTE-35 cue points which do not use the draft-pantos-http-live-streaming-19 EXT-X-DATERANGE tag and instead have their own custom tags
const ( // Syntax672014 will be the default due to backwards compatibility reasons. // (defined in http://www.scte.org/documents/pdf/standards/SCTE%2067%202014.pdf) Syntax672014 SCTE35Syntax = iota // SyntaxOATCLS is a non-standard but common format SyntaxOATCLS )
type Variant ¶
type Variant struct {
URI string
Chunklist *MediaPlaylist
VariantParams
}
Variant represents variants for master playlist. Variants included in a master playlist and point to media playlists.
type VariantParams ¶
type VariantParams struct {
ProgramID int
Bandwidth int
Codecs string
Resolution string
Audio string // EXT-X-STREAM-INF only
Video string
Subtitles string // EXT-X-STREAM-INF only
Captions string // EXT-X-STREAM-INF only
Name string // EXT-X-STREAM-INF only (non standard Wowza/JWPlayer extension to name the variant/quality in UA)
Iframe bool // EXT-X-I-FRAME-STREAM-INF
Alternatives []*Alternative // EXT-X-MEDIA
}
VariantParams represents additional parameters for a variant used in EXT-X-STREAM-INF and EXT-X-I-FRAME-STREAM-INF
type Widevine ¶
type Widevine struct {
AudioChannels int
AudioFormat int
AudioProfileIDC int
AudioSampleSize int
AudioSamplingFrequency int
CypherVersion string
ECM string
VideoFormat int
VideoFrameRate int
VideoLevelIDC int
VideoProfileIDC int
VideoResolution string
VideoSAR string
}
Widevine represents metadata for Google Widevine playlists. This format not described in IETF draft but provied by Widevine Live Packager as additional tags with #Widevine-prefix.