Gocv+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)
图像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)
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"))
通过websocket广播
mg:=websocket.Message{
	Body:[]byte(urldata),
	IsNative:true,
}
ws.Broadcast(nil,mg)

完整代码

这里贴出完整代码,也可以到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"))
}
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>

效果图

效果图

参考

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

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ango_Cango

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值