-
Notifications
You must be signed in to change notification settings - Fork 0
/
io.go
95 lines (81 loc) · 2.06 KB
/
io.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
package ffmpeg
import (
"bufio"
"bytes"
"io"
"regexp"
"strings"
)
var (
progPtrn = regexp.MustCompile(`^([^=]+)=\s*([^\s]+)$`)
statsPtrn = regexp.MustCompile(`^frame=\s*[^\s]+\s+fps=\s*[^\s]+\s+q=\s*[^\s]+\s+L?size=\s*[^\s]+\s+time=\s*[^\s]+\s+bitrate=\s*[^\s]+\s+speed=\s*[^\s]+$`)
finalStatsPtrn = regexp.MustCompile(`^video:[^\s]+\s+audio:[^\s]+\s+subtitle:[^\s]+\s+other\s+streams:[^\s]+\s+global\s+headers:[^\s]+\s+muxing\s+overhead:\s+[^\s]+$`)
repeatPtrn = regexp.MustCompile(`^Last message repeated`)
)
type filterReader struct {
scanner *bufio.Scanner
patterns []*regexp.Regexp
text string
pattern *regexp.Regexp
err error
}
func newFilterReader(reader io.Reader, patterns ...*regexp.Regexp) *filterReader {
fr := &filterReader{
scanner: bufio.NewScanner(reader),
patterns: patterns,
}
fr.scanner.Split(scanLines)
return fr
}
func (fr *filterReader) Scan() bool {
ok := fr.scanner.Scan()
fr.pattern = nil
fr.text = strings.TrimSpace(fr.scanner.Text())
for _, pattern := range fr.patterns {
if pattern.MatchString(fr.text) {
fr.pattern = pattern
}
}
fr.err = fr.scanner.Err()
if !ok && fr.err == nil {
fr.err = io.EOF
}
return ok
}
func (fr *filterReader) Pattern() *regexp.Regexp {
return fr.pattern
}
func (fr *filterReader) Text() string {
return fr.text
}
func (fr *filterReader) Bytes() []byte {
return []byte(fr.text)
}
func (fr *filterReader) Err() error {
return fr.err
}
func scanLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
if atEOF && len(data) == 0 {
return 0, nil, nil
}
if i := bytes.IndexByte(data, '\r'); i >= 0 {
if i < len(data)-2 {
return i + 1, data[0:i], nil
}
}
if i := bytes.IndexByte(data, '\n'); i >= 0 {
if data[i-1] == '\r' {
return i + 1, data[0 : i-1], nil
}
return i + 1, data[0:i], nil
}
// If we're at EOF, we have a final, non-terminated line. Return it.
if atEOF {
if data[len(data)-1] == '\r' {
return len(data), data[0 : len(data)-1], nil
}
return len(data), data, nil
}
// Request more data.
return 0, nil, nil
}