forked from grafov/m3u8
-
Notifications
You must be signed in to change notification settings - Fork 0
/
structure.go
291 lines (257 loc) · 9.47 KB
/
structure.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
package m3u8
/*
Part of M3U8 parser & generator library.
This file defines data structures related to package.
Copyleft 2013-2015 Alexander I.Grafov aka Axel <grafov@gmail.com>
Copyleft 2013-2015 library authors (see AUTHORS file).
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
ॐ तारे तुत्तारे तुरे स्व
*/
import (
"bytes"
"io"
"time"
)
const (
/*
Compatibility rules described in section 7:
Clients and servers MUST implement protocol version 2 or higher to use:
o The IV attribute of the EXT-X-KEY tag.
Clients and servers MUST implement protocol version 3 or higher to use:
o Floating-point EXTINF duration values.
Clients and servers MUST implement protocol version 4 or higher to use:
o The EXT-X-BYTERANGE tag.
o The EXT-X-I-FRAME-STREAM-INF tag.
o The EXT-X-I-FRAMES-ONLY tag.
o The EXT-X-MEDIA tag.
o The AUDIO and VIDEO attributes of the EXT-X-STREAM-INF tag.
*/
minver = uint8(3)
DATETIME = time.RFC3339Nano // Format for EXT-X-PROGRAM-DATE-TIME defined in section 3.4.5
)
type ListType uint
const (
// use 0 for not defined type
MASTER ListType = iota + 1
MEDIA
)
// for EXT-X-PLAYLIST-TYPE tag
type MediaType uint
const (
// use 0 for not defined type
EVENT MediaType = iota + 1
VOD
)
/*
This structure 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
*/
type MediaPlaylist struct {
TargetDuration float64
SeqNo uint64 // 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
durationAsInt bool // output durations as integers of floats?
keyformat int
winsize uint // max number of segments displayed in an encoded playlist; need set to zero for VOD playlists
capacity uint // total capacity of slice used for the playlist
head uint // head of FIFO, we add segments to head
tail uint // tail of FIFO, we remove segments from tail
count uint // number of segments added to the playlist
buf bytes.Buffer
ver uint8
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)
WV *WV // Widevine related tags outside of M3U8 specs
}
/*
This structure 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
*/
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)
buf bytes.Buffer
ver uint8
}
// This structure represents variants for master playlist.
// Variants included in a master playlist and point to media playlists.
type Variant struct {
URI string
Chunklist *MediaPlaylist
VariantParams
}
// This stucture represents additional parameters for a variant
// used in EXT-X-STREAM-INF and EXT-X-I-FRAME-STREAM-INF
type VariantParams struct {
ProgramId uint32
Bandwidth uint32
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
}
// This structure represents EXT-X-MEDIA tag in variants.
type Alternative struct {
GroupId string
URI string
Type string
Language string
Name string
Default bool
Autoselect string
Forced string
Characteristics string
Subtitles string
}
// This structure represents a media segment included in a media playlist.
// Media segment may be encrypted.
// Widevine supports own tags for encryption metadata.
type MediaSegment struct {
SeqId uint64
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 int64 // EXT-X-BYTERANGE <n> is length in bytes for the file under URI
Offset int64 // 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)
ProgramDateTime time.Time // EXT-X-PROGRAM-DATE-TIME tag associates the first sample of a media segment with an absolute date and/or time
// Cue related information
CueOut *CueOut // EXT-X-CUE-OUT displayed before the start of cue segments
CueIn *CueIn // EXT-X-CUE-IN displayed before the end of cue segments
CueSpan *CueSpan // EXT-X-CUE-SPAN displayed with segment between in and out.
}
// CueOut is EXT-X-CUE-OUT
type CueOut struct {
ID string
CueID string
Duration float64
}
// CueIn is EXT-X-CUE-IN
type CueIn struct {
ID string
CueID string
}
// CueSpan is EXT-X-CUE-SPAN
type CueSpan struct {
ID string
TimeFromSignal string
}
// This structure represents information about stream encryption.
//
// Realizes EXT-X-KEY tag.
type Key struct {
Method string
URI string
IV string
Keyformat string
Keyformatversions string
}
// This structure 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.
//
// Realizes EXT-MAP tag.
type Map struct {
URI string
Limit int64 // <n> is length in bytes for the file under URI
Offset int64 // [@o] is offset from the start of the file under URI
}
// This structure represents metadata for Google Widevine playlists.
// This format not described in IETF draft but provied by Widevine Live Packager as
// additional tags with #WV-prefix.
type WV struct {
AudioChannels uint
AudioFormat uint
AudioProfileIDC uint
AudioSampleSize uint
AudioSamplingFrequency uint
CypherVersion string
ECM string
VideoFormat uint
VideoFrameRate uint
VideoLevelIDC uint
VideoProfileIDC uint
VideoResolution string
VideoSAR string
}
// Interface applied to various playlist types.
type Playlist interface {
Encode() *bytes.Buffer
Decode(bytes.Buffer, bool) error
DecodeFrom(reader io.Reader, strict bool) error
String() string
}
// Internal structure for decoding a line of input stream with a list type detection
type decodingState struct {
listType ListType
m3u bool
tagWV bool
tagStreamInf bool
tagIframeStreamInf bool
tagInf bool
tagRange bool
tagDiscontinuity bool
tagProgramDateTime bool
tagKey bool
tagMap bool
programDateTime time.Time
limit int64
offset int64
duration float64
variant *Variant
xkey *Key
xmap *Map
}