当前位置:   article > 正文

Gocv+websocket实现视频直播_golang websocket 传输视频流

golang websocket 传输视频流

数据流向图

数据流

实现方式

  1. 通过opencv抓取摄像头的视频数据按帧处理
  2. 将每一帧压缩成jpg格式并编码成base64格式
  3. 通过websocket协议将base64图像传输给前端页面
  4. 前端解析每一帧并更新显示

本文使用了iris框架的websocket封装,因此opencv也使用了go语言的版本GoCV。

主要功能点

从摄像头获取视频数据
img:=gocv.NewMat()
camera,err:=gocv.VideoCaptureDevice(0)
camera.Read(&img)
  • 1
  • 2
  • 3
图像Base64编码
data,err:=gocv.IMEncode(".jpg",img)
n:=base64.StdEncoding.EncodedLen(len(data))
dst:=make([]byte,n)
base64.StdEncoding.Encode(dst,data)
urldata:="data:image/jpeg;base64,"+string(dst)
  • 1
  • 2
  • 3
  • 4
  • 5
Websocket服务
ws:=websocket.New(websocket.DefaultGorillaUpgrader,websocket.Events{
	websocket.OnNativeMessage:func(nsConn*websocket.NSConn,msgwebsocket.Message)error{
		log.Printf("Servergot:%sfrom[%s]",msg.Body,nsConn.Conn.ID())
		return nil
	},
})
app:=iris.New()
app.Get("/video",websocket.Handler(ws))
app.Run(iris.Addr(":8080"))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
通过websocket广播
mg:=websocket.Message{
	Body:[]byte(urldata),
	IsNative:true,
}
ws.Broadcast(nil,mg)
  • 1
  • 2
  • 3
  • 4
  • 5

完整代码

这里贴出完整代码,也可以到GitHub上查看
https://github.com/chenguan1/go-h5-video-demo

go
package main

import (
	"encoding/base64"
	"fmt"
	"github.com/kataras/iris/v12"
	"github.com/kataras/iris/v12/websocket"
	"gocv.io/x/gocv"
	"log"
	"time"
)

func main() {
	ws := websocket.New(websocket.DefaultGorillaUpgrader, websocket.Events{
		websocket.OnNativeMessage: func(nsConn *websocket.NSConn, msg websocket.Message) error {
			log.Printf("Server got: %s from [%s]", msg.Body, nsConn.Conn.ID())
			return nil
		},
	})

	ws.OnConnect = func(c *websocket.Conn) error {
		log.Printf("[%s] Connected to server!", c.ID())
		return nil
	}

	ws.OnDisconnect = func(c *websocket.Conn) {
		log.Printf("[%s] Disconnected from server", c.ID())
	}

	ws.OnUpgradeError = func(err error) {
		log.Printf("Upgrade Error: %v", err)
	}

	go func() {
		camera, err := gocv.VideoCaptureDevice(0)
		if err != nil {
			panic(err)
		}

		img := gocv.NewMat()

		for {
			camera.Read(&img)
			data, err := gocv.IMEncode(".jpg", img)
			if err != nil {
				fmt.Println(err)
			} else {
				n := base64.StdEncoding.EncodedLen(len(data))
				dst := make([]byte, n)
				base64.StdEncoding.Encode(dst, data)
				urldata := "data:image/jpeg;base64," + string(dst)
				mg := websocket.Message{
					Body:     []byte(urldata),
					IsNative: true,
				}
				ws.Broadcast(nil, mg)
			}
			time.Sleep(time.Millisecond * time.Duration(50))
		}
	}()

	app := iris.New()
	app.HandleDir("/", "./html")
	app.Get("/video", websocket.Handler(ws))

	app.Run(iris.Addr(":8080"))
}
  • 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
html5
<html>
<head>
    <title>video</title>
</head>
<body style="padding:10px;">
<img id="target" style="display:inline;"/>
<canvas id="canvas" style="display:inline;"/>
<script type="text/javascript">
    var HOST = "localhost:8080"

    w = new WebSocket("ws://" + HOST + "/video");
    w.onopen = function () {
        console.log("Websocket connection enstablished");
    };

    w.onclose = function () {
        console.log("Websocket disconnected");
    };

    var canvas = document.getElementById("canvas");
    var img = new Image()
    img.onload = function(){
        canvas.width = img.width
        canvas.height = img.height
        canvas.getContext("2d").drawImage(img,0,0,img.width,img.height);
    };
    w.onmessage = function (message) {
        img.src = message.data;
    };
</script>
</body>
</html>
  • 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

效果图

效果图

参考

https://github.com/kataras/iris/tree/v12/_examples/websocket

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/157583
推荐阅读
相关标签
  

闽ICP备14008679号