JS调用摄像头、实时视频流上传(一次不成功的试验)

思路

前端调用摄像头,获取视频流,从视频流中取一帧转图片,用websocket上传图片。

研究了一下发现了WebRTC这种技术,看到有博客说一些直播应用使用WebRTC将视频流发布到服务器上,然后用hls等技术在前端播放,但是我花了些时间还是没搞清楚WebRTC的原理,只能以后再尝试了。

1.前端代码

前端用的React+Typescript,所以这里贴出tsx代码。
逻辑比较简单,调用WebRTC的接口getUserMedia获取视频流,然后把stream绑定到video元素上,接下来设个clock,每100ms抓一次视频帧(fps=10),将其画到canvas上后就可以调canvas.toDataUrl把图片的位图数据编码成png格式,编码是必须的,因为编码后的数据一般比原始数据小一个数量级,节约带宽。也可以编码成其他格式,像jpeg或者webp,我对这些格式了解不多,可能压缩率最高的是webp。

其实到这一步已经出现问题了,800*800大小的png图片大小也近2M左右,这意味着一秒钟要上传10 * 2M = 20M的数据,十分不现实。没有测试过转webp格式,我觉得效果也不会太好,还是直接上传视频流比较好

export default class App extends React.Component<any, State> {componentDidMount() {let canvas = (this.refs.canvas as HTMLCanvasElement)let canvasContext = canvas.getContext('2d') as CanvasRenderingContext2Dlet video = (this.refs.video as HTMLVideoElement)navigator.getUserMedia({video: true},(stream: MediaStream) => {video.srcObject = streamvideo.play()// upload stream to serverlet ws = this.initWebSocket(() => {console.log('start send frames')setInterval(() => {canvasContext.drawImage(video, 0, 0, 800, 800)// TODO: check if ws is closedws.send(canvas.toDataURL('image/png', 1))}, 100) // 10 fps})}, (err: MediaStreamError) => console.error(err))}initWebSocket(onReady: () => void) {let ws = new WebSocket(format('ws://%s:%d/ws', config.server.host, config.server.port))ws.onopen = () => {console.log('websocket opened')onReady()}ws.onclose = () => console.log('websocket closed')return ws}render() {return (<Layout style={{display: 'block',height: '100%', width: '100%'}}><Layout.Header><Typography.Title style={{color: 'white', textShadow: '1px 1px 3px black'}}>Face Detect</Typography.Title></Layout.Header><Layout.Content style={{width: '60%', height: '100%', margin: '0px auto'}}><video ref='video' width={800} height={800} style={{border: '1px black solid'}}></video><canvas ref='canvas' width={800} height={800} style={{display: 'block', border: '1px black solid'}}></canvas></Layout.Content></Layout>)}
}

2.后端代码

后端用go写的,篇幅有限,搭建http服务和websocket相关的代码就不贴出来了。功能就是把从websocket接收到的每一条消息,从DataUrl解码成Image对象。

import ("bytes""encoding/base64""github.com/gorilla/websocket""image""image/png""net/http""github.com/Luncert/slog"
)func serverWs(w http.ResponseWriter, r *http.Request) {conn, err := upgrader.Upgrade(w, r, nil)if err != nil {log.Error(err)return}defer func() {_ = conn.Close()}()for {_, message, err := conn.ReadMessage()if err != nil {log.Error("read:", err)break}// 将DataUrl解码成png字节数据src := decodeDataUrl(message)// 调image/png库解码出Image对象img, err := png.Decode(bytes.NewReader(src))if err != nil {log.Fatal(err)}}
}func decodeDataUrl(raw []byte) []byte {// 去掉DataUrl中的元数据:从第一个字符到第一个','i := 0for raw[i] != ',' {i++}i++src := raw[i:]// 调base64解码后续数据maxLen := base64.StdEncoding.DecodedLen(len(src))dst := make([]byte, maxLen)if _, err := base64.StdEncoding.Decode(dst, src); err != nil {log.Fatal(err)}return dst
}

这个方案到此为止了,接下来转向Rtmp

JS调用摄像头、实时视频流上传(一次不成功的试验)相关推荐

  1. JS打开摄像头并截图上传

    直入正题,JS打开摄像头并截图上传至后端的一个完整步骤 1. 打开摄像头主要用到getUserMedia方法,然后将获取到的媒体流置入video标签 2. 截取图片主要用到canvas绘图,使用dra ...

  2. 在网页中调用摄像头实现拍照上传 - 高拍仪二次开发

    在网页中调用摄像头实现拍照上传 高拍仪二次开发     在一些公共部门的办事处,比如银行.护照办理中心.税务等,我们可能会注意到办公桌上摆着这样一台机器.办公人员用它拍摄各种证件.文件.表格,有时候还 ...

  3. c++ 二次开发 良田高拍仪_在网页中调用摄像头实现拍照上传 - 高拍仪二次开发...

    来源于  https://blog.csdn.net/weixin_40659738/article/details/78252562 在网页中调用摄像头实现拍照上传 高拍仪二次开发 在一些公共部门的 ...

  4. 前端js调用摄像头进行录像并传到后端

    js调用摄像头录像并传到后端 参考自https://juejin.im/entry/5b91e8e7f265da0ac55e2cd6?tdsourcetag=s_pcqq_aiomsg 项目要求前端h ...

  5. chrome摄像头java_Chrome 谷歌浏览器调用摄像头并拍照上传 java示例

    html页面: html5调用摄像头实现拍照 拍照 var video=document.getElementById("video"); var context=canvas.g ...

  6. web调用摄像头拍照并上传到服务器

    1.注意事项 1.网页对摄像头调用的限制比较高,要求网页必须https协议或者是要本地localhost(127.0.0.1)否则无法调用, 2.当你的网页协议是https请求的时候你向后端服务器发的 ...

  7. IE与非IE浏览器调用PC摄像头拍摄并且上传

     需要下载源码以及相关文件的可以到(不好意思,之前上传的不知道怎么回事就没了) http://download.csdn.net/detail/u013946285/9886280 中下载 一,f ...

  8. H5调用手机摄像头,实时拍照上传(旧)

    H5调用手机摄像头,完成拍照,实时上传(旧) 项目开发中,偶尔会遇到网页中调用手机摄像头,通过相册选择或直接实时拍照的方式,完成图片上传的功能型需求. 今天,就通过一个小的案例,演示一下完整的实现流程 ...

  9. 摄像头网页服务器,js调用本地摄像头拍照并上传到web服务器

    [实例简介] js调用本地摄像头拍照并上传到web服务器.后台使用java实现图片的接收和存储,上传的图片默认保存到项目下的images文件夹中. [实例截图] [核心代码] MyCamera └── ...

最新文章

  1. vivado 2018与modelsim的联合仿真
  2. 30分钟带你熟练性能优化的那点儿事儿(案例说明)
  3. Python-OpenCV 处理图像(六):对象识别
  4. Java普通对象的内存配置
  5. flex采用blazeds实现服务器向客户端推数据
  6. ASP.NET Core依赖注入初识与思考
  7. 使用引用的方式交换数据的数值
  8. linux iphone 同步时间,与iPad/iPhone同步
  9. python下俄罗斯方块的游戏设计_[源码和文档分享]基于Python的PyGame的俄罗斯方块游戏设计与实现...
  10. 堆积柱形图显示总数_送你一份堆积柱形图小点心,请收下~
  11. 网页中嵌入swf文件的几种方法
  12. 2019年软考程序员考试大纲
  13. 学习日记day36 平面设计 字体设计
  14. SCI论文图片拼接Tips
  15. 数学建模时序数据分析——趋势性检验和平稳性检验
  16. 可编程渲染管线(SRP)_学习笔记
  17. 展锋芒,一遇风云便化龙
  18. 树莓派裸板linux,树莓派裸机开发步骤
  19. TypeScript学习总结
  20. MATLAB画图必备知识

热门文章

  1. 智源社区AI周刊No.105:谷歌FLAN-T5 30亿参数即超越GPT-3性能;Copilot推出语音编程新功能,但面临诉讼...
  2. git master和main 的纠缠
  3. VS2017+OpenCV3.4.1
  4. Flask邮件的配置和使用
  5. 攻防世界——杂项(1-5)
  6. echarts世界地图,国家名称翻译
  7. python英语单词 扇贝英语安卓下载_扇贝单词英语版
  8. 谷歌浏览器开发者工具鼠标箭头变成小圆点了
  9. 阿里、百度、华为都用什么编程语言?做程序员前,这些别说不知道!
  10. 设计一个计算器,实现0-9数字间的加减乘除运算