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

本文记录了一次使用JS调用摄像头,通过WebRTC获取视频流并尝试实时上传的试验过程。作者遇到的问题是每100ms抓取的一帧800*800 png图片大小约2MB,导致上传不切实际。后端使用Go接收websocket消息并解码。由于问题,作者决定转向研究RTMP技术。
摘要由CSDN通过智能技术生成

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 CanvasRenderingContext2D

    let video = (this.refs.video as HTMLVideoElement)
     navigator.getUserMedia({
   video: true},
      (stream: MediaStream) => {
   
              video.srcObject = stream
        video.play()
        // upload stream to server
        let ws = this.initWebSocket(
          () => {
   
            console.log('start send frames')
     
由于涉及到浏览器的安全限制,前端无法直接调用摄像头实时上传视频数据。一般情况下,需要使用浏览器提供的WebRTC API来实现。 以下是一个使用WebRTC API实现视频采集并上传的完整代码例子: HTML代码: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>WebRTC视频采集与上传</title> </head> <body> <video id="video" width="640" height="480" autoplay></video> <button id="startButton">开始采集</button> <button id="stopButton">停止采集</button> <script src="main.js"></script> </body> </html> ``` JavaScript代码: ```javascript // 获取DOM元素 const video = document.getElementById('video'); const startButton = document.getElementById('startButton'); const stopButton = document.getElementById('stopButton'); let stream; // 存储视频流 // 获取视频流 function getMediaStream() { // 判断浏览器是否支持WebRTC API if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) { alert('您的浏览器不支持WebRTC API!'); return; } // 获取视频流 navigator.mediaDevices.getUserMedia({ video: true, // 开启视频 audio: false // 禁用音频 }).then(function (mediaStream) { // 将视频流绑定到video元素中 video.srcObject = mediaStream; stream = mediaStream; }).catch(function (error) { console.error('获取视频流出错:', error); }); } // 停止视频采集 function stopMediaStream() { if (stream) { stream.getTracks().forEach(function (track) { track.stop(); }); } } // 开始采集视频 startButton.addEventListener('click', function () { getMediaStream(); }); // 停止采集视频 stopButton.addEventListener('click', function () { stopMediaStream(); }); ``` 上述代码实现了获取视频流,并将视频流绑定到video元素中。如果需要上传视频数据,可以在获取视频流成功回调中获取到视频数据,并通过ajax等方式上传到服务器。具体实现方式可以根据具体需求进行调整。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值