vue 录制视频并压缩视频文件的方法

文件上传框<input type="file">,除了可以选择文件上传之外,还可以调用摄像头来拍摄照片或者视频并上传。capture属性可以判断前置or后置摄像头。在视频播放的过程中,用canvas定时截取一张图片,然后用gif.js生成一张GIF图,从而完成前端的视频压缩。

我这里使用的是Vue写的,以下是我的流程及代码:

一、下载gif.js相关文件,可以到这里下载,然后将这几个文件放在根目录的static/js里面。

gif.js相关文件及存放路径

二、下载依赖包:

npm i timers

三、在页面中声明:

import { setInterval, clearInterval } from "timers";
import GIF from "../../static/js/gif.js"

四、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>

五、在页面加载完成时初始化GIF:

mounted(){
  //初始gif
  this.gif = new GIF({
   workers: 1,
   quality: 1000,
   width: window.innerWidth,
   height: window.innerHeight,
   workerScript: '../../static/js/gif.worker.js',
  });
 },

六、当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);
  },

七、上一步提到的this.androidFile方法,是通过这个视频文件,在页面播放一遍,在这个播放过程处理视频,完成整个转换过程,获取到最终的文件:

//安卓拍摄视频
  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);
   });
  },

八、步骤七所说的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);
  },

九、步骤七所说的this.videoEnded方法。视频播放完,通过gif.js将图片堆叠的动态图渲染出来:

//视频播放完
  videoEnded(){
   this.gifSetTime = false;
   console.log("视频播放完毕!")
   this.gif.render();
  },

十、步骤七所说的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});
  },

最后通过步骤七所说的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>

试过很多种方法,而这种在移动端浏览器(特别是微信浏览器!)的兼容性是最好的。但是这个生成的视频文件将会失去音频,如果需要音频的可以看我另一篇简书有说明几种方法。有更好的方法欢迎大家留言,互相学习~

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Vue结合Video.js播放m3u8视频流的方法示例

    首先,我们需要在vue工程中安装video.js相关依赖. npm install --save video.js npm install --save videojs-contrib-hls 然后,我们需要引入videojs的css文件,例如在main.js中引入 import 'video.js/dist/video-js.css' 接着,我们在需要播放视频的页面引入js对象 import videojs from 'video.js' import 'videojs-contrib-hls

  • vue做网页开场视频的实例代码

    本demo背景是一个视频,文字是打印机效果,按钮在文字打完才会显示,点击按钮背景向上收起,同时显示默认首页组件(如是初建vue项目列表,则为helloWorld.vue的组件内容) 公司电脑没有gif动图尽情谅解 文末会附上demo地址,如需看效果,可前往下载 本人一直很喜欢网页开场有一段视频或动画,个人认为网页的开场动画起到引导浏览作用,相当于网页的一个开始,一个好的开始往往就成功了一半,对于浏览网站的用户来说,也就吸引了极大地注意力. 以上都是废话,网页开场动画在移动端的应用十分广泛,具体操

  • mpvue 如何使用腾讯视频插件的方法

    1.在小程序微信开放平台:设置 --- 第三方服务里,申请腾讯视频插件 2.申请成功后就可以在项目中使用了 具体使用步骤如下: 1.在项目目录src下的main.js中加入下面代码,这里代码会被编译到app.json中 config: { // 页面前带有 ^ 符号的,会被编译成首页,其他页面可以选填,我们会自动把 webpack entry 里面的入口页面加进去 pages: ['^pages/index/main'], window: { backgroundTextStyle: 'ligh

  • 基于 Vue.js 2.0 酷炫自适应背景视频登录页面实现方式

    本文讲述如何实现拥有酷炫背景视频的登录页面,浏览器窗口随意拉伸,背景视频及前景登录组件均能完美适配,背景视频可始终铺满窗口,前景组件始终居中,视频的内容始终得到最大限度的保留,可以得到最好的视觉效果.并且基于 Vue.js 2.0 全家桶.具体效果如下图所示: 最终效果可以翻到文章最后观看. 1. 背景视频 Web 页面的既有实现方式 国外有一个很好的网站 「Coverr」 ,提供了完善的教程和视频资源,帮助前端开发者构建酷炫的背景视频主页,网站效果示例如下图所示: 教程如下所示: 从图中以及我

  • vue2.0实现音乐/视频播放进度条组件

    基于vue2.0实现音乐/视频播放进度条组件的方法及代码解释,具体内容如下 需求分析: ①:进度条随着歌曲的播放延长,歌曲播放完时长度等于黑色总进度条长度:时间实时更新. ②:当滑动按钮时,实时更新播放时间,橙色进度条长度也会随着按钮的滑动而改变,当滑动结束时,橙色区域停留在滑动结束的位置,歌曲从当前进度开始播放. ③:点击进度条,橙色进度条长度变为点击处至起点的长度,并从当前点开始播放歌曲. 大概思路: ①:左边的时间可以通过audio播放时派发的timeupdate事件获取,右边的时间为接口

  • vue中实现图片压缩 file文件的方法

    项目中遇到上传图片需要在前端进行图片压缩,将我的实现思路记录一下.(我已经拿到上传的file文件的前提下) 先创建一个公用的js,这里我的是api.js,里面封装一些常用的方法 将图片压缩的方法写到这个公用的js(api.js)中 //base64转码(压缩完成后的图片为base64编码,这个方法可以将base64编码转回file文件) function dataURLtoFile(dataurl) { var arr = dataurl.split(','), mime = arr[0].ma

  • Python实现压缩和解压缩ZIP文件的方法分析

    本文实例讲述了Python实现压缩和解压缩ZIP文件的方法.分享给大家供大家参考,具体如下: 有时我们需要在 Python 中使用 zip 文件,而在1.6版中,Python 就已经提供了 zipfile 模块可以进行这样的操作.不过 Python 中的 zipfile 模块不能处理多卷的情况,不过这种情况并不多见,因此在通常情况下已经足够使用了.下面我只是对一些基本的 zipfile 操作进行了记录,足以应付大部分的情况了. zipfile 模块可以让你打开或写入一个 zip 文件.比如: i

  • C语言使用libZPlay录制声音并写到文件的方法

    本文实例讲述了C语言使用libZPlay录制声音并写到文件的方法.分享给大家供大家参考.具体实现方法如下: /** * Record samples from line-in and save to out.mp3 * */ #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <olectl.h> #include <ole2.h> #include <stdio.h> #include <

  • vue编译打包本地查看index文件的方法

    /build/config/index.js assetsPublicPath: './'(编译出来可以本地查看,'/'没有点的就直接发布到线上) 以上这篇vue编译打包本地查看index文件的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • ASP.NET Core中预压缩静态文件的方法步骤

    前言 Web应用程序的优化是非常重要,因为使用更少的CPU,占用更少的带宽可以减少项目的费用. 在ASP.NET Core中我们可以很容易的启用响应压缩,但是针对预压缩文件,就需要做一些额外的功能了. 这篇博客文章展示了如何在ASP.NET Core中预压缩静态文件. 下面话不多说了,来一起看看详细的介绍吧 为什么需要预压缩文件? 虽然在从服务器请求文件时, 我们可以动态压缩文件,但这意味这Web服务器需要做更多的额外工作. 其实只有在新的应用程序部署时才会更改要压缩的文件. 越好的压缩效果需要

  • vue 录制视频并压缩视频文件的方法

    文件上传框<input type="file">,除了可以选择文件上传之外,还可以调用摄像头来拍摄照片或者视频并上传.capture属性可以判断前置or后置摄像头.在视频播放的过程中,用canvas定时截取一张图片,然后用gif.js生成一张GIF图,从而完成前端的视频压缩. 我这里使用的是Vue写的,以下是我的流程及代码: 一.下载gif.js相关文件,可以到这里下载,然后将这几个文件放在根目录的static/js里面. gif.js相关文件及存放路径 二.下载依赖包:

  • 实例展示使用Java压缩和解压缩7z文件的方法

    压缩为7z文件 首先网络上对7z的压缩内容很少. 尤其是java调用进行压缩的是更少了. 一下是自己完成的一个压缩. 本人进行了测试是成功的. 将压缩的流写如磁盘一个压缩文件中. 然后使用7z的压缩软件进行打开解压. 7-zip的开源项目7-zip-JBinding项目地址(sourceforge) 不多说,调用7z源码进行压缩的方法如下. public byte[] lzmaZip(String xml) throws IOException{ BufferedInputStream inSt

  • vue组件内部引入外部js文件的方法

    之所以要做这个是因为,在一个组件内部需要引入一个js文件来定位.如果放在index.html,这样每个组件都会有这个js.所以需要在组件内单独引入. 第一种操作 Dom引入js: export default { mounted() { const s = document.createElement('script'); s.type = 'text/javascript'; s.src = '你的需要的js文件地址'; document.body.appendChild(s); }, } 第

  • python如何压缩新文件到已有ZIP文件

    本文为大家分享了python压缩新文件到已有ZIP文件的具体代码,供大家参考,具体内容如下 要点在于使用Python标准库zipfile创建压缩文件时,如果使用'a'模式时,可以追加新内容. from zipfile import ZipFile from os import listdir from os.path import isfile, isdir, join def addFileIntoZipfile(srcDir, fp): #遍历该文件夹中所有文件 for subpath in

  • python下解压缩zip文件并删除文件的实例

    利用python下载数据,下载下来的数据为zip格式,因为有上千个这样的文件,因此便直接在爬虫程序里加入了解压缩zip文件的内容,并且因为数据量较大,为了节省空间,便在解压缩后立即删除该zip文件. 先来介绍解压缩的方法: import zipfile filename = '/home/username/work/1.zip' fz = zipfile.ZipFile(filename, 'r') for file in fz.namelist(): fz.extract(file, path

随机推荐