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 if m != Rtsp { 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 }