-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathoutput.go
121 lines (99 loc) · 2.39 KB
/
output.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
package main
import (
"fmt"
"strconv"
"time"
"github.com/3d0c/gmf"
gocache "github.com/patrickmn/go-cache"
)
type yalsaPoint struct {
TimeStamp int `json:"timestamp_ms"`
KeyFrame int `json:"keyframes"`
BitRate int `json:"bitrate"`
F1 int `json:"avg_fps_1s"`
F10 int `json:"avg_fps_10s"`
F100 int `json:"avg_fps_100s"`
SourceRetries int `json:"source_retries"`
}
var (
framesCache = gocache.New(time.Minute*2, time.Second)
pointsCache = gocache.New(time.Hour*24, time.Second)
lastPointKey = ""
)
func savePoints() {
pointsCache.SaveFile(fmt.Sprintf("yasla_%d.data", *port))
}
func loadPoints() error {
return pointsCache.LoadFile(fmt.Sprintf("yasla_%d.data", *port))
}
func count() {
frames := framesCache.Items()
timeNow := time.Now()
f1, f10, f100 := 0, 0, 0
keyframe := 0
bitrate := 0
var f100Diff time.Duration
for t, f := range frames {
it, _ := strconv.ParseInt(t, 10, 64)
ft := time.Unix(it/int64(time.Second), it%int64(time.Second))
frame := f.Object.(*yalsaFrame)
if frame.MediaType != gmf.AVMEDIA_TYPE_VIDEO {
continue
}
if timeNow.Sub(ft) < time.Second {
f1++
if frame.Keyframe {
keyframe++
}
bitrate += frame.Size
}
if timeNow.Sub(ft) < time.Second*10 {
f10++
}
if timeNow.Sub(ft) < time.Second*100 {
if timeNow.Sub(ft) > f100Diff {
f100Diff = timeNow.Sub(ft)
}
f100++
}
}
f10 /= 10
if int(f100Diff/time.Second) > 0 {
f100 /= int(f100Diff / time.Second)
}
tms := time.Now().UnixNano() / int64(time.Millisecond)
lastPointKey = fmt.Sprint(tms)
pointsCache.SetDefault(lastPointKey, &yalsaPoint{
TimeStamp: int(tms),
KeyFrame: keyframe,
BitRate: bitrate * 8 / 1024,
F1: f1,
F10: f10,
F100: f100,
SourceRetries: sourceRetries,
})
}
func output(streamInfoChan chan *yalsaFrame) {
startTime := time.Now()
t := time.NewTicker(time.Second)
for {
select {
case f := <-streamInfoChan:
if time.Now().Sub(startTime) > 1*time.Second {
framesCache.Add(fmt.Sprint(time.Now().UnixNano()), f, 0)
}
case <-t.C:
count()
var point *yalsaPoint
v, ok := pointsCache.Get(lastPointKey)
if ok {
point = v.(*yalsaPoint)
} else {
point = &yalsaPoint{}
}
fmt.Printf("[%s] %3d %3d %3d %5dK %2d\n",
time.Now().Format("0102T15:04:05.000Z07"),
point.F1, point.F10, point.F100, point.BitRate, point.KeyFrame)
}
}
}