为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕运维8079593 2022-06-27 10:41:36
我有下面的代码读取 cam 并将其显示在 GUI 窗口中,我想将相同的东西推送到我的服务器 url localhost:8080/cam,我该怎么做?package mainimport (    "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        }    }}
查看完整描述

1 回答

?
泛舟湖上清波郎朗

TA贡献1818条经验 获得超3个赞

我找到了这个包的解决方案,这个包的一个分支


package mjpeg


import (

    "fmt"

    "log"

    "net/http"

    "sync"

    "time"

)


// Stream represents a single video feed.

type Stream struct {

    m             map[chan []byte]bool

    frame         []byte

    lock          sync.Mutex

    FrameInterval time.Duration

}


const boundaryWord = "MJPEGBOUNDARY"

const headerf = "\r\n" +

    "--" + boundaryWord + "\r\n" +

    "Content-Type: image/jpeg\r\n" +

    "Content-Length: %d\r\n" +

    "X-Timestamp: 0.000000\r\n" +

    "\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) {

    log.Println("Stream:", r.RemoteAddr, "connected")

    w.Header().Add("Content-Type", "multipart/x-mixed-replace;boundary="+boundaryWord)


    c := make(chan []byte)

    s.lock.Lock()

    s.m[c] = true

    s.lock.Unlock()


    for {

        time.Sleep(s.FrameInterval)

        b := <-c

        _, err := w.Write(b)

        if err != nil {

            break

        }

    }


    s.lock.Lock()

    delete(s.m, c)

    s.lock.Unlock()

    log.Println("Stream:", r.RemoteAddr, "disconnected")

}


// UpdateJPEG pushes a new JPEG frame onto the clients.

func (s *Stream) UpdateJPEG(jpeg []byte) {

    header := fmt.Sprintf(headerf, len(jpeg))

    if len(s.frame) < len(jpeg)+len(header) {

        s.frame = make([]byte, (len(jpeg)+len(header))*2)

    }


    copy(s.frame, header)

    copy(s.frame[len(header):], jpeg)


    s.lock.Lock()

    for c := range s.m {

        // Select to skip streams which are sleeping to drop frames.

        // This might need more thought.

        select {

        case c <- s.frame:

        default:

        }

    }

    s.lock.Unlock()

}


// NewStream initializes and returns a new Stream.

func NewStream() *Stream {

    return &Stream{

        m:             make(map[chan []byte]bool),

        frame:         make([]byte, len(headerf)),

        FrameInterval: 50 * time.Millisecond,

    }

}

我的任何运行代码是:


package main


import (

    "fmt"

    "log"

    "net/http"


    "github.com/hybridgroup/mjpeg"

    _ "github.com/hybridgroup/mjpeg"

    "gocv.io/x/gocv"

)


func main() {

    deviceID := 0

    webcam, err := gocv.OpenVideoCapture(deviceID)

    if err != nil {

        fmt.Printf("Error opening video capture device: %v\n", deviceID)

        return

    }


    // create the mjpeg stream

    stream := mjpeg.NewStream()


    // start capturing

    go func(webcam *gocv.VideoCapture, stream *mjpeg.Stream) {

        defer webcam.Close()


        window := gocv.NewWindow("Capture Window")

        defer window.Close()


        img := gocv.NewMat()

        defer img.Close()


        fmt.Printf("Start reading device: %v\n", deviceID)

        for {

            if ok := webcam.Read(&img); !ok {

                fmt.Printf("Device closed: %v\n", deviceID)

                return

            }

            if img.Empty() {

                continue

            }

            buf, _ := gocv.IMEncode(".jpg", img)

            stream.UpdateJPEG(buf)

            window.IMShow(img)

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

                break

            }

        }

    }(webcam, stream)


    http.Handle("/", stream)

    log.Fatal(http.ListenAndServe(":8080", nil))

}


查看完整回答
反对 回复 2022-06-27
  • 1 回答
  • 0 关注
  • 100 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信