如何将视频捕获流式传输到网络

我有下面的代码读取 cam 并将其显示在 GUI 窗口中,我想将相同的东西推送到我的服务器 url localhost:8080/cam,我该怎么做?


package main


import (

    "gocv.io/x/gocv"

)


func main() {

    webcam, _ := gocv.VideoCaptureDevice(0)

    defer webcam.Close() // Close the cam once execution completed

    window := gocv.NewWindow("Hello")

    defer window.Close() // Close the GUI once execution completed, though it is done automatically

    img := gocv.NewMat()

    defer img.Close() // Close the img once execution completed


    for {

        webcam.Read(&img)

        window.IMShow(img)

        // Want to do streaming here to localhost:8080/cam

        if window.WaitKey(1) == 27 { // 27 => Esc

            break

        }

    }

}


慕运维8079593
浏览 101回答 1
1回答

泛舟湖上清波郎朗

我找到了这个包的解决方案,这个包的一个分支package mjpegimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "log"&nbsp; &nbsp; "net/http"&nbsp; &nbsp; "sync"&nbsp; &nbsp; "time")// Stream represents a single video feed.type Stream struct {&nbsp; &nbsp; m&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;map[chan []byte]bool&nbsp; &nbsp; frame&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[]byte&nbsp; &nbsp; lock&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sync.Mutex&nbsp; &nbsp; FrameInterval time.Duration}const boundaryWord = "MJPEGBOUNDARY"const headerf = "\r\n" +&nbsp; &nbsp; "--" + boundaryWord + "\r\n" +&nbsp; &nbsp; "Content-Type: image/jpeg\r\n" +&nbsp; &nbsp; "Content-Length: %d\r\n" +&nbsp; &nbsp; "X-Timestamp: 0.000000\r\n" +&nbsp; &nbsp; "\r\n"// ServeHTTP responds to HTTP requests with the MJPEG stream, implementing the http.Handler interface.func (s *Stream) ServeHTTP(w http.ResponseWriter, r *http.Request) {&nbsp; &nbsp; log.Println("Stream:", r.RemoteAddr, "connected")&nbsp; &nbsp; w.Header().Add("Content-Type", "multipart/x-mixed-replace;boundary="+boundaryWord)&nbsp; &nbsp; c := make(chan []byte)&nbsp; &nbsp; s.lock.Lock()&nbsp; &nbsp; s.m[c] = true&nbsp; &nbsp; s.lock.Unlock()&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; time.Sleep(s.FrameInterval)&nbsp; &nbsp; &nbsp; &nbsp; b := <-c&nbsp; &nbsp; &nbsp; &nbsp; _, err := w.Write(b)&nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; s.lock.Lock()&nbsp; &nbsp; delete(s.m, c)&nbsp; &nbsp; s.lock.Unlock()&nbsp; &nbsp; log.Println("Stream:", r.RemoteAddr, "disconnected")}// UpdateJPEG pushes a new JPEG frame onto the clients.func (s *Stream) UpdateJPEG(jpeg []byte) {&nbsp; &nbsp; header := fmt.Sprintf(headerf, len(jpeg))&nbsp; &nbsp; if len(s.frame) < len(jpeg)+len(header) {&nbsp; &nbsp; &nbsp; &nbsp; s.frame = make([]byte, (len(jpeg)+len(header))*2)&nbsp; &nbsp; }&nbsp; &nbsp; copy(s.frame, header)&nbsp; &nbsp; copy(s.frame[len(header):], jpeg)&nbsp; &nbsp; s.lock.Lock()&nbsp; &nbsp; for c := range s.m {&nbsp; &nbsp; &nbsp; &nbsp; // Select to skip streams which are sleeping to drop frames.&nbsp; &nbsp; &nbsp; &nbsp; // This might need more thought.&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case c <- s.frame:&nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; s.lock.Unlock()}// NewStream initializes and returns a new Stream.func NewStream() *Stream {&nbsp; &nbsp; return &Stream{&nbsp; &nbsp; &nbsp; &nbsp; m:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;make(map[chan []byte]bool),&nbsp; &nbsp; &nbsp; &nbsp; frame:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;make([]byte, len(headerf)),&nbsp; &nbsp; &nbsp; &nbsp; FrameInterval: 50 * time.Millisecond,&nbsp; &nbsp; }}我的任何运行代码是:package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "log"&nbsp; &nbsp; "net/http"&nbsp; &nbsp; "github.com/hybridgroup/mjpeg"&nbsp; &nbsp; _ "github.com/hybridgroup/mjpeg"&nbsp; &nbsp; "gocv.io/x/gocv")func main() {&nbsp; &nbsp; deviceID := 0&nbsp; &nbsp; webcam, err := gocv.OpenVideoCapture(deviceID)&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("Error opening video capture device: %v\n", deviceID)&nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; }&nbsp; &nbsp; // create the mjpeg stream&nbsp; &nbsp; stream := mjpeg.NewStream()&nbsp; &nbsp; // start capturing&nbsp; &nbsp; go func(webcam *gocv.VideoCapture, stream *mjpeg.Stream) {&nbsp; &nbsp; &nbsp; &nbsp; defer webcam.Close()&nbsp; &nbsp; &nbsp; &nbsp; window := gocv.NewWindow("Capture Window")&nbsp; &nbsp; &nbsp; &nbsp; defer window.Close()&nbsp; &nbsp; &nbsp; &nbsp; img := gocv.NewMat()&nbsp; &nbsp; &nbsp; &nbsp; defer img.Close()&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("Start reading device: %v\n", deviceID)&nbsp; &nbsp; &nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ok := webcam.Read(&img); !ok {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("Device closed: %v\n", deviceID)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if img.Empty() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buf, _ := gocv.IMEncode(".jpg", img)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stream.UpdateJPEG(buf)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; window.IMShow(img)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if window.WaitKey(1) == 27 { // 27 => Esc&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }(webcam, stream)&nbsp; &nbsp; http.Handle("/", stream)&nbsp; &nbsp; log.Fatal(http.ListenAndServe(":8080", nil))}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go