在 Vue js 中从网络摄像头流中提取图像帧

问题描述 投票:0回答:1

我正在使用 Vue.js 制作一个记录用户网络摄像头镜头的 Web 应用程序。我想将这段视频发送到我通过网络套接字连接的后端服务器。

问题是我想从前端逐帧提取并发送直播流,并单独发送帧,无论前端的 FPS 如何。

我之前在 HTML 上执行此操作,方法是使用

video_element = document.getElementById("videoElement") 
在任何实例中提取框架,然后使用此处描述的过程。

如何在使用 VUE js 框架时实现同样的效果。以下是我的VUE文件供参考。

<template>
  <b-form class="step-form" @submit.stop.prevent="onSubmit">
    <div class="row">
      <div class="col-lg-12">
        <h3>Step 2: Record Video</h3>
        <p class="info">
          <i class="icon-error_outline"></i>Please point video camera
          on customer face and make sure their straight face is
          completely visible in the video. Click on Record button to
          record 10 seconds video.
        </p>
        <div
          class="video-record"
          :class="
                        showVideo == true
                            ? 'videoRecored'
                            : '' || timeShow == true
                            ? 'videoRecored'
                            : ''
                    "
        >
          <div class="show-record-video">
            <video-js-record
              @recordingStarted="onVideoRecording"
              @recordingEnded="onRecordingEnded"
            ></video-js-record>
          </div>
          <div
            :class="showVideo == true ? 'video-recorded' : ''"
            class="video-play"
          >
                        <span v-if="timeShow" class="timer-countdown">{{
                            countDown
                          }}</span>
            <i class="icon-record">
              <i class="path1"></i>
              <i class="path2"></i>
              <i class="path3"></i>
            </i>
            <p v-if="showVideo == false">Record</p>
            <p v-if="showVideo == true">Finish</p>
          </div>
        </div>
        <base-button
          v-if="showVideo"
          btn-type="submit"
          btn-variant="primary"
          btn-label="CONTINUE"
          :class="loading ? 'disabled' : ''"
          :disabled="loading"
        ></base-button>
      </div>
    </div>
    <!-- <b-modal
        :style="{'overflow': hidden}"
        class="modal-open"
        ref="modal" hide-footer centered title="Alert">
        <div class="text-center">
            <h5>Please remove glasses if you are wearing before capturing video for accurate results</h5>
        </div>
        <b-button class="mt-3" block @click="$bvModal.hide('bv-modal-example')">Ok</b-button>
    </b-modal> -->
  </b-form>
</template>
<script>
import {mapGetters } from 'vuex'
import request from '@/utils/request'
import videoJsRecord from '@/components/VideoJSRecord.vue'

export default {
    /*
    |--------------------------------------------------------------------------
    | Component > components
    |--------------------------------------------------------------------------
    */
    components: {
        videoJsRecord,

    }, // End of Component > components

    /*
    |--------------------------------------------------------------------------
    | Component > props
    |--------------------------------------------------------------------------
    */
    props: {}, // End of Component > props

    /*
    |--------------------------------------------------------------------------
    | Component > data
    |--------------------------------------------------------------------------
    */
    data() {
        return {
            countDown: 10,
            showVideo: false,
            timeShow: false,

        }
    }, // End of Component > data

    /*
    |--------------------------------------------------------------------------
    | Component > computed
    |--------------------------------------------------------------------------
    */
    computed: {
      ...mapGetters(['dataSegmentId', 'loading']),
    }, // End of Component > computed

    /*
    |--------------------------------------------------------------------------
    | Component > watch
    |--------------------------------------------------------------------------
    */

    watch: {
        /**
         * Handle when the file is uploaded successfully
         *
         * @return {void}
         */

        // End of user() method
    }, // End of Component > methods

    /*
    |--------------------------------------------------------------------------
    | Component > mounted
    |--------------------------------------------------------------------------
    */
    mounted() {
        this.$socket.emit('test', { hello: 'helloo' })
        this.sockets.subscribe('response_back', (data) => {
            // this.msg = data.message;
            console.log('SocketRecieve: ' + data)
        })

        this.getBrandingData()
        // this.$store.commit('initDefaultFields', 'form')
    }, // End of Component > watch

    /*
    |--------------------------------------------------------------------------
    | Component > methods
    |--------------------------------------------------------------------------
    */
  methods: {
    /**
     * Handle when the form has been submitted
     *
     * @return {void}
     */
    async onSubmit() {
      if (this.$route.meta.publicRegistration === true) {
        this.$router.push({
          name: 'public-registration-setup-profile',
          params: {
            dataSegmentId: this.dataSegmentId,
          },
        })
      } else {
        this.$router.push('/register-customer/setup-profile')
      }
    }, // End of onSubmit() method
    onVideoRecording() {
      this.timeShow = true
      this.showVideo = false
      this.countDownTimer()
    },
    async onRecordingEnded(player) {
      this.showVideo = true
      this.timeShow = false
      this.countDown = 10

      console.log(player)

      try {
        const formData = new FormData()
        formData.append('type', 'video')
        formData.append('file', player.recordedData, 'video.mp4')
        const headers = {
          'Content-Type': 'multipart/form-data',
        }
        const { data } = await request.post('files/', formData, {
          headers,
        })
        this.$store.commit('updateField', {
          key: 'documentInfo.video.fileName',
          value: data.data.fileName,
        })
      } catch (error) {
        console.log(error)
      }
    },
    countDownTimer() {
      if (this.countDown > 0) {
        setTimeout(() => {
          this.countDown -= 1
          this.countDownTimer()
        }, 1000)
      }
    },
    showMsgBoxTwo() {
      this.$bvModal
        .msgBoxOk(
          'Please remove glasses if wearing to get better results',
          {
            title: 'Alert',
            size: 'sm',
            buttonSize: 'sm',
            okVariant: 'success',
            headerClass: 'p-2 border-bottom-0',
            footerClass: 'p-2 border-top-0',
            centered: true,
          }
        )
        .then((value) => {
          // On Ok
          console.log('pop-up', value)
        })
        .catch((err) => {
          // An error occurred
          console.log('pop-up error', err)
        })
    },
  }, // End of Component > mounted
} // End of export default
</script>

node.js vue.js vue-component html5-video video.js
1个回答
0
投票

vue-capture-media 让您可以轻松地在 Vue.js 应用程序中捕获媒体(麦克风、相机、视频)。

npm install vue-capture-media
  1. 使用方法

将此代码写入您的 html 文件中

<template>
<div>
    <PhotoCapture v-model="imageBase64" />
    <VideoCapture uploadUrl="<example-server-address.com>" v-model="videoUrl" />
</div>

将这些组件导入到你的 vue 文件中

import {PhotoCapture, VideoCapture} from 'vue-capture-media'

JS代码

export default {
    data(){
        return {
            imageBase64: '',
            videoUrl: '',
        }
    },
    components:{
        PhotoCapture,
        VideoCapture
    }
}
  1. 参考链接

研究 vue-capture-media 了解更多详细信息。

  1. 捕获网络摄像头流的替代方法

访问此如何使用 VueJS 捕获自拍,了解捕获屏幕或网络摄像头流的基本知识。

© www.soinside.com 2019 - 2024. All rights reserved.