-
Notifications
You must be signed in to change notification settings - Fork 317
/
storageStreamHLS.go
85 lines (79 loc) · 2.5 KB
/
storageStreamHLS.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
package main
import (
"sort"
"strconv"
"time"
"github.com/deepch/vdk/av"
)
// StreamHLSAdd add hls seq to buffer
func (obj *StorageST) StreamHLSAdd(uuid string, channelID string, val []*av.Packet, dur time.Duration) {
obj.mutex.Lock()
defer obj.mutex.Unlock()
if tmp, ok := obj.Streams[uuid]; ok {
if channelTmp, ok := tmp.Channels[channelID]; ok {
channelTmp.hlsSegmentNumber++
channelTmp.hlsSegmentBuffer[channelTmp.hlsSegmentNumber] = SegmentOld{data: val, dur: dur}
channelTmp.hlsLastDur = int(dur.Seconds())
if len(channelTmp.hlsSegmentBuffer) >= 6 {
delete(channelTmp.hlsSegmentBuffer, channelTmp.hlsSegmentNumber-5)
channelTmp.hlsSequence++
}
tmp.Channels[channelID] = channelTmp
obj.Streams[uuid] = tmp
}
}
}
// StreamHLSm3u8 get hls m3u8 list
func (obj *StorageST) StreamHLSm3u8(uuid string, channelID string) (string, int, error) {
obj.mutex.RLock()
defer obj.mutex.RUnlock()
if tmp, ok := obj.Streams[uuid]; ok {
if channelTmp, ok := tmp.Channels[channelID]; ok {
var out string
//TODO fix it
out += "#EXTM3U\r\n#EXT-X-TARGETDURATION:" + strconv.Itoa(channelTmp.hlsLastDur) + "\r\n#EXT-X-VERSION:4\r\n#EXT-X-MEDIA-SEQUENCE:" + strconv.Itoa(channelTmp.hlsSequence) + "\r\n"
var keys []int
for k := range channelTmp.hlsSegmentBuffer {
keys = append(keys, k)
}
sort.Ints(keys)
var count int
for _, i := range keys {
if i == 2 {
out += "#EXT-X-DISCONTINUITY\r\n"
}
count++
out += "#EXTINF:" + strconv.FormatFloat(channelTmp.hlsSegmentBuffer[i].dur.Seconds(), 'f', 1, 64) + ",\r\nsegment/" + strconv.Itoa(i) + "/file.ts\r\n"
}
return out, count, nil
}
}
return "", 0, ErrorStreamNotFound
}
// StreamHLSTS send hls segment buffer to clients
func (obj *StorageST) StreamHLSTS(uuid string, channelID string, seq int) ([]*av.Packet, error) {
obj.mutex.RLock()
defer obj.mutex.RUnlock()
if tmp, ok := obj.Streams[uuid]; ok {
if channelTmp, ok := tmp.Channels[channelID]; ok {
if tmp, ok := channelTmp.hlsSegmentBuffer[seq]; ok {
return tmp.data, nil
}
}
}
return nil, ErrorStreamNotFound
}
// StreamHLSFlush delete hls cache
func (obj *StorageST) StreamHLSFlush(uuid string, channelID string) {
obj.mutex.Lock()
defer obj.mutex.Unlock()
if tmp, ok := obj.Streams[uuid]; ok {
if channelTmp, ok := tmp.Channels[channelID]; ok {
channelTmp.hlsSegmentBuffer = make(map[int]SegmentOld)
channelTmp.hlsSegmentNumber = 0
channelTmp.hlsSequence = 0
tmp.Channels[channelID] = channelTmp
obj.Streams[uuid] = tmp
}
}
}