/
m3u8.go
123 lines (99 loc) · 2.1 KB
/
m3u8.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
package zbox
import (
"bytes"
"io"
"sort"
"strconv"
"time"
)
// #EXTM3U
// #EXT-X-VERSION:3
// #EXT-X-TARGETDURATION:5
// #EXT-X-MEDIA-SEQUENCE:17
// #EXTINF:5.000000,
// tv17.ts
// #EXTINF:5.000000,
// tv18.ts
// #EXTINF:5.000000,
// tv19.ts
// #EXTINF:5.000000,
// tv20.ts
// #EXTINF:5.000000,
// tv21.ts
// MediaPlaylist m3u8 encoder and decoder
type MediaPlaylist struct {
delay int
Writer M3u8Writer
Wait []string
next chan string
Seq int
}
// M3u8Writer m3u8 writer
type M3u8Writer interface {
io.WriteSeeker
Truncate(size int64) error
Sync() error
}
// NewMediaPlaylist create media playlist(.m3u8)
func NewMediaPlaylist(delay int, writer M3u8Writer) *MediaPlaylist {
m3u8 := &MediaPlaylist{
delay: delay,
Wait: make([]string, 0, 100),
next: make(chan string, 100),
Seq: 0,
Writer: writer,
}
return m3u8
}
// Append append new item
func (m *MediaPlaylist) Append(item string) {
m.next <- item
}
// Play start to push item into playlist
func (m *MediaPlaylist) Play() {
for {
item := <-m.next
found := sort.Search(len(m.Wait), func(i int) bool {
return m.Wait[i] == item
})
if found != len(m.Wait) { // means found
continue
}
m.Wait = append(m.Wait, item)
m.flush()
time.Sleep(1 * time.Second)
}
}
// flush try flush new ts file into playlist
func (m *MediaPlaylist) flush() {
if len(m.Wait) == 0 {
return
}
m.Writer.Truncate(0)
m.Writer.Seek(0, 0)
m.Writer.Write(m.Encode())
m.Writer.Sync()
}
// Encode encode m3u8
func (m *MediaPlaylist) Encode() []byte {
var buf bytes.Buffer
if len(m.Wait) == 0 {
return buf.Bytes()
}
duration := strconv.Itoa(m.delay)
name := m.Wait[0]
sequience := strconv.Itoa(GetNumber(name))
buf.WriteString("#EXTM3U\n")
buf.WriteString("#EXT-X-VERSION:3\n")
buf.WriteString("#EXT-X-TARGETDURATION:" + duration + "\n")
buf.WriteString("#EXT-X-MEDIA-SEQUENCE:" + sequience + "\n")
for _, it := range m.Wait {
buf.WriteString("#EXTINF:" + duration + ",\n")
buf.WriteString(it + "\n")
}
return buf.Bytes()
}
// String implement Stringer
func (m *MediaPlaylist) String() string {
return string(m.Encode())
}