vue 비디오 녹화 및 비디오 파일 압축 방법

파일 업로드 상자gif.jsGIF 그림 을 생 성하 여 전단 의 영상 압축 을 완성 합 니 다.
제 가 여기 서 사용 하 는 것 은 Vue 가 쓴 것 입 니 다.다음은 제 절차 와 코드 입 니 다.
1.gif.js 관련 파일 을 다운로드 한 다음 에 이 몇 개의 파일 을 루트 디 렉 터 리 의 static/js 에 넣 습 니 다.

gif.js 관련 파일 및 저장 경로
2.다운로드 의존 패키지:

npm i timers
3.페이지 에서 설명:

import { setInterval, clearInterval } from "timers";
import GIF from "../../static/js/gif.js"
4.html 코드 블록:

<template>
 <div>
   <input ref="changeInput" type="file" accept="video/*" capture="user" @change="changeVideo" />
   <div>
    <div>    :{{videoSize}}</div>
    <div>    :{{videoLength}}</div>
    <div>
     <video id="myvideo" :src="videoSrc" :width="winWidth" :height="winHeight" ref="videoId" autoplay="true" controls muted></video>
     <canvas id="canvas" :width="winWidth" :height="winHeight"></canvas>
    </div>
   </div>
 </div>
</template>
5.페이지 로 딩 완료 시 GIF 초기 화:

mounted(){
  //  gif
  this.gif = new GIF({
   workers: 1,
   quality: 1000,
   width: window.innerWidth,
   height: window.innerHeight,
   workerScript: '../../static/js/gif.worker.js',
  });
 },
6.input 이 동 영상 을 녹화 하고 페이지 로 돌아 가면 이 동 영상 파일 을 얻 을 수 있 습 니 다.동 영상 파일 을 받 을 때마다 이전의 감청 을 제거 해 야 합 니 다.

//input    
  changeVideo(e){
   var file = e.target.files[0];
   const video = document.getElementById('myvideo');
   //      
   video.removeEventListener('play', this.videoPlay, false);
   //     
   video.removeEventListener('ended', this.videoEnded, false); 
   this.androidFile(file);
  },
7.앞에서 언급 한 this.android File 방법 은 이 영상 파일 을 통 해 페이지 에서 한 번 재생 하고 이 재생 과정 에서 영상 을 처리 하 며 전체 변환 과정 을 완성 하여 최종 파일 을 얻 는 것 입 니 다.

//      
  androidFile(file){
   //      
   this.videoSize = file.size;

   const that = this;
   const video = document.getElementById('myvideo');
   const canvas = document.getElementById('canvas');
   var context = canvas.getContext('2d');

   this.gifSetTime = true;
   this.gif.abort()
   this.gif.frames = [];

   //file base64
   var reader = new FileReader();
   reader.readAsDataURL(file);
   reader.onload = function () {
    that.videoSrc = this.result;
    video.play();
   }
   //      
   video.addEventListener('play', this.videoPlay, false);
   //     
   video.addEventListener('ended', this.videoEnded, false); 
   //               
   this.gif.on('finished', function(blob) {
    if(that.fileAndroid.size == blob.size) return;
    console.log("gif blob  ",blob);
    //file
    that.fileAndroid = that.convertBase64UrlToFile(blob);
    //      
    that.uploadVideo(that.fileAndroid);
   });
  },

8.7 단계 에서 말 한 this.videoPlay 방법.동 영상 은 페이지 재생 과정 에서 200 밀리초 마다 canvas 를 통 해 그림 한 장 을 캡 처 하고 이 그림 들 을 gif.js 에 한 장 씩 쌓 아 줍 니 다.

//      
  videoPlay(){
   const that = this;
   const video = document.getElementById('myvideo');
   const canvas = document.getElementById('canvas');
   var context = canvas.getContext('2d');
   console.log("    ",video.duration);
   this.videoLength = video.duration;
    //      ,        ,        
    var times = setInterval(function(){
      context.drawImage(video, 0, 0, that.winWidth, that.winHeight);
      that.gif.addFrame(context, {
       copy: true
      });
      if(that.gifSetTime == false){
       clearInterval(times);
      }
    }, 200);
  },
9.7 단계 에서 말 한 this.videoEnded 방법.동 영상 재생 이 끝나 면 gif.js 를 통 해 그림 이 쌓 인 동적 그림 을 렌 더 링 합 니 다.

//     
  videoEnded(){
   this.gifSetTime = false;
   console.log("      !")
   this.gif.render();
  },
10.7 단계 에서 말 한 that.convertBase64UrlToFile 방법.gif.js 에서 생 성 된 Blob 파일 을 File 형식 으로 변환 합 니 다.

//blob to file
  convertBase64UrlToFile(blob) {
   var d = new Date().getTime();
   var type = 'image/gif'
   return new File([blob],"fileGif-" + d + '.gif', {type:type});
  },
마지막 으로 7 단계 에서 말 한 that.uploadVideo 방법 을 통 해 서버 에 사진 을 업로드 합 니 다.

//    
  uploadVideo(file){
   console.log("       ", file)
  },
여기 서 제 모든 코드 를 제공 합 니 다.Android 의 동 영상 파일 이 커서 압축 을 했 고 IOS 자체 에 동 영상 압축 이 존재 하기 때문에 저 는 구분 을 했 습 니 다.

<template>
 <div>
   <input ref="changeInput" type="file" accept="video/*" capture="user" @change="changeVideo" />
   <div>
    <div>    :{{videoSize}}</div>
    <div>    :{{videoLength}}</div>
    <div>
     <video id="myvideo" :src="videoSrc" :width="winWidth" :height="winHeight" ref="videoId" autoplay="true" controls muted></video>
     <canvas id="canvas" :width="winWidth" :height="winHeight"></canvas>
    </div>
   </div>
 </div>
</template>

<script>
import { setInterval, clearInterval } from "timers";
import GIF from "../../static/js/gif.js"
export default {
 data(){
  return {
   videoSize: '',
   videoSrc: '',
   videoLength: '',
   isAndroid: false,
   fileAndroid: {},
   winWidth: window.innerWidth,
   winHeight: window.innerHeight,
   gifSetTime: false,
   gif: '',
  }
 },
 created() {
  //    
  var u = navigator.userAgent;
  var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android  
  var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios  
  if(isAndroid){
   console.log('isAndroid')
   this.isAndroid = true;
  }else if(isiOS){
   console.log('isiOS')
   this.isAndroid = false;
  }
 },
 mounted(){
  //  gif
  this.gif = new GIF({
   workers: 1,
   quality: 1000,
   width: this.winWidth,
   height:this.winHeight,
   workerScript: '../../static/js/gif.worker.js',
  });
 },
 methods:{
  //input    
  changeVideo(e){
   var file = e.target.files[0];
   const video = document.getElementById('myvideo');
   
   if(file !== undefined){
    //    
    if(this.isAndroid){
     //      
     video.removeEventListener('play', this.videoPlay, false);
     //     
     video.removeEventListener('ended', this.videoEnded, false); 
     this.androidFile(file);
    }else{
     this.iphoneFile(file);
    }
   }
  },
  //IOS    
  iphoneFile(file){
   const that = this;
   //      
   this.videoSize = file.size;
   
   var url = null ; 
   //file   blob
   if (window.createObjectURL!=undefined) { // basic
    url = window.createObjectURL(file) ;
   } else if (window.URL!=undefined) { // mozilla(firefox)
    url = window.URL.createObjectURL(file) ;
   } else if (window.webkitURL!=undefined) { // webkit or chrome
    url = window.webkitURL.createObjectURL(file) ;
   }
   this.videoSrc = url;
   if(file.size < 2100000 && file.size > 500000){
    this.uploadVideo(file);
   }else if(file.size >= 2100000){
    this.$vux.toast.text('    ,    10  ');
   }else{
    this.$vux.toast.text('        5 ');
   }
  },
  //      
  androidFile(file){
   //      
   this.videoSize = file.size;

   const that = this;
   const video = document.getElementById('myvideo');
   const canvas = document.getElementById('canvas');
   var context = canvas.getContext('2d');

   this.gifSetTime = true;
   this.gif.abort()
   this.gif.frames = [];

   //file base64
   var reader = new FileReader();
   reader.readAsDataURL(file);
   reader.onload = function () {
    that.videoSrc = this.result;
    video.play();
   }
   //      
   video.addEventListener('play', this.videoPlay, false);
   //     
   video.addEventListener('ended', this.videoEnded, false); 
   
   this.gif.on('finished', function(blob) {
    if(that.fileAndroid.size == blob.size) return;
    console.log("gif blob  ",blob);
    that.fileAndroid = that.convertBase64UrlToFile(blob);
    that.uploadVideo(that.fileAndroid);
   });
  },
  //      
  videoPlay(){
   const that = this;
   const video = document.getElementById('myvideo');
   const canvas = document.getElementById('canvas');
   var context = canvas.getContext('2d');
   console.log("    ",video.duration);
   this.videoLength = video.duration;
    //      ,        ,        
    var times = setInterval(function(){
      context.drawImage(video, 0, 0, that.winWidth, that.winHeight);
      that.gif.addFrame(context, {
       copy: true
      });
      if(that.gifSetTime == false){
       clearInterval(times);
      }
    }, 200);
  },
  //     
  videoEnded(){
   this.gifSetTime = false;
   console.log("      !")
   this.gif.render();
  },
  //blob to file
  convertBase64UrlToFile(blob) {
   var d = new Date().getTime();
   var type = 'image/gif'
   return new File([blob],"fileGif-" + d + '.gif', {type:type});
  },
  //    
  uploadVideo(file){
   console.log("       ", file)
  },
 }
};
</script>
<style scoped>

</style>
모 바 일 브 라 우 저(특히 위 챗 브 라 우 저!)호환성 이 가장 좋다.그러나 이 생 성 된 비디오 파일 은 오디 오 를 잃 게 될 것 입 니 다.오디 오 가 필요 하 다 면 다른 약 서 를 볼 수 있 습 니 다.몇 가지 방법 이 있 습 니 다.더 좋 은 방법 이 있 습 니 다.여러분 의 댓 글 을 환영 합 니 다.서로 공부 합 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기