justadudewhohacks / face-api.js

JavaScript API for face detection and face recognition in the browser and nodejs with tensorflow.js
MIT License
16.38k stars 3.65k forks source link

Use flv.js to load the live stream. In the video, the live broadcast was delayed due to the loading time of 3 or 4 seconds, so I added a live broadcast catch-up mechanism, but the canvas did not load after catching up #796

Open lai53050960 opened 3 years ago

lai53050960 commented 3 years ago

Use flv.js to load the live stream. In the video, the live broadcast was delayed due to the loading time of 3 or 4 seconds, so I added a live broadcast catch-up mechanism, but the canvas did not load after catching up.

lai53050960 commented 3 years ago
 <script>
    let forwardTimes = []
    let withFaceLandmarks = false
    let withBoxes = true

    function onChangeWithFaceLandmarks(e) {
      withFaceLandmarks = $(e.target).prop('checked')
    }

    function onChangeHideBoundingBoxes(e) {
      withBoxes = !$(e.target).prop('checked')
    }

    function updateTimeStats(timeInMs) {
      forwardTimes = [timeInMs].concat(forwardTimes).slice(0, 30)
      const avgTimeInMs = forwardTimes.reduce((total, t) => total + t) / forwardTimes.length
      $('#time').val(`${Math.round(avgTimeInMs)} ms`)
      $('#fps').val(`${faceapi.utils.round(1000 / avgTimeInMs)}`)
    }

    async function onPlay(videoEl) {
      if(!videoEl.currentTime || videoEl.paused || videoEl.ended || !isFaceDetectionModelLoaded())
        return setTimeout(() => onPlay(videoEl))

      const options = getFaceDetectorOptions()

      const ts = Date.now()

      const drawBoxes = withBoxes
      const drawLandmarks = withFaceLandmarks

      let task = faceapi.detectAllFaces(videoEl, options)
      task = withFaceLandmarks ? task.withFaceLandmarks() : task
      const results = await task

      updateTimeStats(Date.now() - ts)

      const canvas = $('#overlay').get(0)
      const dims = faceapi.matchDimensions(canvas, videoEl, true)

      const resizedResults = faceapi.resizeResults(results, dims)

      if (drawBoxes) {
        faceapi.draw.drawDetections(canvas, resizedResults)
      }
      if (drawLandmarks) {
        faceapi.draw.drawFaceLandmarks(canvas, resizedResults)
      }

      setTimeout(() => onPlay(videoEl))
    }

    async function run() {
      // load face detection and face landmark models
      await changeFaceDetector(TINY_FACE_DETECTOR)
      await faceapi.loadFaceLandmarkModel('/')
      changeInputSize(416)

      // start processing frames
      onPlay($('#inputVideo').get(0))
    }

    function updateResults() {}

    $(document).ready(function() {
      startVideo()
      renderNavBar('#navbar', 'video_face_tracking')
      initFaceDetectionControls()
      run()
    })

    function startVideo() {
            var videoElement = document.getElementById('inputVideo');
            var flvPlayer = flvjs.createPlayer({
                type: 'flv',
                enableWorker: true,     //浏览器端开启flv.js的worker,多进程运行flv.js
                isLive: true,           //直播模式
                hasAudio: false,        //关闭音频             
                hasVideo: true,
                stashInitialSize: 128,
                enableStashBuffer: false, //播放flv时,设置是否启用播放缓存,只在直播起作用。
                url: 'xxx'
            });

            flvPlayer.attachMediaElement(videoElement);
            flvPlayer.load();
            flvPlayer.play();

            setInterval(function () {
                console.log("时延校正判断");
                if (!flvPlayer.buffered.length) {
                    return;
                }
                var end = flvPlayer.buffered.end(0);
                var diff = end - flvPlayer.currentTime;
                console.log(diff);
                if (diff >= 4) {
                    console.log("进行时延校正");
                    flvPlayer.currentTime = end - 0.1;
                    //alert("时延过长,请点击时延校准");
                }
            }, 3000)
        }

  </script>
lai53050960 commented 3 years ago

flv.js address https://github.com/Bilibili/flv.js/