Gocv+websocket實現視訊直播
阿新 • • 發佈:2022-03-06
文章目錄
資料流向圖
實現方式
- 通過opencv抓取攝像頭的視訊資料按幀處理
- 將每一幀壓縮成jpg格式並編碼成base64格式
- 通過websocket協議將base64影象傳輸給前端頁面
- 前端解析每一幀並更新顯示
本文使用了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