网页录制gb28181录像

Posted qianbo_insist

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网页录制gb28181录像相关的知识,希望对你有一定的参考价值。

网页编解码

网页已经可以编解码h264,h265 等等常规编码,我们可以使用网页来进行gb28181的录像和解码以及形成文件,当然以前也可以,不过现在更为简便。需求来自于客户端不再进行更新,而使用网页版本来制作gb28181的本地录像(非服务器录像),同时创建链接可以下载,格式位webm。
以下将使用两种方式来存储录像,1 是重新编码,可以叠加数据,2 是不重新编码,我们的格式是flv ,将flv demux后直接存储

方式1 使用VideoTrackReader 和MediaStreamTrackProcessor

VideoTrackReader 根据文档已经deprecated,现在比较新的chrome版本应该使用MediaStreamTrackProcessor,并且有些函数已经过时,已经变成全局函数,比如createImageBitmap,不再属于videoFrame的内部函数,取而代之请使用全局createImageBitmap。不过还是给出一段VideoTrackReader的代码

// VideoTrackReader is deprecated; use MediaStreamTrackProcessor instead.

 function startReader(stream) 
   if (videoTrackReader) 
     console.warn('VideoTrackReader ALREADY exist');
     return;
   

   const track = stream.getVideoTracks()[0];
   videoTrackReader = new VideoTrackReader(track);
   videoTrackReader.start(async (videoFrame) => 
     if (keepAnimation) 
     // 注意videoFrame的createImageBitmap也已经过时
       const imageBitmap = await videoFrame.createImageBitmap();
       drawCanvasBitmap(imageBitmap);
       imageBitmap.close();
     
     videoFrame.destroy();
   );
 

使用

function startProcessor(stream) 
    if (processor) 
      console.warn('MediaStreamTrackProcessor ALREADY exist');
      return;
    

    const track = stream.getVideoTracks()[0];
    processor = new MediaStreamTrackProcessor(track);
    writable = new WritableStream(
      start() 
        console.log('Writable start');
      ,
      async write(videoFrame) 
        const imageBitmap =await createImageBitmap(videoFrame);
        drawCanvasBitmap(imageBitmap);
        imageBitmap.close();
        if (videoFrame.close) 
          videoFrame.close();
        
        else 
          videoFrame.destroy();
        
      ,
      // stop() 
      //   console.log('Writable stop');
      // ,
      close() 
        console.log('Writable close');
      ,
      abort(reason) 
        console.log('Writable abort:', reason);
      ,
    )

    processor.readable
      .pipeTo(writable);
  

测试

可以使用getUserMedia 来做测试,假定视频已经在网页上播放,制作一个界面

  async function startVideo() 
    const constraints =  video: true, audio: false ;
    const stream = await navigator.mediaDevices.getUserMedia(constraints)
      .catch(err => 
        console.error('Media ERROR:', err);
        return;
      );

    video.srcObject = stream;
    await video.play().catch(err => console.error('media ERROR:', err));
  

  async function stopVideo() 
    if (video.srcObject) 
      video.pause();
      stopMediaStream(video.srcObject);
      video.srcObject = null;
    
  

点击开始录像以后,允许摄像头进行采集,如果没有摄像头,可以使用canvas,随手画上一段动画就行,下面给出一个示例

async function startDrawing() 
  const cnv = document.getElementById("src");
  const ctx = cnv.getContext("2d",  alpha: false );

  ctx.fillStyle = "white";
  const  width  = cnv;
  const  height  = cnv;
  const cx = width / 2;
  const cy = height / 2;
  const r = Math.min(width, height) / 5;
  var drawtime = 0;
  const drawOneFrame = function drawOneFrame(time) 
    //const angle = Math.PI * 2 * (time / 5000);
    //const scale = 1 + 0.3 * Math.sin(Math.PI * 2 * (time / 7000));
    ctx.save();
    ctx.fillRect(0, 0, width, height);

    ctx.translate(cx, cy);
    //ctx.rotate(angle);
    //ctx.scale(scale, scale);

    ctx.font = "30px Verdana";
    ctx.fillStyle = "black";
    const text = "this is " +drawtime++;
    const size = ctx.measureText(text).width;
    ctx.fillText(text, -size / 2, 0);
    ctx.restore();
    window.requestAnimationFrame(drawOneFrame);
  ;

以上使用不断变化的数字来代替gb28181 的播放,如上图所示。下面为播放中的界面。

录像呈现,默认为h264

方式2

使用接收的videoFrame去存储,比如我们是flv方式,那就是demux flv以后,装载成videoFrame,然后解码展现,可以将数据直接存储,这样可以省却编码,那么方式1的优势是什么呢?在里面可以直接叠加数据,比如AI 目标框和文字。原理和方式1 无大的差别,读者自己可以实践。demax后,可以使用EncodedVideoChunk来包装接收到的flv数据,变成了videoFrame, 然后进行pipe,如下面代码所示:

function inputChunk(data, pts, iskey) 
  console.log(data, pts, iskey)
  const chunk = new EncodedVideoChunk(
    timestamp: pts,
    type: iskey ? 'key' : 'delta',
    data: data
  );
  decoder.decode(chunk);

以上是关于网页录制gb28181录像的主要内容,如果未能解决你的问题,请参考以下文章

数字硬盘录像机接入GB28181流媒体服务(LiveGBS)设备录像实时查询

GB28181实现摄像头网页无插件直播回放过程中设备状态分析

LiveGBS通过GB28181协议接入海康大华华为等各厂家硬盘录像机NVR 或者带存储的摄像头实现WEB直播及录像查询回放

GB28181录像回放

GB28181协议的用途是啥

用EasyGBD做国标GB28181协议级联