package service import ( "bytes" "context" "decoder/valib/goffmpeg" "decoder/valib/ipc" "encoding/gob" "fmt" ) // Decoder decoder ingo type Decoder struct { ctxIPC *ContextIPC cameraID string streamURL string ipcURL string ffmpeg *goffmpeg.GoFFMPEG } // NewDecoder decoder func NewDecoder(cameraID, streamURL, ipcURL string) *Decoder { ctx, cancel := context.WithCancel(context.Background()) return &Decoder{ ctxIPC: &ContextIPC{ctx, cancel}, cameraID: cameraID, streamURL: streamURL, ipcURL: ipcURL, } } func (dec *Decoder) serializeImageInfo(img <-chan ImageInfo, data chan<- []byte) { for { select { case <-dec.ctxIPC.ctx.Done(): fmt.Println("stop decoder") return case i := <-img: var buf bytes.Buffer enc := gob.NewEncoder(&buf) if err := enc.Encode(i); err != nil { fmt.Println("gob encode camera image error", err) continue } b := buf.Bytes() data <- b } } } // Run run a decoder func (dec *Decoder) Run(asServer bool) { var i *ipc.IPC if asServer { i = ipc.NewServer(dec.ctxIPC.ctx, dec.ipcURL) } else { i = ipc.NewClient(dec.ctxIPC.ctx, dec.ipcURL) } gf := goffmpeg.New() if gf != nil { dec.ffmpeg = gf } imageChan := make(chan ImageInfo) dataChan := make(chan []byte) go dec.serializeImageInfo(imageChan, dataChan) // str := "hello" gf.ActiveDecoder(func(d *[]byte, w, h *int) { if *w > 0 && *h > 0 { i := ImageInfo{*d, *w, *h, dec.cameraID} imageChan <- i } else { fmt.Println("decode jpg error") } }) gf.Run(dec.streamURL) i.SendFromChannel(dataChan) } // Stop stop run decoder, must run in goroutine func (dec *Decoder) Stop() { dec.ffmpeg.Free() dec.ctxIPC.cancel() }