zhangmeng
2019-07-19 a55bcd63caf8db05459bb46279634985ba273f6d
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
package capture
 
import (
    "errors"
    "fmt"
    "image"
    "time"
 
    "basic.com/valib/goffmpeg.git"
    "gocv.io/x/gocv"
)
 
// StreamMode stream mode
type StreamMode int
 
const (
    // Rtsp mode
    Rtsp = StreamMode(iota)
    // GB28181 mode
    GB28181
)
 
// PicExt file extention
type PicExt string
 
const (
    // PNGFileExt png
    PNGFileExt PicExt = PicExt(gocv.PNGFileExt)
    // JPEGFileExt jpeg
    JPEGFileExt PicExt = PicExt(gocv.JPEGFileExt)
    // GIFFileExt gif
    GIFFileExt PicExt = PicExt(gocv.GIFFileExt)
    // InvalidFileExt invalid
    InvalidFileExt PicExt = PicExt("")
)
 
// Capture pic
func Capture(soFile string, m StreamMode, url string, ext PicExt, w, h, maxTry int) ([]byte, error) {
    gb := false
    if m == GB28181 {
        gb = true
    } else {
        return nil, errors.New("there is no this mode, try capture.Rtsp/capture.GB28181")
    }
 
    if ext == InvalidFileExt {
        ext = JPEGFileExt
    }
    var ret []byte
    var err error
 
    err = goffmpeg.InitFFmpeg(soFile)
    if err != nil {
        return nil, err
    }
 
    conf := goffmpeg.Config{
        Scale:  goffmpeg.ScalePoint,
        Width:  w,
        Height: h,
        GB:     gb,
        CPU:    true,
    }
    gf := goffmpeg.New(conf)
 
    ret, err = capt2Data(gf, url, gocv.FileExt(ext), w, h, maxTry)
 
    gf.Free()
    goffmpeg.FreeFFmpeg()
 
    return ret, err
}
 
func capt2Data(gf *goffmpeg.GoFFMPEG, url string, ext gocv.FileExt, w, h, maxTry int) ([]byte, error) {
 
    gf.Run(url)
    gf.BuildDecoder()
 
    tryTime := 0
 
    var picData []byte
    var err2 error
    for {
 
        data, wid, hei := gf.GetPicDecoder()
        if wid > 0 && hei > 0 {
            img, err := gocv.NewMatFromBytes(hei, wid, gocv.MatTypeCV8UC3, data)
            if err != nil {
                continue
            }
            pic := img
            if w >= 0 && h >= 0 {
                pic = gocv.NewMatWithSize(h, w, gocv.MatTypeCV8UC3)
                gocv.Resize(img, &pic, image.Pt(w, h), 0, 0, gocv.InterpolationDefault)
            }
            picData, err2 = gocv.IMEncode(ext, pic)
            if err2 != nil {
                continue
            }
            break
        } else {
            tryTime++
            if tryTime > maxTry {
                break
            }
            time.Sleep(time.Second)
        }
    }
 
    if tryTime > maxTry {
        err := fmt.Sprintf("try %d times to capture image, is url correct?\n", tryTime)
        return nil, errors.New(err)
    }
 
    return picData, nil
}