I am using Vue.js to make a web application that records users web-cam footage. I want to send this footage to a backend server with which I am connected to via web socket.
The issue is that I want to extract and send the live-stream frame-by-frame from the frontend and send the frames individually, regardless of the FPS on the frontend.
I was previously doing this on HTML by extracting the frame at any instance using video_element = document.getElementById("videoElement")
and then using the process described here.
How can I achieve the same thing while using the VUE js framework. Below is my VUE file for referrence.
<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>